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, Увидеть:

Другие вопросы по тегам