August 18, 2005
Hibernate の composite-element を使うときは equals() と hashCode() をオーバーライドする
という必要があるのに気づくまで、ちょっとハマったのでメモ。
Hibernate でコンポーネントのコレクションへのマッピングをするとき、つまりあるクラスのメンバに Set などのコレクションがあって、その中身が特定の値型のとき、composite-element を使います。そのとき、コレクションの中身になるクラスでは equals() と hashCode() をオーバーライドしないといけない、という話。
クラスが、
public class Group { private Integer id; private String groupName; private Set members = new HashSet(); // 中身は Person .... } public class Person { private String name; private Integer age; .... }
みたいなとき、マッピングファイルは、
<hibernate-mapping> <class name="Group" table="group"> <id name="id"> <generator class="identity"/> </id> <property name="groupName" column="group_name"/> <set name="members" table="members"> <key column="id"/> <composite-element class="Person"> <property name="name"/> <property name="age"/> </composite-element> </set> </class> </hibernate-mapping>
てな感じになるわけですが、ここで、Person に equals() と hashCode() を実装しておかないとですね、例えば Group に member を追加するときに、members テーブルに対して大量に insert と delete を発行してしまったり、わけわかんないことになります。まあよく考えてみれば確かにそうなるかも、というところですが、ドキュメントにも、
Note: if you define a Set of composite elements, it is very important to implement equals() and hashCode() correctly.
とか書いてあるので、注意が必要です。バッチリ見落としてましたよ。よく参考にしてるHibernate 入門記のエントリでも、
こいつは値型なので本来は hashCode() と equals(Object) をオーバーライドすべきですが,手抜きしてます.心より恥じる.とあったのですが、これも見落としてました。いかんいかん。
投稿者 ryoji : August 18, 2005 10:47 AM
トラックバック
このエントリーのトラックバックURL:
http://ryoji.sakura.ne.jp/mt/mt-tb.cgi/148