Spring Data实体同步

huangapple go评论59阅读模式
英文:

Spring Data entity synchronization

问题

我正在使用Spring Data访问关系数据库,以下是伪代码:

@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;
    // ...
}

现在我的问题是:
如果我多次调用UserRepository#findByName,每次都会得到一个不同的Java对象 - 当然,它们包含相同的数据。这是有意为之吗?如果我对一个这样的实例进行更改,另一个实例不会得到更新。
在理想情况下,我希望对于相同的实体要么有相同的对象,要么至少有对象同步。

英文:

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

@Repository
public interface UserRepository extends JpaRepository&lt;User, BigDecimal&gt; {
    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.

答案1

得分: 3

  • 在第一个方法中,事务开始时打开一个会话,事务完成时关闭该会话,因此Hibernate提供了“可重复读”。

  • 在第二个方法中,当您调用userRepository.findByName时会打开一个会话,并在返回时关闭它。当您第二次调用它时,会再次发生。由于上一个会话已关闭,Hibernate不会记住它,并返回新的对象。

英文:
  • 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

huangapple
  • 本文由 发表于 2020年7月29日 18:21:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/63151427.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定