Hibernate JPA one-to-one saving child class entity
The problem here is that the @Id
of EmployeeInfo
is declared as being auto-generated and you're thus not supposed to set it manually (Hibernate looks at the Entity passed to persist
and assumes it is already in the database because the @Id
field is populated).
In other words, remove the @GeneratedValue
on EmployeeInfo
if you want to set the PK manually.
Note that Hibernate provides support for OneToOne
association using a shared primary key in JPA 1.0 through a custom extension. See:
In JPA 2.0, derived identifiers are well supported and you can annotate OneToOne
and ManyToOne
associations with @Id
. See:
PaiS
A complete techie, who realised that he cannot stay away from technology, after being away from technology (into management stuffs) for a short while in his career. Working mainly on Java and related open-source technologies/frameworks like Spring, Hibernate. Passionate about mushrooming open-source frameworks and inter-systems integration, which are the way to go these days...!
Updated on June 19, 2022Comments
-
PaiS almost 2 years
I have a one-to-one relationship using
PrimaryKeyJoinColumn
annotated on the parent side. And now I want to save the child entity by itself.For example, I have
Employee
andEmpInfo
as the child entity, I need to saveEmpInfo
(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...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?