私は問題を抱えており、この問題を克服するためにあなたの助けが必要です。うまくいけば、このトレッドが同様の問題のリファレンスになるかもしれません…</ p>
私の最小化されたビジネスモデルには、ユーザーとタイトルがあります。タイトルは最初に作成する必要があり、多くのユーザーに割り当てることができます。ユーザーは同じタイトルを共有できます。したがって、@ ManyToMany関係を持つUserとTitleという2つのエンティティを作成し、Titleがこの関係を所有する必要があると判断しました。さらに、この例を実行するためのUnitTestがあります。
ユーザーエンティティ
public class User {
Long id;
String name;
Set<Title> titles = new HashSet<Title>();
@Id
@GeneratedValue
@Column(name = "id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/*============ Approach1 ============*/
// @ManyToMany(mappedBy = "users")
/*============ Approach2 ============*/
// @ManyToMany
/*============ Approach3 ============*/
@ManyToMany
@JoinTable( name = "tb_title_user",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "title_id"))
public Set<Title> getTitles() {
return titles;
}
public void setTitles(Set<Title> titles) {
this.titles = titles;
}
}
タイトルエンティティ
public class Title {
Long id;
String description;
Set<User> users = new HashSet<User>();
@Id
@GeneratedValue
@Column(name = "id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/*============ Approach1 & Approach2 & Approach3 ============*/
@ManyToMany
@JoinTable( name = "tb_title_user",
joinColumns = @JoinColumn(name = "title_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
単体テスト
public class UserTest {
@Autowired
private SessionFactory sessionFactory;
@Test
@Rollback(false)
@Transactional
public void saveUser(){
Session session = sessionFactory.getCurrentSession();
String now = new Date().toString();
Title title = new Title();
title.setDescription("TitleDescription: " + now);
session.save(title);
User user = new User();
user.setName("UserName: " + now);
user.getTitles().add(title);
session.saveOrUpdate(user);
}
}
上記のコードを見ると、3つの異なるアプローチがわかります。以下に、データがデータベーステーブルに正しく格納されているかどうかを説明します。
Title User JoinTable
Approach1 Yes Yes No
Approach2 Yes Yes Yes
Approach3 Yes Yes Yes
それぞれのアプローチに関する私の考えは次のとおりです。
アプローチ1
Hibernateのドキュメント(http://docs.jboss.org/hibernate/core/4.1/manual/en-US/html/ch07.html#d5e5537)によると、Approach1に従う必要があります。特に、ドキュメントには次のことが明示的に記載されているためです。
「前に見たように、反対側は物理マッピングを記述する必要はありません(してはいけません)。所有者側のプロパティ名を含む単純なmappedBy引数が2つをバインドします。」</ p>
正しく理解していれば、Userエンティティに@JoinTableを追加する必要はありません(してはいけません)。
アプローチ2
動作しますが、@ JoinTable定義を無視し、次のような独自のテーブルを作成しますtb_user_tb_title
。魚臭い匂いがします。
アプローチ3
動作しますが、ドキュメントには使用しないように記載されています。したがって、エンタープライズ製品でこのアプローチを使用したことを後悔しているように思われます。