回答:
編集2017-04-29:一部のコメンターが指摘しているように、このJoinTable
例ではmappedBy
注釈属性は必要ありません。実際、Hibernateの最近のバージョンでは、次のエラーを出力して起動を拒否しています。
org.hibernate.AnnotationException:
Associations marked as mappedBy must not define database mappings
like @JoinTable or @JoinColumn
名前の付いたエンティティと名前の付いたProject
別のエンティティがTask
あり、各プロジェクトが多くのタスクを持つことができるとしましょう。
このシナリオのデータベーススキーマは、2つの方法で設計できます。
最初の解決策は、というテーブルとという名前のProject
別のテーブルを作成し、という名前Task
のタスクテーブルに外部キー列を追加することproject_id
です。
Project Task
------- ----
id id
name name
project_id
このようにして、タスクテーブルの各行のプロジェクトを決定することができます。このアプローチを使用する場合、エンティティクラスでは結合テーブルは必要ありません。
@Entity
public class Project {
@OneToMany(mappedBy = "project")
private Collection<Task> tasks;
}
@Entity
public class Task {
@ManyToOne
private Project project;
}
もう1つの解決策は、3番目のテーブル(例:)を使用して、Project_Tasks
プロジェクトとタスク間の関係をそのテーブルに格納することです。
Project Task Project_Tasks
------- ---- -------------
id id project_id
name name task_id
Project_Tasks
表には、「結合テーブル」と呼ばれています。この2番目のソリューションをJPAに実装するには、@JoinTable
アノテーションを使用する必要があります。たとえば、単方向の1対多の関連付けを実装するために、エンティティを次のように定義できます。
Project
エンティティ:
@Entity
public class Project {
@Id
@GeneratedValue
private Long pid;
private String name;
@JoinTable
@OneToMany
private List<Task> tasks;
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Task> getTasks() {
return tasks;
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
}
}
Task
エンティティ:
@Entity
public class Task {
@Id
@GeneratedValue
private Long tid;
private String name;
public Long getTid() {
return tid;
}
public void setTid(Long tid) {
this.tid = tid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
これにより、次のデータベース構造が作成されます。
@JoinTable
注釈はまた、あなたが参加するテーブルのさまざまな側面をカスタマイズすることができます。たとえば、次のtasks
ようにプロパティに注釈を付けたとします。
@JoinTable(
name = "MY_JT",
joinColumns = @JoinColumn(
name = "PROJ_ID",
referencedColumnName = "PID"
),
inverseJoinColumns = @JoinColumn(
name = "TASK_ID",
referencedColumnName = "TID"
)
)
@OneToMany
private List<Task> tasks;
結果のデータベースは次のようになります。
最後に、多対多の関連付けのスキーマを作成する場合は、結合テーブルの使用が唯一の利用可能なソリューションです。
@JoinTable/@JoinColumn
同じフィールドに注釈を付けることができると思いますmappedBy
。したがって、正しい例は、mappedBy
inを維持しProject
、@JoinColumn
toをTask.project
(またはその逆)に移動することです
Project_Tasks
必要とname
のTask
3つの列となる、だけでなく、: 、project_id
、task_id
、task_name
どのようにこれを達成するには?
Caused by: org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn:
これは、ManyToMany関連付けをマップする唯一のソリューションです。関連付けをマップするには、2つのエンティティテーブル間に結合テーブルが必要です。
多面のテーブルに外部キーを追加したくない場合、OneToMany(通常は単方向)アソシエーションにも使用され、片面から独立させます。
説明と例については、Hibernateドキュメントで@JoinTableを検索してください。
多対多の関係を処理できます。例:
Table 1: post
post has following columns
____________________
| ID | DATE |
|_________|_________|
| | |
|_________|_________|
Table 2: user
user has the following columns:
____________________
| ID |NAME |
|_________|_________|
| | |
|_________|_________|
テーブルの結合では、次を使用してマッピングを作成できます。
@JoinTable(
name="USER_POST",
joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="ID"),
inverseJoinColumns=@JoinColumn(name="POST_ID", referencedColumnName="ID"))
テーブルを作成します:
____________________
| USER_ID| POST_ID |
|_________|_________|
| | |
|_________|_________|
@ManyToMany
協会ほとんどの場合、@JoinTable
アノテーションを使用して、多対多のテーブルリレーションシップのマッピングを指定する必要があります。
したがって、次のデータベーステーブルがあるとします。
ではPost
エンティティ、あなたはこのように、この関係をマップになります。
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(
name = "post_tag",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id")
)
private List<Tag> tags = new ArrayList<>();
@JoinTable
注釈は、経由して、テーブル名を指定するために使用されてname
参照する属性だけでなく、外部キー列post
テーブル(例えば、joinColumns
)との外部キー列post_tag
のリンクテーブル参照することTag
を通じて実体をinverseJoinColumns
属性。
カスケード属性ということに注意してください
@ManyToMany
注釈に設定するPERSIST
と、MERGE
カスケードが理由だけでREMOVE
、我々はDELETE文は、他の親レコードのために発行されますので、悪い考えであるtag
私たちの場合は、しないようにpost_tag
記録します。このトピックの詳細については、こちらの記事をご覧ください。
@OneToMany
関連付けマッピングの@OneToMany
ない単方向の関連付け@JoinColumn
は、1対多ではなく、多対多のテーブルリレーションシップのように動作します。
したがって、次のエンティティマッピングがあると仮定します。
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
//Constructors, getters and setters removed for brevity
}
@Entity(name = "PostComment")
@Table(name = "post_comment")
public class PostComment {
@Id
@GeneratedValue
private Long id;
private String review;
//Constructors, getters and setters removed for brevity
}
Hibernateは、上記のエンティティマッピングに対して次のデータベーススキーマを想定しています。
すでに説明したように、単方向@OneToMany
JPAマッピングは多対多の関連付けのように動作します。
リンクテーブルをカスタマイズするには、@JoinTable
アノテーションを使用することもできます。
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
@JoinTable(
name = "post_comment_ref",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "post_comment_id")
)
private List<PostComment> comments = new ArrayList<>();
これで、リンクテーブルが呼び出さpost_comment_ref
れ、外部キー列はpost_id
、post
テーブルの場合は、テーブルの場合post_comment_id
はになりpost_comment
ます。
単方向の
@OneToMany
関連付けは効率的ではないため、双方向の@OneToMany
関連付けまたは@ManyToOne
サイドのみを使用するほうがよいでしょう。チェックアウトこの記事をこのトピックの詳細については。