当前位置: 首页 > 面试题库 >

Spring JpaRepository-分离并附加实体

龚永新
2023-03-14
问题内容

我正在使用Spring Boot并通过jpahibernate。我正在使用JpaRepository接口来实现我的存储库。与以下UserRepository一样

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

我想实现以下目标

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

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

当我通过Web服务的存储库将Webservice结果保存到DB中时,我对User实体的更改也将保存。根据我的理解,这是由于在步骤#3中清除了持久性上下文的原因。经过一番google之后,如果我可以在第一步中分离用户实体并在步骤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
}

谢谢


问题答案:

如果使用的是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,并避免将自定义实现添加到存储库的麻烦。



 类似资料:
  • 我正在JPA上使用spring boot和hibernate。我正在使用JpaRepository接口来实现我的存储库。与下面的UserRepository一样 我想实现以下目标 加载用户实体。 更改实体对象的状态,例如user.setname(“foo”) 执行外部系统webservice调用。将调用结果保存在DB中 仅当成功响应此webservice调用时,才将用户的新状态保存在存储库中。 以

  • 我正在尝试从Java分离并附加一个RServe会话。连接到RServe可以完美地工作,但连接会导致异常。 线程“main”org.rosuda.REngine.Rserve.Rserve异常:无法连接:连接被拒绝:连接到org.rosuda.REngine.Rserve.RConnection。(RConnection.java:90)org.rosuda.REngine.Rserve.RConn

  • null 我能找到的使用JPA/Hibernate的唯一有效解决方案是执行以下步骤。这是因为hibernate将实体保留在第一级缓存中,直到事务结束。 创建新实体 强制快速刷新() 分离实体 这样做的开销是 null 使用JDBC或JdbcTemplate,但您必须为实体编写自己的插入 所以问题是:是否存在同时坚持和分离的可能性,或者甚至更好地坚持而不成为被管理的?

  • 我使用的是Laravel 4,有两种型号: 上有标准的时间戳(处创建,处更新),我想在附加/分离

  • 问题内容: 我有以下代码: 这会在第四行引发IllegalArgumentException,提示“实体未管理”。如果我将第三行改为而不是,那么一切似乎都可以正常工作。 这里发生了什么?我可以防止这种情况发生吗? 更新: @DataNucleus将我引向PersistenceContext。如何在代码中更改持久性上下文? 问题答案: 根据Eval 2.0 Eval的JSR-000317持久性规范: