JpaRepository caches newly created object. How to refresh it?

If you are using Hibernate, this is the expected result. When you call translationRepository.saveAndFlush(translation) and translationRepository.findOne(t.getId()) one after the other, they hit the same Hibernate session which maintains a cache of all objects that it has worked on. Therefore, the second call simply returns the object passed to the first. There is nothing in those two lines that would have forced Hibernate to fire a SELECT query on the database for the Version entity.

Now, the JPA spec does have a refresh method on the EntityManager interface. Unfortunately, Spring Data JPA does not expose this method using its JpaRepository interface. If this method was available, you could have done t = translationRepository.saveAndFlush(translation) and then versionRepository.refresh(t.getVersion()) to force the JPA provider to synchronize the version entity with the database.

Implementing this method is not difficult. Just extend SimpleJpaRepository class from Spring Data JPA and implement the method yourself. For details see adding custom behaviour to all Spring Data JPA repositories.

An alternate would be to load the version entity as versionRepository.findOne(version.getId()) before setting it on the translation. Since you can hard-code version id in your code, your versions seem to be static. You can therefore mark your Version entity as @Immutable and @Cacheable (the former is a Hibernate-specific annotation). That way, versionRepository.findOne(version.getId()) should not hit the database every time it is called.

Leave a Comment