0

Below is my code snippet. @cacheput only inserts data onto redis on the first call. Does not update the value the second time save function is called. CacheManager in reference is a RedisCacheManager.

@CachePut(cacheNames = "User", key = "#user.Id")
@Override
public Optional<User> save(User user) {
    if(em.contains(user) || user.isPersisted()) { // merge if exists
        User retVal = em.merge(user);
        retVal.setPersisted(true);
        System.out.println("hashCode after merge-->"+retVal.hashCode());
        return Optional.ofNullable(retVal);
    } else {
        em.persist(user);
        user.setPersisted(true);
        return Optional.ofNullable(user);
    }
}

Dependency being used :

<dependency>
    <groupId>biz.paluch.redis</groupId>
    <artifactId>lettuce</artifactId>
    <version>4.3.2.Final</version>
</dependency>

I did verify the hashcodes for the object to be updated and the object inserted during first save, they are different.

rahul
  • 71
  • 1
  • 1
  • 7
  • So the `else` is running on the second call? So both `em.contains(user)` and `user.isPersisted()` are false on the second call? What does user.equals() look like? How is the method invoked on the second call? – Andrew S Feb 02 '18 at 18:34
  • if block is executed on the second call while else block is executed on the first call.Method is invoked the same way with a proxy even the second time. I can see the trace log of cache during second save similar to the first one. equals method compares each attribute of user against the object and returns false. I added a logger to verify that the object1.equals(object2) is false where object1 from first save and object2 from second save – rahul Feb 02 '18 at 19:24

1 Answers1

0

I found the issue. My save method is inside a DAO class annotated with

@Transactional

. Though DB commits were happening, Redis commit was not happening until the whole global transaction was successfully commit. So I added

@Transactional(propagation=Propagation.REQUIRES_NEW)

to my transactional annotation in all my Dao classes with @cacheput methods and that fixed my problem. I know its a bad idea to add this on a DAO method considering the problems we might face with two phase commits. But in my current usecase, it is not a problem.

rahul
  • 71
  • 1
  • 1
  • 7