0

Hello my problem is that i can't avoid cache. I'm using Spring Data Jpa with Spring Boot 1.5.4

What am I doing: I have a case when some client request my REST endpoint with some data based on which I am creating an entity and I'm saveing it into database, next I request another REST endpoint which response me dirlectly OK, but request which I got isn't finished yet. Next I'm waiting for another service which has to request my another REST endpoint (First client is all the time on wire). This endpoint modifies entity which was created after first request I got and here I got problem.

So basicly, first request creates entity and saves it using "saveAndFlush" method. When first request is waiting another thread modifies this entity using spring data jpa:

@Modifying(clearAutomatically = true)
@Query("UPDATE QUERY ")
@Transactional
int updateMethod();

But after that (when first request is released from waiting) when I call findOne method in first thread I got old entity, I have tried also override method:

@Transactional
default MyEntity findOneWithoutCache(Long id) {
    return findOne(id);
}

But this not working too, I also added

@Cacheable(false)
public class MyEntity {

And this is not working too.

There is only one way which is working, when i select this entity using @Query this way:

@Query("SELECT STATEMENT "
        + "WHERE p.id = ?1")
MyEntity findEntityById(Long id);

Could you explain me how to solve this problem?

pustypawel
  • 331
  • 2
  • 17
  • Maybe easier: Thread#1: create Entity and saveAndFlush Thread#2: update entity using @Query Thread#1: findOne entity and gets old object – pustypawel Jun 20 '17 at 08:38
  • what if you use `@Transactional(propagation = Propagation.REQUIRES_NEW)` on your `findOneWithoutCache` method? – ledniov Jun 20 '17 at 09:55
  • The same effect – pustypawel Jun 20 '17 at 10:08
  • what about `@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)` ? – ledniov Jun 20 '17 at 10:15
  • The same, maybe the problem is somewhere else, when I'm doing saveAndFlush i have no transaction opened (what spring data jpa is doing in this situation)? – pustypawel Jun 20 '17 at 10:58
  • You should probably focus on your JPA provider. Does this help? [how to disable cache in eclipselink](https://stackoverflow.com/a/12927611) – Jarekczek Jun 21 '17 at 21:36
  • My JPA provider is Hibernate and you cannot disable first level cache – pustypawel Jun 22 '17 at 07:11

1 Answers1

1

The thing is what kind of Transaction Isolation do You have? What Database , settings, driver?

Theoretically in a perfect ACID transaction - after starting transaction you cannot see changes done in other transactions. (see Repeatable Read).

On the other hand typically you do not have I in ACID. And isolation is weaker. (like Read Commited).

If the query works it suggests you do not have Repeatable read - so maybe you should simply get EnityManager (via JpaContext) and try to clear() session (in the 1st thread)?

jarek000000
  • 96
  • 1
  • 3
  • It works! But tell me one more thing I came across your solution but i used refresh method (what was wrong - i got exception TransactionRequiredException). Thanks for response, now I see that detach method will be enouch. Can you tell me one more thing, is there difference when I inject entityManager using @PersistenceContext annotation instand of autowiring JpaContext and getting it using getEntityManagerByManagedType method? – pustypawel Jun 20 '17 at 23:23
  • And another thing - why EntityManager still keeps old object when transaction is commited (ended)? What I missed? – pustypawel Jun 20 '17 at 23:29