Alex Barnes
Alex Barnes

Reputation: 7218

Transactional Second Level Cache and Generated Identifier

I have the following stack:

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 I see the results I expect when I assign the id and save the entity:

sessionFactory.getCache().containsEntity(MyEntity.class, myIdentifier)

However, if I repeat these tests using an @Entity which has a generated @Id (MySQL auto-incrementing long property) as shown:

@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:

      //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.

I have posted this question over on the Hibernate forums but haven't had much interest.

Upvotes: 1

Views: 230

Answers (1)

tscho
tscho

Reputation: 2054

I also think that this is quite a limitation for second-level cache usage so I created an issue (HHH-7964). I also added a comment with a workaround, but this is only a proof of concept and should not be used for production as far as I can tell.

Upvotes: 1

Related Questions