gpt4 book ai didi

java - saveorupdate()在hibernate中不更新集合(list)一对多映射

转载 作者:搜寻专家 更新时间:2023-11-01 03:38:48 25 4
gpt4 key购买 nike

类(class)学生

public class Student {

private Long id;
private String name;
private String className;
private List<Phone> phones;
// getter setter
}

电话

public class Phone {

private Long id;
private String number;
//getter setter
}

->映射文件Student.hbm.xml

     <id name="id" type="long" column="id">
<generator class="native" />
</id>

<property name="name" column="name" type="string" />

<property name="className" column="class_name" type="string" />

<list name="phones" cascade="all-delete-orphan">
<key column="student_id"/>
<list-index column="idx" />
<one-to-many class="Phone" />
</list>

->映射文件Phone.hbm.xml

    <id name="id" type="long" column="id">
<generator class="native" />
</id>

<property name="number" column="number" type="string" />

当我尝试更新电话号码(列表)时,前一个条目没有被删除,但 idx(列表索引)和外键为空,新条目标有正确的 idx 和外键! !其他数据(不是列表)已完全更新。在这里,我从数据库中获取类对象,对其进行修改并将该对象传递给 saveorupdate(),但没有帮助。已经尝试了这么久。

读取和更新的代码:

      private void readAndUpdateStudent() {
Student student = null;
Session session = HibernateUtil.getSessionFactory().openSession();
String name = "John";
try {

String queryString = "from Student student where student.name =:name";
Query query = session.createQuery(queryString);
query.setString("name", name);
student = (Student) query.uniqueResult();
System.out.println(student.getName());
student.setName("Mary");
List<Phone> phones = new ArrayList<Phone>();
phones.add(new Phone("555555")); //here if I SET rather adding, the already existing values, update is done accordingly
phones.add(new Phone("789789"));//but when I use the list as a string type(instead of Phone Type), adding a new 0bject deletes the previous
student.setPhones(phones);//entries and adds new list on its own but not in the case of user defined type.

} catch (Exception e) {
e.printStackTrace();
if (session != null) {

session.close();

}

}finally{

session.close();
updateStudent(student);
}

}
private void updateStudent(Student student) {

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;

try {
tx = session.beginTransaction();
session.saveOrUpdate(student);
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}

enter image description here

最佳答案

我注意到这现在有点旧了,但是 FWIW,另一个答案是正确的,你不应该在 hibernate 检索的持久实体上设置新集合,因为这会像你的情况一样创建孤儿。

Hibernate 代理实体,因此它可以管理实体属性的数据库更新(哪些字段已更改等)。因此,当您检索实体并设置新列表时,hibernate 失去了跟踪该列表中曾经存在的内容的更改的能力。因此,您应该按照指出的那样更新现有列表,以便在更新时删除孤儿。您也可以使用 clear()。

List<Phone> phones = student.getPhones();
phones.clear();
phones.add(new Phone("555555"));
phones.add(new Phone("789789"));
session.saveOrUpdate(student);

如果您想避免重复,请尝试使用 Set 而不是列表,并在 Phone 类上实现 hashCode() 和 equals(),例如,检查 phone.number 上的检查相等性可能有意义。

希望这有帮助:)

关于java - saveorupdate()在hibernate中不更新集合(list)一对多映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20637508/

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