1

I am using Spring Data to access a relational database, here pseudo code:

@Repository
public interface UserRepository extends JpaRepository<User, BigDecimal> {
    public User findByName(String name);
...
}

@Entity
@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class User {
    @Column(...)
    @EqualsAndHashCode.Include
    private String name;
...
}

Now my question is: If I call UserRepository#findByName several times, I get each time a different Java object - of course containing the same data. Is this intentional? And if I apply changes to one such instance the other one doesn't get the update. In an ideal scenario I wanted to either have the same object for the same entity or at least have the objects synchronized.

2
  • It is intentional yes in the sense that it's normal or default behaviour. I don't know if what you want is possible out-of-the-box. Is there a reason why you didn't remove the Lombok annotations before posting the question? (I'm just ruling out that you think they could help solving the question). Commented Jul 29, 2020 at 11:47
  • for one part I was ruling out myself that a missing equals and hashCode are a problem, the @Data is apart from getters and setters obsolete, true Commented Jul 29, 2020 at 11:51

1 Answer 1

4
  • Lets say you have a service like this
    @Service
    public class ServiceA {
       
       @Autowired
       private UserRepository userRepository
       
       @Transactional
       public User findByNameWithTransactionHereTimes(String name){
          User user1 = userRepository.findByName(name);
          User user2 = userRepository.findByName(name);
          // user1 == user2 will be true and I am comparing by reference
          
       }

       //
       public User findByNameWithNoTransactionHere(String name){
          User user1 = userRepository.findByName(name);
          User user2 = userRepository.findByName(name);
          // user1 != user2 will be true and I am comparing by reference
          
       }
    ...
    }
  • Hibernate guarantees Repeatable read within session and it can act as cache.

  • In the first method, a session opened when the transaction started and it is closed when the transaction completes so hibernate gives you Repeatable read

  • In the second method, a session opened when you called userRepository.findByName and closed when it returns. It happens again, when you call it second time. Since the previous session was closed, hibernate does not have any memory of it and returns the new object

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.