@GeneratedValue polymorphic abstract superclass over MySQL

What a mess… AUTO_INCREMENT is MySQL’s hidden sequence. The radical problem is that MySQL can not insert and return the PK at the same time, but Hibernate need this while INSERTing a new Entity.

The Problems you run into:

  1. If Hibernate save a new Entity, he try to immerdentelly set the id to the new EntityBean. Therefore hibernate must read what ID will the Database use before hibernate save the new Tuple to the Table.
  2. If you have multiple Servers who access the database, you shall let hibernate’s session-factory decide to use the built-in sequence(AUTO-INCREMENT) or let hibernate decide (GenerationType.AUTO/GenerationType.IDENTITY) how large the open range of reserved PK’s is (Job of a DB-Architect). (We have about 20 servers to one Database, so on a good-used table we use a PK-distance of +100). If only one server have access to the database GenerationType.TABLE shall be correct.

Hibernate must calculate the next id by yourself using max(*)+1 but:

  • What if two requests ask for max(*)+1 at the same time/with the same result? Right: The last try to insert will fail.

So you need to have a Table LAST_IDS in the database who stores the last Table-PK’s. If you like to add one, you must do this steps:

  1. Start read-optimistic transaction.
  2. SELECT MAX(address_id) FROM LAST_IDS
  3. store the maximum in a java-variable i.e.: $OldID.
  4. $NewID = $OldID + 1. (+100 in pessimistic-lock)
  5. UPDATE LAST_IDS SET address_id= $newID WHERE address_id= $oldID?
  6. commit the read-optimistic transaction.
  7. if commit was successfull, store $newID to setID() in the HibernateBean you like to save.
  8. Finally let Hibernate call the insert.

This is the only way i know.

BTW: Hibernate-Entitys shall only use inheritance if the Database support inheritance between tables like PostgreSQL or Oracle.

Leave a Comment