2010-08-16 69 views
4

我有一個使用PrimaryKeyJoinColumn在父級註釋的一對一關係。現在我想自己保存子實體。休眠JPA一對一保存子類實體

例如,我有EmployeeEmpInfo作爲子實體,我需要保存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("[email protected]"); 
concreteDAO.save(emp); // This uses the JPATemplate provided by Spring JpaDaoSupport 


info.setId(emp.getId()); 
concreteDAO.saveEmpInfo(info); 

任何po inters非常感謝,至於我怎樣才能嘗試保存子實體?

回答

9

這裏的問題是,EmployeeInfo@Id被宣佈爲被自動生成的,你就因此不應該手動(休眠着眼於實體傳遞給persist並假定它是已在數據庫中,因爲設置@Id字段已填充)。

換句話說,如果要手動設置PK,請在EmployeeInfo上刪除@GeneratedValue

請注意,Hibernate通過自定義擴展提供對使用JPA 1.0中的共享主鍵關聯的OneToOne關聯的支持。請參閱:

在JPA 2.0,得到的標識符很好的支持,你可以批註OneToOneManyToOne協會與@Id。請參閱:

+0

大感謝很多的大開眼界,我做了昨晚一樣(之前我看到這個帖子),它解決了這個問題。 但是,我不確定這是否是一種好的做法(因爲它可能會導致因服務用戶將不正確的ID設置爲EmployeeInfo而導致數據損壞),還是應請求服務用戶傳遞整個對象圖(父對象以及孩子)拯救... – PaiS 2010-08-17 06:05:31