10

私には2つのクラスがあります。1:1の関係にあるUserとUserPictureです。

public class User {
     @Id
     @GeneratedValue(strategy=GenerationType.AUTO)
     @Column(name="id", nullable = false, unique = true)
 private int id;

     private String firstname;

     private String lastname;

     @OneToOne
     @JoinColumn(name = "picture") //field named "picture" in the database
     private UserPicture userPicture;

     ..
}


public class UserPicture {

     @Id
     @GeneratedValue(strategy=GenerationType.AUTO)
     @Column(name="id", nullable = false, unique = true)
     private int id;

     private Blob image;

     @OneToOne
     @JoinColumn(name = "user")
     User user;

UserPictureの「user」はロードされますが、Userの「userPicture」はロードされません-Imは何が間違っていましたか?

編集 ImはUserPictureを作成し、それらを(既存のuserIdで)挿入するだけであるということを追加する必要があります-多分私はUserPictureで'user'をカスケードする必要がありますか?

4

3 に答える 3

19

クラスをマッピングする必要があります。

public class User {
    ...
    @OneToOne (mappedBy="user")
    private UserPicture userPicture;
    ...
}

public class UserPicture {
    ...
    @OneToOne
    @JoinColumn (name="user")
    private User user;
    ...
}
于 2012-10-24T08:06:51.507 に答える
5

あなたの質問に関して:(コメントで答えるのに十分な評判がないので)

「すべて明確です。あと1つだけ質問がありますが、userPictureをユーザーの怠惰にすることは可能ですか?–user17312992012年10月24日10:44」

はい、レイジーフェッチにすることは可能です。ただし、「fetchType=FetchType.Lazy」とだけ言っても機能しません。理由は、Hibernateは結合されたテーブルをチェックして、それがnull値であるかどうか、またはそこにレコードがあるかどうかを確認する必要があります。これはOneToOneマッピングであるため、Hibernateは、データがnullであるかどうかをチェックする必要があるため、そこにあるデータをプルバックするだけでデータベース呼び出しを節約できると考えています。これはx-to-manyマッピングには当てはまりません。Hibernateは「many」が他のテーブルで待機しているリストがあることを意味することを知っているためです...空のリストでも入力済みのリストでも、それはリストのままです。単一の値の場合、実際のデータとnull値を区別する必要があります。

これを回避する方法は、Hibernateに常に値が存在し、null値は決して存在しないことを通知することです。これを知っていると、Hibernateはそのデータをフェッチする時までプレースホルダーを作成できます。アノテーションでこれを行う方法は、@OneToOneアノテーションに「optional=false」を追加することです。

ただし、注意してください。これにはいくつかの問題があります。私が今理解しようとしているもの(そして私がここであなたの質問に出くわした方法)を含みます。このoptional=falseは、Hibernateに少し余分な検証を行わせ、挿入の実行方法についてHibernateを混乱させるようです。したがって、この遅延フェッチ手法には近づかないようにすることをお勧めします。

于 2013-08-06T17:56:15.617 に答える
2

JoinColumnアノテーションでフィールドをnull不可として指定した場合でも、OnetoOneでの遅延読み込みは機能します。ただし、双方向の1対1では、mappedBy=''を使用するエンティティでは遅延読み込みは機能しません。たとえば、ContractとHouseの2つのエンティティがあり、ContractテーブルがHouseへの外部キーを保持している場合です。ここで双方向OneToOneを使用してコントラクトをロードしようとすると、遅延ロードが機能します(つまり、Houseが熱心にロードされません)が、Houseをロードしようとすると(Houseリポジトリを使用して)、コントラクトは常に熱心にフェッチされます。なぜこれが起こるのか誰かが知っていますか?

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

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

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

于 2016-07-25T23:28:52.817 に答える