一尘不染

Hibernate JPA一对一保存子类实体

hibernate

PrimaryKeyJoinColumn在父方使用批注具有一对一关系。现在,我想自己保存子实体。

例如,我有EmployeeEmpInfo作为孩子的实体,我需要保存EmpInfo(父的id属性设置为之后的课程)。但是,当使用这种安排时,我在下面列出了一个例外…

org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist

为什么hibernate不允许这样做的任何想法?更清楚地说,我的代码如下…

ParentEntity:

public class Employee {
    private Long id;
    private String name;
    private EmployeeInfo info;
    private Integer enumId;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    @Column(name="EMP_NAME")
    public String getName() {
        return name;
    }

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = CascadeType.REMOVE)
    public EmployeeInfo getInfo() {
        return info;
    }
  }

ChildEntity:

@Table(name="EMP_INFO")
@Entity
public class EmployeeInfo {
    private Long id;
    private String email;

    @Column(name="EMPLOYEE_EMAIL")
    public String getEmail() {
        return email;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "emp_id", nullable = false)
    public Long getId() {
        return id;
    }
}

我尝试保存的方式是…

Employee emp = new Employee();
emp.setEnumId(SimpleEnum.COMPLETE);
emp.setName("Shreyas");
EmployeeInfo info = new EmployeeInfo();
info.setEmail("Sh@gmail");
concreteDAO.save(emp);   // This uses the JPATemplate provided by Spring JpaDaoSupport


info.setId(emp.getId());
concreteDAO.saveEmpInfo(info);

关于如何尝试保存子实体,任何指针将不胜感激。


阅读 572

收藏
2020-06-20

共1个答案

一尘不染

这里的问题是@IdofEmployeeInfo被声明为自动生成的,因此您不应该手动设置它(Hibernate查看传递给的Entity,persist并假设它已经存在于数据库中,因为该@Id字段已填充)。

换句话说,如果要手动设置PK ,请删除@GeneratedValueon EmployeeInfo

注意,Hibernate OneToOne通过自定义扩展在JPA 1.0中使用共享主键为关联提供支持。看到:

  • JPAhibernate一对一关系

在JPA 2.0中,派生标识符得到了很好的支持,您可以使用进行注释OneToOneManyToOne关联@Id。看到:

  • 通过一对一关系的主键
2020-06-20