On ensuring ID available after persist

#1

This reports on a possible solution to a common problem:

I was trialling ObjectDB on an existing, functioning, large JavaEE/JPA web application, which until now had used EclipseLink+MySQL and then Oracle+MySQL.

On trying it out on ObjectDB I hit a problem with my very extensive entity wiring code, which relies on an "external" entity object having a non-null id after it has been passed to EntityManager.persist, thus:

Element e  = new Element();
// .. configure element ..
em.persist(e);
// then do something that relies on Java variable e having e.getId() defined (like wiring up to another element)

I am using the following for the ID:

    @Id
    //@GeneratedValue(strategy = GenerationType.AUTO)// Explicit for EclipseLink + Oracle or MySQL
    @GeneratedValue//ObjectDB takes as AUTO
    public Long getId() {
        return id;
    }

The javadocs for EntityManager.persist() merely state that it should "Make an instance managed and persistent.", and unlike merge() there is no managed entity returned. My copious entity wiring code assumed that the Java variable passed to persist becomes endowed with an id (the same as the "internal" managed entity), which under EclipseLink it did.

Performing em.flush() immediately after em.persist(e) seems to work (although I'm not sure about the performance hit of flushing every time). This can be encapsulated as a wrapping persist(Object) method that also always flushes after persist(), to afford central experimentation.

I also found this in the documentation at https://www.objectdb.com/java/jpa/entity/generated:

    Unlike AUTO and IDENTITY, the SEQUENCE strategy generates an automatic value as soon as a new entity object is   persisted (i.e. before commit). This may be useful when the primary key value is needed earlier.

Hoping this is of help,

Webel

PS: The following external links discuss this common problem with JPA handlers other than ObjectDB:

forums.netbeans.org/topic13007.html

Spring forum: Get id of JPA persisted object
(forum.springsource.org/showthread.php?64943-Get-id-of-JPA-persisted-object)

#2

This is a good point.

Notice that the most portable generation strategy is TABLE, because:

  • AUTO - each JPA implementation uses its own default strategy.
  • IDENTITY - implementation depends on the database.
  • SEQUENCE - should work well except for DBMS that do not support sequences.

Regarding flush - I think it may be slower than just using SEQUENCE or TABLE.

ObjectDB Support
#3

The reason that ObjectDB doesn't assign ID during persist by default (when using the AUTO strategy or not specifying strategy) is performance considerations. Allocating IDs requires a round trip to the server. By postponing ID allocation to commit or flush - multiple IDs for multiple objects can be allocated together in one round trip.

In many cases the ID is not required immediately after persist. But if it is required - using the SEQUENCE or TABLE strategies, which support allocating a group of IDs in advance in one round trip (see the allocationSize attribute) is expected to be more efficient than a flush after every persist.

ObjectDB Support
#4

Just for the record, the reason I am using flush at the moment is that I don't want to fork (yet) my existing, previously EclipseLink-based web application, I am still evaluating ObjectDB, and as far as possible I want to preserve the state of the common code base; if I commit to ObjectDB I can then adopt performance tuning strategies that suit it better, such as TABLE.

Reply