Spring JpaRepository - 分离和附加实体

新手上路,请多包涵

我在 jpa 上使用 spring boot 和 hibernate。我正在使用 JpaRepository 接口来实现我的存储库。与以下 UserRepository 一样

public interface UserRepository extends JpaRepository<User, Long> {
}

我想实现以下目标

  1. 加载用户实体。
  2. 更改实体对象的状态,例如 user.setName(“foo”)
  3. 进行外部系统网络服务调用。将调用结果保存到数据库中
  4. 只有在成功响应此 web 服务调用后,才会将用户的新状态保存在存储库中。

以上所有步骤都不会在一个事务中发生,即外部服务调用不在事务中。

当我通过其存储库将我的 web 服务结果保存在数据库中时,我在用户实体中的更改也被保存。根据我的理解,这是由于在第 3 步刷新了底层持久性上下文。经过一些谷歌搜索,我认为我可以实现我的目的,如果我可以在第一步分离我的用户实体并在第 4 步重新附加它。请确认如果我的理解是正确的,我该如何实现? JpaRepository 接口中没有分离实体的方法。

下面是代码来说明

public void updateUser(int id, String name, int changeReqId){
    User mUser = userRepository.findOne(id); //1
    mUser.setName(name); //2

    ChangeRequest cr = changeRequestRepository.findOne(changeReqId);
    ChangeResponse rs = userWebService.updateDetails(mUser); //3

    if(rs.isAccepted()){
        userRepository.saveAndFlush(mUser); //4
    }

    cr.setResponseCode(rs.getCode());
    changeRequestRepository.saveAndFlush(cr); //this call also saves the changes at step 2
}

谢谢

原文由 amique 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 864
2 个回答

如果您使用的是 JPA 2.0,则可以使用 EntityManager#detach() 从持久性上下文中分离单个实体。此外,Hibernate 有一个 Session#evict() 用于相同的目的。

由于 JpaRepository 本身不提供此功能,您可以 向其添加自定义实现,如下所示

public interface UserRepositoryCustom {
    ...
   void detachUser(User u);
    ...
}

public interface UserRepository extends JpaRepository<User, Long>, UserRepositoryCustom {
    ...
}

@Repository
public class UserRepositoryCustomImpl implements UserRepositoryCustom {
    ...
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void detachUser(User u) {
        entityManager.detach(u);
    }
    ...
}

我还没有尝试过这段代码,但你应该能够让它工作。您甚至可以尝试在您的服务类中保留 EntityManager (其中 updateUser() 是)和 @PersistenceContext ,并避免将自定义实现添加到存储库 - a1 .

原文由 Predrag Maric 发布,翻译遵循 CC BY-SA 3.0 许可协议

按照@Predrag Maric 的建议使用自定义实现显然是这个问题的正确答案。但是,我发现在服务层进行分离要好得多,因为它通常知道实体是否应该分离。

只需在服务中用 @PersistenceContext 它。

 @Service
class ConsumerServiceImpl {

    @PersistenceContext
    private EntityManager entityManager
...

    entityManager.detach(en)

原文由 Chayne P. S. 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题