2016-10-14 81 views
0

每個人。我是Hibernate的新手,在對象持久化方面遇到了一些意想不到的麻煩。 下面是相關的提取從我的實體類:hibernate非空屬性引用空值或瞬態值

TAnalysis.java

public class TAnalysis implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE) 
    private Integer unAnalysis; 

    @JoinColumn(name = "uninttest", referencedColumnName = "un_inttest", nullable = false) 
    @ManyToOne(fetch = FetchType.EAGER, optional = false, cascade = CascadeType.ALL) 
    private TIntTest tIntTest; 

    @OneToOne(optional = false, mappedBy = "tAnalysis", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    private TBaseComp tBaseComp; 

    @OneToOne(optional = false, mappedBy = "tAnalysis", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    private TWellTest tWellTest; 

    @OneToOne(optional = false, mappedBy = "tAnalysis", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    private TGasPart tGasPart; 

    @OneToOne(optional = false, mappedBy = "tAnalysis", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    private TAddOnComp tAddOnComp; 
} 

TIntTest.java

public class TIntTest implements Serializable, ISimpleEntity { 

    @Id 
    @GeneratedValue (strategy = GenerationType.SEQUENCE) 
    @Column (name = "un_inttest", nullable = false) 
    private Integer unInttest; 

    @OneToMany (cascade = CascadeType.ALL, mappedBy = "tIntTest") 
    private Set<TAnalysis> tAnalysisSet; 
} 

TBaseComp.java

public class TBaseComp implements Serializable { 

    @Id 
    @Column(name = "un_analysis", nullable = false) 
    private Integer unAnalysis; 

    @MapsId 
    @JoinColumn(name = "un_analysis", referencedColumnName = "un_analysis", nullable = false, insertable = false, updatable = false) 
    @OneToOne(optional = false, fetch = FetchType.EAGER) 
    private TAnalysis tAnalysis; 
} 

其他類(TAddOnCompTGasPartTWellTest),其具有[@OneToOne]與TAnalysis(種類 「亞類」)的關係與TBaseComp共享相同的結構。

所有列出的關係都必須爲非空。所以,當我堅持新的TAnalysis實例我必須指定TIntTest對象,也必須創建「子類」實例。這就是我要做的事:

EntityManager em = emf.createEntityManager(); 
TAnalysis an = new TAnalysis(); 
TBaseComp baseComp = new TBaseComp(); 
TGasPart gasPart = new TGasPart(); 
TAddOnComp addInComp = new TAddOnComp(); 
TWellTest wellTest = new TWellTest(); 

an.setTBaseComp(baseComp); 
an.setTGasPart(gasPart); 
an.setTAddOnComp(addInComp); 
an.setTWellTest(wellTest); 

baseComp.setTAnalysis(an); 
gasPart.setTAnalysis(an); 
addInComp.setTAnalysis(an); 
wellTest.setTAnalysis(an); 

TIntTest intTest = em.find(TIntTest.class, 10); 
an.setTIntTest(intTest); 

an = em.merge(an); 
//baseComp = em.merge(baseComp); 
//gasPart = em.merge(gasPart); 
//addOnComp = em.merge(addOnComp); 
//wellTest = em.merge(wellTest); 
//em.persist(an); 
em.getTransaction().commit(); 

合併操作拋出一個異常

org.hibernate.PropertyValueException: not-null property references a null or transient value : org.foladesoft.omnibus_client_maven.entities.TAnalysis.tIntTest" 

我不明白爲什麼會這樣,因爲我指定requered屬性值an.setTIntTest(intTest);

試圖解決我的問題,我用em.persist(an),而不是合併,但得到了在另一個異常提交階段:PostgreSQL的外鍵衝突異常告訴我,我試圖插入新記錄之前,插入記錄到TAddOnComp進入TAnalysis

您能否告訴我爲什麼我遇到了這些問題以及如何讓我的應用程序工作。

+0

我recommen調試em.find是否返回一個非空TIntTest。另外,讓Hibernate記錄更新查詢,包括params。 – Kirinya

回答

0

首先,因爲這是一個新的實體,你應該叫:

em.persist(an); 

調用em.persist當你得到FK違反原因(一)是TAddOnComp一無所知它的相關TAnalysis等它不能插入FK。

對於雙向關係您總是需要在您的內存模型中保持關係的雙方。然後,TAddOnComp將對其相關聯的TAnalysis進行引用,並且插入操作可以相應地獲得並插入FK。

TAnalysis an = new TAnalysis(); 
an.setTBaseComp(baseComp); 
an.setTGasPart(gasPart); 
//etc 
baseComp.setAnalysis(an); 
gasPart.setAnalysis(an); 
//etc 
em.persist(an); 

理想情況下,你應該封裝這些操作:

public class TAnalysis implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE) 
    private Integer unAnalysis; 

    private TAddOnComp tAddOnComp; 

    public void setTAddOnComp(TAddOnComp tAddOnComp){ 
     this.tAddOnComp = tAddOnComp; 

     if(! tAddOnComp.getTAnalysis != this){ 
      tAddOnComp.setTAnalysis(this); 
     } 

     // and do the same on the other side of the relationship 
    } 
} 
相關問題