Generating a sequence of jpa identifiers

There is tremendous value to be gained by assigning an ID to an object before it is stored in the database, but right away in the constructor: implementing equals / hashcode becomes trivial and saves a lot of headaches .

I've seen problems where entity equality is based on ==

: the proxy gets in the session and when it is unboxed as a real object, you get equals()

that which returns false

.

And when you override equals

and hashcode

to use the generated id, because it is only generated on persist()

, all non-resident objects have id null

and hence all are equal to each other.

From what I read, when you use traditional id generation technology (like autoincrement), the id is generated when the object manager is cleared. When you use a sequence based solution, it is generated persist-time.

For this article and my current understanding, the simplest solution is to assign an ID at creation time, not to save or clean up. And with sequences that appear to be available, but JPA has decided against it. With getting IDs being something cheap with sequences (how can you prefetch) why hasn't JPA provided at least the option to get ID based on sequence already at object creation? There is a risk of losing some ids if the entity is not actually saved at the end, but I think this is not a big problem.

Not to mention, the only "no compromise" solutions in terms of simplicity and clarity look like UUIDs, which have their own problems.

Am I missing something? Maybe there is some kind of JPA identity generator somewhere or some kind of library that will be sequence based and will allow an id to be given at build time?

+3


source to share


1 answer


Using the assigned ID is the best approach in terms of writing. It is also consistent across all object state transitions , and you can even batch insert multiple inserts at the JDBC level.

When it comes to reading and indexing, a numeric column works better, and the assigned ID is a unique logical key (social security number) or a unique identifier (like UUID). Using unique assigned application-level IDs is tricky because you might have multiple application nodes (in a cluster) or want to synchronize inserts from both the application and external sources (database client utility).

For the identifier assigned to the database, you need to consider how much of your choice depends on your choice. Hibernate tries to postpone the "persistence container" that goes to the last moment . This strategy is traditionally known as transactional writing.

The writer has more to do with the Hibernate flush rather than any logical or physical transaction. During a transaction, the flash may appear several times.



The flushed changes are visible only for the current database transaction. Until the current transaction is committed, no changes will be visible to other concurrent transactions.

IDENTITY requires a flush, while the sequence is not transactional, so it does not require a flush. IDENTITY disables batch JDBC insertion and does not support preallocation.

JPA cannot assign an ID during Entity construction because a new instance can only be persisted through a call to EntityManager.persist (). JPA requires explicit "object state transitions".

Dropping the sequence id is not a problem. The database works fine even with breaks in sequence values. Using a bigint column can ensure that you almost never run out of sequence ids. It is better to have a distribution of sequence IDs without transactions at random intervals than to have a distribution of transactions with a higher risk of deadlock conflict.

+2


source







All Articles