[Hibernate]1対1関連のマッピング
ユーザとその住所のように、実際は1対1の関連にある場合でも、ER図上では多対1関連で表現することとなる。
この状態でHibernateのリバースエンジニアリングをかけると、ユーザから住所はmany-to-one、住所からユーザはone-to-manyの関連でhbmが生成される。
この時、住所からユーザを取得するのにコレクションの操作をするのは面倒である。
このような場合には、one-to-one関連が利用できる。
User.hbm
<many-to-one name="home_address_id" class="hoge.Address" cascade="all" > <column name="home_address_id" unique="true" /> </many-to-one>
Address.hbm
・修正前
<set name="users" table="user" inverse="true" > <key> <column name="home_address_id" /> </key> <one-to-many class="hoge.User" /> </set>
・修正後
<one-to-one name="user" class="hoge.User" property-ref="homeAddress" />
上記のように、one-to-oneタグを利用し、property-refでどのフィールドで紐付くかを指定することで、一対一の関係を表現できる。
また、User.hbmでhome_address_idのunique属性をtrueとしているが、これはリバースエンジニアリング時にのみ影響するものであり、エンティティの保存時はユニークかどうかのチェックは行われない。
そのためDB上でhome_address_idにunique制約が存在しなければ、one-to-one関連を指定している場合であっても、同一のAddressエンティティを複数のユーザに割り当てることが可能となる。
この場合、保存は成功するが、Addressの読み込み時に紐付くUserが特定できないため、下記の例外が発生する。
Exception in thread "main" org.hibernate.HibernateException: More than one row with the given identifier was found: 1, for class: hoge.UserOnetoone