我想保存/持有具有仅由父对象包含的唯一子对象的实体(父)。 任何事情都有效,直到出现重复的孩子,这里我得到以下例外:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry
首先,您必须知道我使用表达式session.bySimpleNaturalId(Child.class).load(child.getMd5Hash())
来检查子项是否已存在,因为所有子对象都具有唯一的哈希值(在初始化后创建),这些哈希值明确未指定为主键(主键是自动增量; strategy = GenerationType.TABLE
)。
我是否在我的DAO上使用session.merge(child)
或任何其他表达式,我得到相同的例外。
我的父对象:
@Entity
@Table(name = "parent")
public class Parent implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id = null;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "kind_child_id", referencedColumnName = "md5hash")
private Child firstChild;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "rude_child_id", referencedColumnName = "md5hash")
private Child secondChild;
//private String attributes;
//Getters & Setters
我的孩子 - 对象:
@Entity
@Table(name = "child")
public class Child implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id = null;
@NaturalId
@Column(name="md5hash", unique=true)
private char[] md5hash = new char[32];
//private String attributes;
//Getters & Setters
这是我保存/持久保存父项的方法(包括验证):
public void writeParent(Parent parent) {
try {
if (parent != null) {
if (globalSession == null) {
globalSession = getSessionFactory().openSession();
}
globalSession.beginTransaction();
if (parent.getFirstChild() != null) {
Child tempFirstChild = (Child) globalSession.bySimpleNaturalId(Child.class).load(parent.getFirstChild().getMd5Hash());
if (tempFirstChild != null) {
parent.setFirstChild(tempFirstChild);
//globalSession.merge(tempFirstChild);
//throws MySQLICV-Exception
//globalSession.update(tempFirstChild);
//throws MySQLICV-Exception
}
}
if (parent.getSecondChild() != null) {
Child tempSecondChild = (Child) globalSession.bySimpleNaturalId(Child.class).load(parent.getSecondChild().getMd5Hash());
if (tempSecondChild != null) {
parent.setSecondChild(tempSecondChild);
//globalSession.merge(tempSecondChild);
//throws MySQLICV-Exception
//globalSession.update(tempSecondChild);
//throws MySQLICV-Exception
}
}
globalSession.saveOrUpdate(parent);
//globalSession.persist(parent);
globalSession.getTransaction().commit();
}
} catch (Exception ex) {
log.error("FAILURE: ", ex);
}
finally{
globalSession.close();
}
}
也许我并不了解整个纪录片,这就是我为什么会这样做的原因:我是否还要告诉Hibernate合并找到的实体?
我如何告诉Hibernate这些孩子不应该被视为需要坚持的新物品?
或者我甚至必须切换到双向关系?(在这种情况下我目前不允许使用双向关系)
欢迎任何提示,非常感谢,提前谢谢。 此致,Yeti
答案 0 :(得分:0)
我找到了答案a.k.a我自己的错误。 首先修复它我使用了一个单独的函数来检查一个子是否存在,而且我使用了单独的会话来检查它们(如果L2C被禁用,它可能无效)。
synchronized public Child checkChild(Child child) {
try {
if (child != null) {
tempSession = getSessionFactory().openSession();
Child tempChild = (Child) tempSession.bySimpleNaturalId(Child.class).load(Child.getMd5Hash());
if (tempChild != null) {
return tempChild;
} else {
return child;
}
} else {
return null;
}
} catch (Exception ex) {
return null;
}
finally{
tempSession.close();
}
}
第二个并且有线索,我试图将父对象保存为参数值,这是错误的,所以只需在方法中启动一个新的父对象即可。
public void writeParent(Parent parent) {
tempParent = new Parent();
tempParent.setFirstChild(checkChild(tempParent.getFirstChild()));
tempParent.setSecondChild(checkChild(tempParent.getSecondChild()));
globalSession = getSessionFactory().openSession();
globalSession.beginTransaction();
globalSession.saveOrUpdate(tempParent);
globalSession.getTransaction().commit();
globalSession.close();
}