I have the following stack:
Hibernate 3.6.9.Final
Spring 3.1.1
Atomikos 3.7.1
Infinispan 4.2.1.FINAL
MySQL
I have been writing a few tests to ensure that when a RuntimeException is thrown the current transaction is rolled back on the database but also on the transactional 2LC.
I have found found some odd results which I was hoping someone could explain.
If I use an @Entity annotated with @Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL) with a String @Id which I assign in my test then I see everything I expect:
* When no exception is thrown the transaction is committed and the 2LC contains the entity, I confirmed this using:
Code:
sessionFactory.getCache().containsEntity(MyEntity.class, myIdentifier)
* If an exception is thrown neither the database or 2LC contain the entity.
However, if I repeat these tests using an @Entity which has a generated @Id (MySQL auto-incrementing long property) as shown:
Code:
@Id
@GeneratedValue
private long id;
I find that the entity is
never put in the 2LC, regardless of any exceptions thrown.
I have done some debugging and it seems to be down to the different code paths in AbstractSaveEventListener#performSaveOrReplicate. For an assigned @Id useIdentityColumn is false and so we instantiate and execute a EntityInsertAction which then puts the new entity in the 2LC.
Conversely, if the @Id is generated by MySQL we find that the useIdentityColumn is true and we instantiate and execute an EntityIdentityInsertAction. This contains commented out code regarding the 2LC as shown:
Code:
//TODO: this bit actually has to be called after all cascades!
// but since identity insert is called *synchronously*,
// instead of asynchronously as other actions, it isn't
/*if ( persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
cacheEntry = new CacheEntry(object, persister, session);
persister.getCache().insert(generatedId, cacheEntry);
}*/
Is there any reason for this? Should the cache insert be done elsewhere? Is this a bug?
If anyone can shed any light on this difference and how this should work I would be very grateful.