大家。我是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;
}
与 TAnalysis 有[@OneToOne]关系的其他类( TAddOnComp , TGasPart 和 TWellTest )(某种&#34;子类&#34;)与 TBaseComp 共享相同的结构。
所有列出的关系必须不为null。因此,当我坚持新的 TAnalysis 实例时,我必须为它指定 TIntTest 对象,并且还必须创建&#34;子类&#34;实例。这就是我如何做到的:
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"
我无法理解为什么会发生这种情况,因为我指定了已重新标记的属性值an.setTIntTest(intTest)
;
尝试解决我的问题我使用了em.persist(an)
而不是合并但在提交阶段又遇到了另一个例外:PostgreSQL的外键违规异常告诉在将新记录插入 TAnalysis 之前,我试图将记录插入 TAddOnComp 。
您能否告诉我为什么遇到这些问题以及如何使我的应用程序正常运行。
答案 0 :(得分:0)
首先,因为这是一个新的实体,你应该打电话:
em.persist(an);
调用em.persist(an)时出现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
}
}