当前位置: 首页 > 知识库问答 >
问题:

spring JpaRepository-分离和附加实体

姜楷
2023-03-14

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

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

我想实现以下目标

  1. 加载用户实体。
  2. 更改实体对象的状态,例如user.setname(“foo”)
  3. 执行外部系统webservice调用。将调用结果保存在DB中
  4. 仅当成功响应此webservice调用时,才将用户的新状态保存在存储库中。

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

当我通过数据库将webservice结果保存在数据库中时,我在用户实体中的更改也会被保存。根据我的理解,这是由于在步骤#3中对底层持久性上下文进行了冲洗。经过一些谷歌,我认为我可以达到我的目的,如果我可以分离我的用户实体在第一步,并重新连接它在第4步。请确认我的理解是否正确,我如何做到这一点?JPararePository接口中没有分离实体的方法。

下面是要说明的代码

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
}

谢谢

共有2个答案

饶骁
2023-03-14

EntityManager.clear()将断开所有JPA对象的连接,因此,如果您计划保持其他对象的连接,那么在所有情况下,这可能不是一个合适的解决方案。

清扬

/**
 * Clear the persistence context, causing all managed
 * entities to become detached. Changes made to entities that
 * have not been flushed to the database will not be
 * persisted.
 */
public void clear();

EntityManager.Detach(entity);从持久性上下文中删除给定的实体

分离

/**
 * Remove the given entity from the persistence context, causing
 * a managed entity to become detached.  Unflushed changes made
 * to the entity if any (including removal of the entity),
 * will not be synchronized to the database.  Entities which
 * previously referenced the detached entity will continue to
 * reference it.
 * @param entity  entity instance
 * @throws IllegalArgumentException if the instance is not an
 *         entity
 * @since Java Persistence 2.0
 */
public void detach(Object entity);
梁丘成和
2023-03-14

如果您使用的是JPA2.0,那么可以使用EntityManager#detach()从持久性上下文中分离单个实体。而且,Hibernate有一个会话#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);
    }
    ...
}

我没有尝试过这段代码,但您应该能够使它工作。您甚至可以尝试使用@PersistenceContext在服务类(updateUser()所在的类)中保留EntityManager,并避免将自定义实现添加到存储库中的麻烦。

 类似资料:
  • 问题内容: 我正在使用Spring Boot并通过jpahibernate。我正在使用JpaRepository接口来实现我的存储库。与以下UserRepository一样 我想实现以下目标 加载用户实体。 更改实体对象的状态,例如user.setName(“ foo”) 进行外部系统Web服务调用。将通话结果保存到数据库中 仅在成功响应此Web服务调用后,才将用户的新状态保存在存储库中。 以上所

  • 问题内容: “独立实体”是什么意思?在交易期间如何将托管实体转换为独立实体? 问题答案: 分离实体是状态不能由JPA提供程序反映的实体。 换句话说,如果您更改其状态(即通过setter方法),则这些更改将不会保存到基础数据库中,因为JPA提供程序不必“观察”此类实体。 如果实体E1是受管实体,则可以使其分离调用(非常合理的命名)方法。您还可以使用它将清除整个PersistenceContext并有

  • 安装它: sudo Mount-O discard/dev/xvdf/mnt/mydisk 我还将其添加到FSTAB中: 我认为当您创建一个EBS时,您可以在其他实例中重用它。但在我的情况下,这是不可能的,或者我做错了什么。此外,如果你有任何想法或选择将是惊人的。 我使用的是免费层T2。小。 操作系统是AWS Linux AMI。 EBS存储是通用的,1 GB,100/3000 I/O

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

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

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