私は3つのクラスを持っています。名前の1つはUserで、このユーザーには他のクラスインスタンスがあります。このような;
public class User{
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
public List<APost> aPosts;
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
public List<BPost> bPosts;
}
public class BPost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
public class APost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
このように動作しますが、dbにemtyテーブルを生成します。外部キーを含む必要があります。 mappedByとJoinColumn annotainsを使用しようとすると失敗しました。どうすれば解決できますか?
追加情報:
で変更したとき;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="id")
public User user;
そして
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="id")
public List<APost> aPosts;
私は得ています
JPAエラーが発生しました(EntityManagerFactoryを構築できません):エンティティのマッピングで繰り返される列:models.post.APost列:id(insert = "false" update = "false"でマッピングする必要があります)
最終編集:最後に、私はJPA注釈について全く間違っていました。 :(私が変わるとき
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="id")
に
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
そして
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="user_id")
エバーシングは大丈夫です。 :)
この記事 と私の本 High-Performance Java Persistence で説明したように、単方向の@OneToMany
アノテーションは使用しないでください。 :
さて、最初の例では、両方の側が関連付けを所有しており、 これは悪い です。
@JoinColumn
が@OneToMany
側にアソシエーションを担当させますが、それは間違いなく最良の選択ではありません。したがって、@OneToMany
側では常にmappedBy
属性を使用してください。
public class User{
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
public List<APost> aPosts;
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
public List<BPost> bPosts;
}
public class BPost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
public class APost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
あなたの質問(「空のテーブル」などの意味、またはmappedBy
とJoinColumn
がどのように機能しなかったのか)について私は本当に知りません。
双方向の関係を作ろうとしていたと思います。
最初に、どちらの側が関係を「所有する」かを決定する必要があります。 Hibernateは、その側に関係ベースをセットアップします。たとえば、Post
側にリレーションシップを所有させると仮定すると(例を単純化するために、物事を適切に保つために)、マッピングは次のようになります。
(構文が正しいことを望みます。私はメモリだけでそれらを書いています。しかし、アイデアはうまくいくはずです)
public class User{
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
private List<Post> posts;
}
public class Post {
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="user_id")
private User user;
}
これにより、Post
のテーブルには、関係を格納する列user_id
が含まれます。 Hibernateは、user
のPost
によって関係を取得しています(posts
のUser
の代わりに。Post
のuser
があるが、User
のposts
がない場合、違いに気付くでしょう)。
mappedBy
に言及しましたが、JoinColumn
は機能していません。しかし、これは実際には正しい方法だと思います。このアプローチがうまくいかない場合は教えてください。問題についてもう少し情報を提供してください。この問題は他の何かが原因だと思います。
編集:
mappedBy
の使用に関する少し余分な情報は、最初は通常混乱を招くためです。 mappedBy
では、テーブルの列名ではなく、双方向の関係の反対側に「プロパティ名」を配置します。