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

异常JPA/Hibernate:保存child@manytone关系时,分离的实体传递给persist

王磊
2023-03-14

无法保存子对象引用。

Employee parent对象包含子Employee\u详细信息,该详细信息还定义了一个@manytone来保存地址对象。

表结构

EMPLOYEE
ID   BIGINT(20) NOT NULL AUTO_INCREMENT
NAME VARCHAR(100) NOT NULL

EMPLOYEE_DETAIL
ID              BIGINT(20) NOT NULL AUTO_INCREMENT
EMPLOYEE_ID     BIGINT(20) NOT NULL
ADDRESS_ID      BIGINT(20) NOT NULL

实体

@Entity
@Table(name = "employee")
public class Employee {
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(name = "id")
 private Long id;

 @Column(name = "name")
 private String name;

 @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
 private List < EmployeeDetail > employeeDetails = new ArrayList < > ();

 public void addEmployeeDetail(EmployeeDetail ed) {
  employeeDetails.add(ed);
  ed.setEmployee(this);
 }

}

@Entity
@Table(name = "employee_detail")
public class EmployeeDetail {
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(name = "id")
 private Long id;

 @ManyToOne(optional = false, cascade = CascadeType.PERSIST)
 @JoinColumn(name = "employee_id")
 private Employee employee;

 @ManyToOne(optional = false, cascade = CascadeType.PERSIST)
 @JoinColumn(name = "address_id")
 private Address address;
}

在REST控制器方法中:

public void saveEmployee(@RequestBody Employee employee)
{
    EmployeeDetail employeeDetail = new EmployeeDetail();
    employeeDetail.setEmployee(employee);

    for(EmployeeDetail ed : employee.getEmployeeDetails())
    {
        Address address = addressService.findOne(ed.getAddress().getId());
        employeeDetail.setAddress(address);
    }

    employee.addEmployeeDetail(employeeDetail);

    //SAVE
    employeeService.create(employee);
}

例外情况:

nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.abc.Address

我无法用子表EmployeeDetail保存地址详细信息。这里怎么了?

共有1个答案

南宫建白
2023-03-14

应用级联类型。合并地址实体,如下所示

 @ManyToOne(optional = false, cascade = {CascadeType.PERSIST,CascadeType.MERGE})
 @JoinColumn(name = "address_id")
 private Address address;

并使用merge()而不是persist来保存更改

编辑

是的,您必须应用级联类型。也为EmployeeDetail合并。。否则,如果在从Employee开始的对象网络中有一个分离的EmployeeDetail实例,则会出现相同的异常。

您需要考虑几个场景。如下所述。

在根实体上调用persist()时,所有与CascadeType映射的实体关联。PERSIST也被传递给PERSIST()(可传递的peristence)。现在,如果对象图中的任何实体被分离,也将为该实体调用persist(),您将得到该实体的异常。

为了保存包含分离实例和瞬态实例的完整对象图,请使用CascadeType标记您的关联。在根实体上合并并调用MERGE()。。现在,merge()操作将级联到使用CascadeType映射的所有实体关联。合并。merge的行为是,它将传递给它的任何分离实体合并到持久性上下文中的现有实体,或者,如果实体是暂时的,它将使其持久化。

因此,在尝试保存实体图时,您需要根据要保存的实体图是否只有瞬态实例或同时具有瞬态实例和分离实例的信息来选择是使用持久()还是合并()。您还必须考虑每个关联上设置的级联类型。

对于您的代码...我看到您在员工详细信息实例上设置的地址实例已分离,因为您正在从另一个已获取的EmplyeeDetail实例中获取它。

你可以在下面的链接上获得更多详细信息

JPA EntityManager:为什么在merge()上使用persist()?

如果您不想使用分离的实例,还可以通过创建对话来扩展持久性上下文

http://www.thoughts-on-java.org/unsychronized-persistencecontext-implement-conversations-jpa/

 类似资料:
  • JPA和Hibernate的新手,所以请耐心等待,因为我试图绘制一整张图片。所以我有两个具有双向关系的Java对象。员工类是拥有类,部门类是关系的反面。一个部门可以有许多员工,一个员工只能有一个部门。我分配了employee_id作为员工实体的主键,department_id作为部门实体的主键。我还想在员工类中使用department_id作为外键。 员工类 部门类 我用来生成两个对象并将它们保存

  • 我正在使用springboot jpa存储库保存方法 这是完整的错误:2020-06-09 15:49:02.371[nio-8080-exec-4]。M.M.A.ExceptionHandlerExceptionResolver:由处理程序执行导致的解析异常:org.springframework.dao.invalidDataAccessapiusageException:传递给persist

  • 我是Hibernate的新手,我需要帮助。 我有一个名为Kasa的表,它有3个属性-id、address和account\u id。在我的表中有12行。我想使用Hibernate对此进行映射,并使用Java添加新的映射,所以我这样做了: 我也有能手和二传手,但不需要复制。 现在我想在我的数据库中添加新行,如下所示: 我得到这样的错误:javax.persistence.PeristenceExce

  • 问题内容: 我正在创建一个简单的应用程序,只需使用将一行插入到表中(如果表不存在,则创建它)。 我为它的一个可运行示例附加了一些代码。 这是我得到的异常和stacktrace: 这是我的代码: 主班: 和Person类: 这是我的persistence.xml文件 -----------------------编辑-------------------------- – 我只是将提供程序更改为Ec

  • 这个网站上没有一个类似的问题能够解决我的问题。 错误:org.hibernate.persistentobjectexception:传递给persist:healthcheckapi.model.checks的分离实体 示例JSON健康对象: 请注意,这两个对象的ID都是自动生成的,我认为这是问题的一部分。

  • 我使用的是Spring Boot 4、Hibernate和JPA注释。我遇到了这个错误 组织。冬眠PersistentObjectException:传递给persist的分离实体。 我试着在互联网上搜索,但没有找到正确的答案。我尝试使用而不是,但没有成功。此外,我认为在更新资源时使用。 这是我的代码: ` `积垢服务 ` ` 存储库 ` '抽象存储库 ` ` 工厂` '支持形式 ` ` 控制器