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

传递给persist的JPA/Hibernate分离实体

郭元凯
2023-03-14

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

员工类

    @Entity
    @Table(name = "Employee")
    public class Employee
    implements java.io.Serializable
    {
       private static final long serialVersionUID = 1L;
       //primary key
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       @Column(name = "Employee_ID")
       private Integer       id;

       //foreign key 
       @ManyToOne(cascade=CascadeType.ALL)
       @JoinColumn(name = "Department_ID")
       private Department department;

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

       public Employee() { }

       public Employee(Integer id)
       {
          this.setId(id);
       }

       public void setDepartment(Department department){
           this.department = department;
       }
       public Department getDepartment(){
           return department;
       }
       public Integer getId() { return id; }
       public void setId(Integer id) { this.id = id; }
       public String getEmployeeName(){
            return name;
        }

        public void setEmployeeName(String name){
            this.name = name;
        }

部门类

@Entity
@Table(name = "Department")
public class Department
implements java.io.Serializable
{
   private static final long serialVersionUID = 1L;
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "Department_ID")
   private Integer       id;

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

   @OneToMany(mappedBy="department", cascade=CascadeType.ALL)
   private Collection<Employee> employees = new ArrayList<Employee>();

   public Collection<Employee> getEmployees() {return employees;}
   public void setEmployees(Collection<Employee> e){ employees = e;}

   public Department() { }

   public Department(Integer id)
   {
      this.setId(id);
   }

   public Integer getId() { return id; }
   public void setId(Integer id) { this.id = id; }
   public String getDepartmentName(){
        return name;
    }

    public void setDepartmentName(String name){
        this.name = name;
    }

我用来生成两个对象并将它们保存在数据库中的函数。我正在测试的数据库是H2,persistence.xml文件被配置为最初删除所有表,因此在调用以下函数之前,所有表都是空的。

public static void populateTable() {
        System.out.println("Populating tables");
        Department d1 = new Department();
        //d1.setId(1);
        d1.setDepartmentName("finance");
        //service.addDepartment(d1);

        Employee e1 = new Employee();
        e1.setEmployeeName("John");
        //e1.setId(1);
        //e1.setDepartment(d1);
        //d1.getEmployees().add(e1);
        service.addDepartment(d1);
        service.addEmployee(e1);
}

起初,我试图自己设置创建对象的主要id,但我遇到了“分离实体传递给持久化”错误。在阅读了一个类似的问题后,我明白如果我尝试在持久化对象之前设置唯一标识符,JPA会认为该实体已经存在于数据库中,它会抛出一个“分离实体传递给持久化错误”。所以我注释了setter函数的调用者,上面的代码运行良好。但是,如果我尝试将员工链接到部门,就像我对e1.set部门(d1)所做的那样;我会得到这个错误分离实体传递给持久化:com.javatunes.jpa.catalog.部门。我读了很多博客,比如这个和这个帖子,但是我仍然找不到这个问题的解决方案。还有一件事,两个持久化函数被定义为

public void addEmployee(Employee employee) {
          em.persist(employee);
          em.flush();
          }

public void addDepartment(Department department){
          em.persist(department);
          em.flush();
          }

错误在em.persistent(雇员)引发。

共有3个答案

董鸣
2023-03-14

我认为问题出在你的服务类上。因为你的服务类是@Transactive,当你保存d1service.add部门(d1);然后当函数返回时,然后d1被分离,它不再处于持久状态,然后在下一行,当你尝试保存e1service.add员工(e1);包括d1.get员工(). add(e1),那么你显然会得到分离的实体传递给持久:这个错误。因为您的d1对象已经处于分离状态,并且您正在尝试将其保存在另一个@Transactionic方法中。我认为要么您可以将两个服务方法合并为一个以保存部门和员工,并且可以简单地忽略此错误,要么您可以在下一个服务方法中使用合并操作,如下所示:

public void addDepartment(Department department) {
    em.merge(department);
    em.flush();
}
万涵亮
2023-03-14

我在我的spring boot项目中也遇到了类似的问题,但是这里的解决方案很容易。我意识到每当你在父对象之前持久化一个子对象时,你总是会得到分离的持久化异常,也就是说,你不应该放置层叠。子实体上的所有约束。

许胡非
2023-03-14

查看您的员工实体,您已将部门配置为级联ALl,这意味着每当员工实体<code>PERSIST、MERGE、REMOVE、REFRESH、DETACH</code>时,部门都会执行同样的操作。

现在回到你的问题。在您的填充表函数中,您已经创建了部门和员工实体,您需要像这样链接部门 员工

e1.setDepartment(d1);

最后坚持员工,这将为你坚持员工和部门

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

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

  • 我有两个模型,一个用于存储用户详细信息,使用该Id,我试图将用户位置保存在另一个表中,该表使用用户的相同Id作为主键。 为什么我会出现这个错误?坚持是什么意思?我正在使用MySQL数据库(&I)

  • 当试图在web应用程序上创建课程实体实例时,我们遇到以下错误。这是一个JHipster应用程序完整的错误日志,下面是,但主要错误是 更新的代码:

  • 无法保存子对象引用。 Employee parent对象包含子Employee\u详细信息,该详细信息还定义了一个@manytone来保存地址对象。 表结构 实体 在REST控制器方法中: 例外情况: 我无法用子表EmployeeDetail保存地址详细信息。这里怎么了?

  • 我有一个JPA持久化的对象模型,它包含多对一的关系:一个有许多。一个有一个。 下面是代码片段: 我能够创建对象,向其添加事务,并正确地持久化对象。但是,当我创建一个事务,使用一个现有的已经持久化的帐户,并持久化该事务时,我会得到一个异常: 原因:org.hibernate.PersistentObjectException:已分离的实体传递给Persist:com.PaulSanwald.Acco