java Hibernate JPA 一对一保存子类实体

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3492608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:04:30  来源:igfitidea点击:

Hibernate JPA one-to-one saving child class entity

javahibernateormjpaone-to-one

提问by PaiS

I have a one-to-one relationship using PrimaryKeyJoinColumnannotated on the parent side. And now I want to save the child entity by itself.

PrimaryKeyJoinColumn在父端使用注释有一对一的关系。现在我想自己保存子实体。

For example, I have Employeeand EmpInfoas the child entity, I need to save EmpInfo(of course after setting the id property of the parent to it). However, when such an arrangement is used, I get an exception listed below...

例如,我有EmployeeEmpInfo作为子实体,我需要保存EmpInfo(当然在将父实体的 id 属性设置为它之后)。但是,当使用这种安排时,我会得到下面列出的例外情况......

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

Any ideas why hibernate does not allow this? To be more clear, the code I have is below...

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

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;
    }
}

The way I try to save it is...

我试图保存它的方法是......

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);

Any pointers would be much appreciated, as to how can I try to save the child entity?

任何指针将不胜感激,至于我如何尝试保存子实体?

回答by Pascal Thivent

The problem here is that the @Idof EmployeeInfois declared as being auto-generated and you're thus not supposed to set it manually (Hibernate looks at the Entity passed to persistand assumes it is already in the database because the @Idfield is populated).

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

In other words, remove the @GeneratedValueon EmployeeInfoif you want to set the PK manually.

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

Note that Hibernate provides support for OneToOneassociation using a shared primary key in JPA 1.0 through a custom extension. See:

请注意,HibernateOneToOne通过自定义扩展支持使用 JPA 1.0 中的共享主键进行关联。看:

In JPA 2.0, derived identifiers are well supported and you can annotate OneToOneand ManyToOneassociations with @Id. See:

在JPA 2.0,得到的标识符很好的支持,你可以批注OneToOneManyToOne协会有@Id。看: