双方向関連
3916 ワード
@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="passport_fk")
public Passport getPassport() {
...
}
@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
...
}
双方向関連には、一端のみが本体(owner)端として存在する、本体端が連結列(すなわち外部キーFK)の維持を担当する.このような関係を維持する必要のないスレーブテーブルについてはmappedBy属性で宣言する.mappedByの値は本体の関連属性を指す.上記の例ではmappedByの値はpassportである.最後に、ホスト側で宣言するため、関連付けられた側(owned side)で結合列を定義する必要はない.本体に@JoinColumuが宣言されていない場合、システムは自動的に処理を行う:本体の関連属性名+下線+被関連端の主キー列名がメインテーブル(owner table)に作成される.上記の例ではpassport_idは、Customerの関連属性名がpassportであるため、passportのプライマリキーはidである.
注意:
双方向の関連関係がある限り、mppedByを設定する必要があります.
ManyToOne関係のデフォルトのfetchはFetchTypeである.EAGER
OneToMany関係のデフォルトのfetchはFetchTypeである.LAZY
データベース内のツリー構造、オブジェクトの表現形式.
@Entity
public class TreeObject {
private int id;
private String name;
private TreeObject parent;
private List<TreeObject> children = new ArrayList<TreeObject>();
@Id
@GeneratedValue
public int getId() {
return id;
}
@ManyToOne
@JoinColumn(name="parent_id")
public TreeObject getParent() {
return parent;
}
@OneToMany(cascade=CascadeType.ALL,mappedBy="parent")
@OrderBy("name ASC")
public List<TreeObject> getChildren() {
return children;
}
....................
生成されたテーブル構造:
create table TreeObject (
id integer not null auto_increment,
name varchar(255),
parent_id integer,
primary key (id)
)
alter table TreeObject
add index FK95A4309DA50A61ED (parent_id),
add constraint FK95A4309DA50A61ED
foreign key (parent_id)
references TreeObject (id)
ManyToOneとOneToManyの双方向関係において、OneToMany側にmappedByを設けることは、本体側がMany側であることを示し、関係の主導はOne側のgetChildren集合におけるTreeObjectのparentオブジェクトが関係維持を担当することである、すなわち、以下の方法でこれらの関係を保存することができる.
@Test
public void testSaveTreeObject() {
TreeObject o = new TreeObject();
o.setName(" ");
TreeObject o1 = new TreeObject();
o1.setName(" 1");
TreeObject o2 = new TreeObject();
o2.setName(" 2");
o1.setParent(o);
o2.setParent(o);
Session s = sessionFactory.openSession();
s.beginTransaction();
s.save(o);
s.save(o1);
s.save(o2);
s.getTransaction().commit();
s.close();
}
@OneToMany(cascade=CascadeType.ALL,mappedBy="parent")、CascadeType.ALLがparentオブジェクトを保存するとchildrenもそれに従って保存する.
@Test
public void testSaveTreeObject() {
TreeObject parent = new TreeObject();
parent.setName(" ");
TreeObject child1 = new TreeObject();
child1.setName(" 1");
TreeObject child2 = new TreeObject();
child2.setName(" 2");
child1.setParent(parent);
child2.setParent(parent);
parent.getChildren().add(child1);
parent.getChildren().add(child2);
Session s = sessionFactory.openSession();
s.beginTransaction();
s.save(parent);
s.getTransaction().commit();
s.close();
}
データベース・テーブルには、次の3つのレコードが生成されます.
id name parent_id
1本社null
2支社1
3支社2 1