4

重複の可能性:
休止状態:同じ識別子値を持つ別のオブジェクトがすでにセッションに関連付けられています

次のエラーが発生します。

同じ識別子値を持つ別のオブジェクトがすでにセッションに関連付けられていました

私には、Courseと一連のコースがあるRecommendedScheduleの2種類のオブジェクトがあります。それらの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>

基本的に、異なるセットで2つの推奨システムを挿入し、同じコースオブジェクトを使用すると機能しますが、まったく同じことを実行し、異なるコースオブジェクト(同じ値)を使用すると、エラーが発生します。

誰かが私が間違っていることを知っていますか?

失敗するコードの例を次に示します。

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);

それはうまくいっただろう。(もちろんこれは本当の問題ではありませんが、簡単な例です)

4

2 に答える 2

10

最後に、save() の代わりに merge() を使用しただけで、通常のオブジェクトを操作しようとしているだけでなく、一連のオブジェクトがあっても問題が解決したようです。

于 2012-06-04T18:15:12.723 に答える
2

id は Course テーブルの一意のキーです。各 id 値は 1 回だけ使用できます。Course 間の関係は m:n です。

同じコース (同じ ID) に異なるインスタンスを使用すると、同じ ID を持つ 2 つの異なる行を挿入しようとします。これはうまくいきません。Hibernate は各インスタンス (キー値ではなくインスタンス!) が既に保存されているかどうかを記憶し、カスケードを使用しているため、Hibernate を保存する瞬間にどの子インスタンスがまだ保存されていないかを確認し、c1最初に保存した場合c12はそうではありませんまだ保存して後で保存すると、エラーが発生します。

解決策: コースの同じインスタンスを、RecommendedSchedule の両方のコース リストに挿入します。とにかく同じコースです。

于 2012-06-01T12:43:55.997 に答える