具有相同标识符值的不同对象已与会话关联

时间:2012-06-01 12:07:54

标签: java hibernate set

  

可能重复:
  Hibernate: different object with the same identifier value was already associated with the session

我收到以下错误:

具有相同标识符值的其他对象已与会话

关联

我有两种类型的对象,Course和RecommendedSchedule,它们有一套课程。 以下是他们的xml定义:

<hibernate-mapping>
<class name="database.datatypes.Course" table="courses" lazy="false">
    <id name="id" column="ID">
         <generator class="assigned"/>
    </id>
    <property name="name" type="string"/>
    <property name="date"/>
</class>

<hibernate-mapping>
<class name="database.datatypes.RecommendedSchedule" table="recommended_schedules" lazy="false">
    <id name="id" column="ID">
         <generator class="increment"/>
    </id>
    <set name="courses" table="schedules_courses" cascade="save-update" lazy="false">
        <key column="course_id"/>
        <many-to-many class="database.datatypes.Course"/>
    </set>
    <property name="semester" type="string"/>
    <property name="path" type="string"/>
</class>

基本上如果我插入两个推荐的系统使用不同的设置,但使用相同的课程对象,它可以工作,但如果我做同样的事情,但使用不同的课程对象(具有相同的值)我得到错误。

任何人都知道我做错了什么?

以下是一段代码失败的示例:

Session s = db.factory.openSession();
    Set<Course> set1 = new HashSet<>();
    Set<Course> set2 = new HashSet<>();
    Course c1 = new Course(104167L, "Algebra A");
    Course c2 = new Course(234114L, "Introduction to CS H and M");
    Course c3 = new Course(104012L, "Calculus 1 T");
    Course c4 = new Course(234145L, "Digital Systems");
    Course c12 = new Course(104167L, "Algebra A");
    Course c22 = new Course(234114L, "Introduction to CS H and M");
    Course c32 = new Course(104012L, "Calculus 1 T");
    Course c42 = new Course(234145L, "Digital Systems");
    set1.add(c1);
    set1.add(c2);
    set1.add(c3);
    set2.add(c12);
    set2.add(c22);
    set2.add(c32);
    set2.add(c42);
    RecommendedSchedule r1 = new RecommendedSchedule(set1, "General 3 years", "1");
    RecommendedSchedule r2 = new RecommendedSchedule(set2, "General 4 years", "1");
    Collection<RecommendedSchedule> col = new ArrayList<RecommendedSchedule>();
    Collection<Course> col2 = new ArrayList<Course>();
    col.add(r1);
    col.add(r2);
    col2.add(c12);
    col2.add(c22);
    col2.add(c32);
    col2.add(c42);

    Transaction t = s.beginTransaction();
    s.save(r1);
    s.save(r2);
    t.commit();
    s.close();

如果我改为:

set2.add(c1);
set2.add(c2);
set2.add(c3);
set2.add(c4);

它会奏效。 (这当然不是真正的问题,而是一个简单的例子)

2 个答案:

答案 0 :(得分:9)

最后我只使用了merge()而不是save(),即使我有一组对象而不仅仅是尝试使用普通对象,它似乎也能解决问题。

答案 1 :(得分:2)

id是Course表的唯一键。每个id值只能使用一次。你在课程之间的关系是m:n。

当您对同一课程(相同的ID)使用不同的实例时,则尝试插入具有相同ID的两个不同的行。这不行。 Hibernate记住每个实例(实例,而不是键值!),如果它已经保存,并且因为你使用级联,那么在保存Hibernate的那一刻看看哪些子实例还没有保存,如果你保存c1首先,然后c12尚未保存,稍后保存会产生错误。

解决方案:在RecommendedSchedule的两个课程列表中插入相同的Course实例。无论如何,它们都是相同的课程。