2012-10-24 22 views
8

私は2つのクラスを持っています:1:1の関係を持つUserとUserPicture。Hibernate - 双方向@OneToOne

UserPictureの 'user'はロードされますが、UserPictureはUserではありません - 何が間違っていましたか?

EDITは はイムだけでUserPictureを作成し、(既存のユーザーIDで)それらを挿入することを追加する必要があります - 多分私はUserPictureの「ユーザー」をカスケード接続する必要がありますか?

答えて

14

クラスをマップする必要があります。

あなたの質問に関しては
public class User { 
    ... 
    @OneToOne (mappedBy="user") 
    private UserPicture userPicture; 
    ... 
} 

public class UserPicture { 
    ... 
    @OneToOne 
    @JoinColumn (name="user") 
    private User user; 
    ... 
} 
+0

ありがとう!しかし、私はUserPictureを挿入した場合ユーザーは更新されません? – user1731299

+0

@ user1731299 'User'を' UserPicture'に関連付けるためにあなたがしなければならないことは、 'UserPicture'を作成し、そのオブジェクトに対して' setUser'を呼び出してDBに保存することです。 – Pigueiras

+0

以下:フロントエンドはユーザーAにユーザー画像を追加するように要求します。私のサービスでは、ユーザーAをリロードし、このユーザーを新しいUserPictureオブジェクトに設定し、userPicture - >フィールド 'picture'を作成します。私がユーザーをロードしている場合、フィールドの画像は本当に奇妙に読み込まれます。 – user1731299

2

:(私はコメントに対応するための十分な評判を持っていないので)

「オールクリアつだけ質問より、ユーザー怠惰でuserPictureを作ることが可能です! ? - user1731299 Oct 24 '12 at 10:44 "

はい、レイジーフェッチすることは可能です。しかし、単に "fetchType = FetchType.Lazy"と言っても動作しません。なぜなら、Hibernateは結合されたテーブルをチェックして、それがヌル値であるか、そこにレコードがあるかどうかを調べる必要があります。 OneToOneマッピングであるため、Hibernateは、それがヌルであったかどうかをチェックしなければならなかったので、そこにあるデータを取り戻すだけでデータベース呼び出しを保存できると判断します。これは、x-to-many-mappingsの場合ではありません。なぜなら、Hibernateは、 'many'は他のテーブルを待っているリストがあることを知っているからです。空のリストであっても、それはまだリストです。単一の値の場合、実際のデータとヌル値を区別する必要があります。

これを回避する方法は、常にそこに値があり、決してヌル値であることをHibernateに伝えることです。これを知ることで、Hibernateはそのデータを取得する時までプレースホルダを作成できます。アノテーションでこれを行う方法は、@ optionalToアノテーションに "optional = false"を追加することです。

ただし、注意してください!これにはいくつか問題があります。私が今理解しようとしているものを含めて(そして私があなたの質問をここでどうやって見つけたのか)。このオプションがfalseの場合、Hibernateは少し検証を行い、Hibernateは挿入をどのように実行すべきかを混乱させるようです。だから、この怠惰なフェッチテクニックから離れることをお勧めします。

1

JoinColumnアノテーションでフィールドをnullでないとして指定しても、1対1の遅延ロードは機能します。しかし、双方向の一対一の場合、私たちがmappedBy = ''を使用するエンティティでは、遅延ロードは機能しません。たとえば、契約テーブルとハウスの2つのエンティティがある場合、契約テーブルには外部キーが格納されます。ここで双方向のOneToOneを使用して契約をロードしようとすると、レイジーローディングが動作します(つまりHouseは熱心に読み込まれません)が、Houseをロードしようとすると(Houseリポジトリを使用)、Contractは常に熱心に取り出されます。なぜ誰が考えているのですか?

Public class Contract { 
    ..... 
    @onetoone(lazy) 
    @JoinColumn(name='houseid', nullable=false) 
    Private House house 
    ..... 
} 

Public class House { 
    ..... 
    @onetoone(lazy, mappedBy='house') 
    Private Contract contract 
    ..... 
} 

私はこれが部分的な答えであることを知っています。しかし、それはここでの議論に非常に関連しています。

関連する問題