2009-07-09 7 views
5

私は、String型と1対多の関係を持つユーザーオブジェクトを持っています。私は彼らが単純なマッピングだと信じています。型テーブルは、基本的にカウンタである主キー 'id'を使用して、関連するuser_idおよび変数型名を保持します。Hibernate異常な動作を保存します。

<class name="Users" table="users"> 
    <id column="id" name="id" /> 
    ... 
    <set name="types" table="types" cascade="save-update"> 
     <key column="id" /> 
     <one-to-many class="Types" /> 
    </set> 
</class> 

<class name="Types" table="types"> 
    <id column="id" name="id" /> 
    <property column="user_id" name="user_id" type="integer" /> 
    <property column="type" name="type" type="string" /> 
</class> 

これは私がデータベースに追加するために使用するJavaである:私はそれを実行すると

User u = new User(); 
u.setId(user_id); 
... 
Collection<Types> t = new HashSet<Types>(); 
t.add(new Type(auto_incremented_id, user_id, type_name)); 
u.setTypes(t); 

getHibernateTemplate().saveOrUpdate(u); 

、それはこのエラーを与える:

61468 [http-8080-3] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1062, SQLState: 23000 
61468 [http-8080-3] ERROR org.hibernate.util.JDBCExceptionReporter - Duplicate entry '6' for key 'PRIMARY' 
61468 [http-8080-3] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session 
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 

私はSQLをチェックすると、それは示しています

Hibernate: insert into users (name, id) values (?, ?) 
Hibernate: insert into types (user_id, type, id) values (?, ?, ?) 
Hibernate: update types set id=? where id=? 
  • なぜHibernateは型のIDを更新しようとしますか?
  • エラー:「PRIMARY」キーのエントリが重複していますが、実際にはありませんか? IDを毎回インクリメントするようにしました。ユーザーとタイプはデータベースに正しく追加されます。

    追加された型のIDは7で、ユーザーIDは6です。Hibernateはuser_idが6で、型の更新を試み、id = 6を設定しようとしました。id = 7?したがって、重複した主キーのエラー?

    しかし、なぜそれは奇妙なことをしますか?それを更新するのを止める方法はありますか?

  • idを手動で設定する必要がありますか?そうでない場合は、どのようにタイプを追加しますか?その中に型文字列しかなく、idsも持たない型オブジェクトを追加すると、他のエラーが発生します。

みんなありがとう。数日間それを調べています...

答えて

2

<key>マッピングでは、あなたの最大の問題は不正な列です。 "id"ではなく "user_id"にする必要があります。つまり、あなたの全体のマッピングはちょっと奇妙に思えます。

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

読むHibernate Documentation様々な利用可能なオプションのための発電機に:あなたがしたい場合

まず第一には、IDの自動はあなたが本当にHibernateは適切なジェネレータを指定することにより、そのの世話をさせてください生成されました。第二に

、あなたが必要とするすべての要素のコレクションではなく、1対多の関係にそれらを再マッピングを検討し、文字列タイプのセットである場合:

 
<set name="types" table="types"> 
    <key column="user_id"/> 
    <element column="type" type="string"/> 
</set> 

あなたが必要としませんその方法明示的な "Types"クラスまたはそのマッピング。 「Types」に追加の属性を追加したい場合でも、エンティティではなくコンポーネントとしてマップすることができます。

最後に「タイプ」は、原因あなたが説明していないいくつかの要件に実体でなければならない場合は、「ユーザー」と「タイプ」との関係は双方向であり、そのようなとしてマッピングする必要があります

 
<set name="types" table="types" inverse="true"> 
    <key column="user_id"/> 
    <one-to-many class="Types"/> 
</set> 

... 
in Types mapping: 
<many-to-one name="user" column="user_id" not-null="true"/> 

後者の場合、 "Types"は "Users"タイプの "user"プロパティを持つ必要があります。 Hereが詳細な例です。私のために働いた

+0

のおかげで多くのことを双方向ソリューションをしようとします!ありがとう! – April

0

ソリューションは、個別に(ユーザーにタイプを追加せずに)二つの部分を保存することでした:

getHibernateTemplate().save(user); 
getHibernateTemplate().save(new Type(user.id, type_name)); 

そして/>だけの種類のIDで<ジェネレータクラス=「ネイティブ」と。

悪い練習ですか?

これは要素のコレクションとしてマップされていましたが、ときどき重複エラーの原因となるuseridを型ID列に誤って追加していました。型idは唯一の主キー列であるためです。奇妙な!私はある種の列エラーがあったことを覚えていますが、すぐに1対多に戻ってしまったので、忘れてしまいました。 ...

を休止状態の奇妙な働きを把握することができませんでした私は...いつかすべてのヘルプ:)要素のコレクションで立ち往生

+1

私はあなたがポイントを完全に失っているのではないかと心配しています。あなたは、Hibernateにあなたの人生をより簡単にしてもらうべきです。途中でそれと戦わないでください。正しいマッピングをすることは、それを達成するために長い道のりになります。上で説明したシナリオは非常に基本的なものです。利用可能な例がたくさんあります(私の答えにリンクを掲載しました)。あなたは実際にドキュメントを読んで、これを働かせて、それがうまく動作することを理解する必要があります。さもなければ、それは道のりでもっと難しくなるでしょう。 – ChssPly76

+0

はい、私はそれが非常に基本的なことを知っています。だから私はまだそれが壊れている理由を混同しています。この解決策を使用して、hibernateは型idを完全に奇妙なuser_idに一致させることによって型を検索しようとします。 上記の要素のコレクションを行い、クラスキャストエラーが発生しました。 Hibernateのマッピングを作成すると、人生は非常に困難になります。マッピングがあるたびに、オブジェクトにアクセスまたは取得する方法をフォローアップしません。他の場所を検索して掘り起こす必要があります。 – April

関連する問題