2011-06-03 28 views
0

我在我的應用程序中使用JPA/Hibernate與Spring事務管理。 有一個InspectionEntity與InspectionDetailEntity具有一對多的關係。 實體的PK由數據庫中的插入觸發器創建。我嘗試保存時的PK值是默認的0值。 我通過調用addInspectionDetail()將InspectionDetailEntity添加到InspectionEntity中,然後保存InspectionEntity - entityManager.persist(inspection); 我期望的是將檢查與所有InspectionDetail一起保存。 但是,這導致 org.hibernate.NonUniqueObjectException:具有相同標識符值的不同對象已與會話相關聯:[com.xyz.entity.InspectionDetailEntity#0]。 我也嘗試將設置直接設置到InspectionEntity中(不使用addInspectionDetail())。這也會導致相同的錯誤。任何幫助將不勝感激。Hibernate - NonUniqueObjectException

@Entity 
@Table(name = "tb_inspection") 
public class InspectionEntity { 

    @Id 
    @Column(name = "inspection_id") 
    private Integer inspectionId; 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "inspectionDetailId", cascade = CascadeType.ALL) 
    @JoinColumn(name = "inspection_id", insertable = true, updatable = true) 
    private Set<InspectionDetailEntity> inspectionDetails; 

    /** 
    * Adds a inspectionDetailEntity to the set of inspectionDetails 
    * @param inspectionDetailEntity 
    */ 
    public void addInspectionDetail(InspectionDetailEntity inspectionDetailEntity) { 
     if(inspectionDetails == null) 
      inspectionDetails = new HashSet<InspectionDetailEntity>(); 
     inspectionDetailEntity.setInspection(this); 
     inspectionDetails.add(inspectionDetailEntity); 
    } 
    //setter and getters 
} 


@Entity 
@Table(name = "tb_inspection_dtl") 
public class InspectionDetailEntity { 

    @Id 
    @Column(name = "inspection_dtl_id") 
    private Integer inspectionDetailId; 

    @Column(name = "inspection_id") 
    private Integer inspectionId; 

    @ManyToOne 
    @JoinColumn(name="inspection_id", insertable = false, updatable = false) 
    private InspectionEntity inspection; 


    //setters and getters 

} 

回答

2

不要設置ID爲0。保留爲空。如果設置了值,Hibernate會假定該對象已經在數據庫中並嘗試更新它。

而且你很可能以多個具有相同id(0)的對象結束。


更新

正如我想想,你是,很可能被迫id設置爲某個值,因爲你沒有id生成和Hibernate希望你的ID提供價值。但是,Hibernate中沒有任何內容會在插入後更新對象上的id。所以你最終在與ID爲0的會話中的多個對象。

我不知道什麼是這種情況的好辦法。很可能你需要編寫自定義ID生成器。但是在序列的情況下,例如,它需要額外的數據庫調用。可能你應該考慮觸發以外的id分配?

+0

我明確地將inspectionDetailId設置爲null,並試圖保存。但現在我得到一個'org.hibernate.id.IdentifierGenerationException:這個類的id必須在調用save()之前手動賦值:com.xyz.entity.InspectionDetailEntity' – Joji 2011-06-03 09:56:43

+0

@joji這正是我的觀點。既然你沒有指定id生成器,Hibernate希望你提供id。但是每個對象都必須是真實的id。所以你的觸發器ID分配有問題。檢查文檔,可能會有一些適合您的用例的生成器 – 2011-06-03 15:10:16

+0

我刪除了DB插入觸發器,而是在我的實體PK屬性上使用了DB序列(@SequenceGenerator)。我知道它不是一個非常令人印象深刻的解決方案,因爲需要額外調用以獲取每個子對象的下一個序列值。也許在稍後的時間,我會選擇像seqhilo這樣的自定義ID生成器。 – Joji 2011-06-06 11:12:58

0

嘗試刪除或者

inspectionDetailEntity.setInspection(this);

inspectionDetails.add(inspectionDetailEntity); 

我不認爲你需要兩者。

您保存之前這可能是值得考慮您的孩子和父母之間的關係單向

相關問題