Hibernate JPA один-к-одному сохраняет сущность дочернего класса - PullRequest
4 голосов
/ 16 августа 2010

У меня отношение один-к-одному, используя 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 Ответ

9 голосов
/ 17 августа 2010

Проблема здесь в том, что @Id из EmployeeInfo объявлен как автоматически сгенерированный, и поэтому вы не должны устанавливать его вручную (Hibernate просматривает сущность, переданную в persist, и предполагает, что она уже в базе данных, потому что заполнено поле @Id).

Другими словами, удалите @GeneratedValue на EmployeeInfo, если вы хотите установить PK вручную.

Обратите внимание, что Hibernate обеспечивает поддержку OneToOne связи с использованием общего первичного ключа в JPA 1.0 через пользовательское расширение. См:

В JPA 2.0, производные идентификаторы хорошо поддерживаются, и вы можете аннотировать OneToOne и ManyToOne ассоциации с @Id. Смотрите:

...