gpt4 book ai didi

java - Hibernate:使用已经存在的子对象保存父对象(单向)

转载 作者:行者123 更新时间:2023-11-29 08:45:22 27 4
gpt4 key购买 nike

我想保存/保留一个实体(父实体),该实体(父实体)具有仅由父对象包含的唯一子对象。一切正常,直到出现重复的 child ,在这里我得到以下异常:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry


首先你必须知道我正在使用表达式 session.bySimpleNaturalId(Child.class).load(child.getMd5Hash()) 来检查 child 是否已经存在,因为所有子对象具有唯一的哈希值(在初始化后创建),这些值未明确分配为主键(它们的主键是自动递增的;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 那些 child 不应该被视为需要持久化的新对象?或者我什至必须切换到双向关系?(在这种情况下我目前不允许使用双向关系)

欢迎任何提示,非常感谢,提前致谢。问候,雪人

最佳答案

我自己找到了答案,也就是错误。起初修复它我使用了一个单独的函数来检查一个 child 是否存在,此外我使用单独的 session 来检查它们(如果禁用 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();
}

关于java - Hibernate:使用已经存在的子对象保存父对象(单向),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25724949/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com