gpt4 book ai didi

java - 具有相同标识符值的不同对象已与 session :. 关联,合并和 saveOrUpdate 都不起作用

转载 作者:行者123 更新时间:2023-11-30 07:19:14 25 4
gpt4 key购买 nike

我有一个 GUI,其中显示了教师列表。两个由用户选择 - 他们将成为创建的新学校类(class)的类主任。师-类关系是n-m。

学校类:(它从它的组继承它的id)

@Entity
@Table(name="school_classes")
@Cacheable(true)
public class SchoolClass extends Group{

@ManyToMany(cascade=CascadeType.ALL, mappedBy="classes", fetch=FetchType.EAGER)
private SortedSet<Teacher> teachers;

老师:

  @Entity
@Table(name="teachers")
@Cacheable(true)
public class Teacher extends creator.models.school.Entity{
// name etc

@ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinTable(name="class_teachers",
joinColumns = @JoinColumn(name="teacher_id", referencedColumnName="id"),
inverseJoinColumns = @JoinColumn(name="class_id", referencedColumnName="id"))
private SortedSet<SchoolClass> classes;

我尝试像这样创建一个新类:

String className = request.getParameter("class_name");
String id1 = request.getParameter("class_teacher1");
String id2 = request.getParameter("class_teacher2");
Teacher t1 = DataRetrieveModule.getTeacher(id1);
Teacher t2 = DataRetrieveModule.getTeacher(id2);


Layout l = new Layout();
SchoolClass newClass = new SchoolClass(className);
newClass.setLayout(l);
newClass.addTeacher(t1);
t1.addClass(newClass);

newClass.addTeacher(t2);
t2.addClass(newClass);
DataInsertionModule.insert(newClass);

此语句 DataRetrieveModule.getTeacher(id1) 打开一个 session ,通过 ID 检索教师并关闭它。DataInsertionModule.insert(newClass) 也打开一个 session ,调用session.saveOrUpdate(newClass)。 (我也试过 session.merge(newClass))

检索教师:

public static Teacher getTeacher(String id) {
Session session = null;
Teacher t = null;
try{
sessionFactory = MyFactory.getSessionFactory();
session = sessionFactory.openSession();
t = (Teacher) session.get(Teacher.class, Long.parseLong(id));

}
catch(Exception e) {
System.out.println("in DAO:");
e.printStackTrace();
if(session!=null)
session.close();
}
finally{
if(session!=null)
session.close();
}

return t;
}

数据插入:

public static void insert(Object o) {
Session session = null;

try
{
sessionFactory = MyFactory.getSessionFactory();
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

session.save(o);
tx.commit();

System.out.println("insertion done");
}
catch (Exception e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
finally
{
if(session!=null)
session.close();
}
}

但是插入永远不会起作用。始终存在一个具有相同 ID 的对象。

a different object with the same identifier value was already associated with the session: [creator.models.school.Teacher#3]

我在 stackoverflow 上搜索并覆盖了类中的 getHashCode 和 equals 方法,我所有的业务对象都继承自:

@Override
public int compareTo(Entity o) {
if(this.id < o.getId())
return -1;
else if(this.id > o.getId())
return 1;
return this.getClass().getName().compareTo(o.getClass().getName());
}

@Override
public boolean equals(Object o) {
if(o instanceof Entity)
return this.compareTo((Entity)o)==0;
else return this.equals(o);
}

@Override
public int hashCode() {

char[] bla = this.getClass().getName().toCharArray();
int blue=0;
for(char c:bla)
blue = blue*10 + c;
return (int) (id+blue);

}

此外,我尝试将 ManyToManyCascadeType 更改为 MERGE(再次还原)。

目前,我在使用 session.get(..) 检索它们之后合并了 teacher 对象,因为检索会从数据库中获取大量数据。还有更多的 ..ToMany 关系。因此,可能会发生这种情况,即调用会导致两位教师都被加载。

public static Object merge(Object o) {
Session session = null;
Object returnVal = null;
try
{
sessionFactory = MyFactory.getSessionFactory();
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
returnVal = session.merge(o);
tx.commit();

}
catch (Exception e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
finally
{
if(session!=null)
session.close();
}
return returnVal;
}

.

Teacher t1 = DataRetrieveModule.getTeacher(id1);
Teacher t2 = DataRetrieveModule.getTeacher(id2);

t1= DataInsertionModule.merge(t1);
t2= DataInsertionModule.merge(t2);

因此我想,如果我将我的 get 方法返回的那个与必须由另一位老师的 get 调用加载的那个合并,它应该可以工作。 (像这里:http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/)但它没有:(

是否可能是因为同一父类(super class)(对象或我的实体类)的对象具有相同的 ID?

请帮帮我!

最佳答案

可能导致此错误的一种潜在情况是教师 1 和教师 2 的 ID 相同。由于您关闭了每次获取之间的 session ,它们将被分离,并且您最终会加载两个不同的对象,它们都代表数据库中的同一行(它们具有相同的主键)。然后,当它们都将被重新附加时通过正在保存的 SchoolClass 到 session ,Hibernate 将看到两个不同的对象都代表数据库中的同一行,并且不知道哪个代表正确的状态以持久保存到数据库中。

不确定这里是否属于这种情况,但您应该运行调试器并检查 teacher1 和 teacher2 引用的对象的状态。

关于java - 具有相同标识符值的不同对象已与 session :. 关联,合并和 saveOrUpdate 都不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14751730/

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