Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[eclipselink-users] Serious bug in EclipseLink sequence pre-allocation

Hello everyone,

there's a serious bug inside EclipseLink's sequence pre-allocation, assigning
the same id on more than one entity.

Imagine an entity TestEntity with allocationSize = 2 on its SequenceGenerator annotation.
Please have a look at following Test case snippet:


    //make sure that JPA entity has a allocationSize of 2
    TestEntity obj1 = new TestEntity();

    //em is our EclipseLink entity manager
    em.persist(obj1);

    TestEntity obj2 = new TestEntity();
    em.persist(obj2);

    TestEntity obj3 = new TestEntity();
    em.persist(obj3);

    assertFalse(obj1.getId().equals(obj2.getId()));

    //this one failes:
    assertFalse(obj2.getId().equals(obj3.getId()));


As you can see, the EntityManager assigns the same id twice:

register_new_for_persist, TestEntity[TEST_ENTITY_ID=null]
execute_query, ValueReadQuery(sql="SELECT TEST_ENTITY_ID.NEXTVAL FROM DUAL")
reconnecting_to_external_connection_pool
SELECT TEST_ENTITY_ID.NEXTVAL FROM DUAL
sequencing_preallocation, TEST_ENTITY_ID, 2, 5446377, 5446378
assign_sequence, 5446377, TestEntity[TEST_ENTITY_ID=null]
register_new_for_persist, TestEntity[TEST_ENTITY_ID=null]
assign_sequence, 5446378, TestEntity[TEST_ENTITY_ID=null]
register_new_for_persist, TestEntity[TEST_ENTITY_ID=null]
execute_query, ValueReadQuery(sql="SELECT TEST_ENTITY_ID.NEXTVAL FROM DUAL")
reconnecting_to_external_connection_pool
SELECT TEST_ENTITY_ID.NEXTVAL FROM DUAL
sequencing_preallocation, TEST_ENTITY_ID, 2, 5446378, 5446379
assign_sequence, 5446378, TestEntity[TEST_ENTITY_ID=null]

What makes this bug even more critical:
Someone may expect that the commit will fail on commit-time at the latest, throwing a unique contraint violation on the primary key. But this is not the case, interestingly.

In fact, this bug confuses the EclipseLink change tracking
mechanism in a way that it cannot determine the changes correctly.
Some changes, which are made to the entity after calling persist(), but before commit()/flush() may not been tracked correctly, hence not written.

This bug happens at least in EclipseLink 1.1.2.
The only workaround for this bug seems to be to set allocationSize=1 on all JPA entities,
which, of course, may affect performance.

Best regards,
Patric





Back to the top