Hibernate JPA один-к-одному сохраняет сущность дочернего класса
У меня есть отношения один к одному, используя PrimaryKeyJoinColumn
аннотируется на родительской стороне. И теперь я хочу сохранить дочернюю сущность самостоятельно.
Например, у меня есть Employee
а также EmpInfo
как дочерняя сущность, мне нужно сохранить 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);
Будем очень благодарны за любые указания относительно того, как я могу попытаться сохранить дочернюю сущность?
1 ответ
Проблема здесь в том, что @Id
из EmployeeInfo
объявляется автоматически генерируемым, и поэтому вы не должны устанавливать его вручную (Hibernate просматривает сущность, переданную в persist
и предполагает, что он уже находится в базе данных, потому что @Id
поле заполнено).
Другими словами, удалите @GeneratedValue
на EmployeeInfo
если вы хотите установить ПК вручную.
Обратите внимание, что Hibernate обеспечивает поддержку OneToOne
ассоциация с использованием общего первичного ключа в JPA 1.0 через пользовательское расширение. Увидеть:
В JPA 2.0, производные идентификаторы хорошо поддерживаются, и вы можете аннотировать OneToOne
а также ManyToOne
ассоциации с @Id
, Увидеть: