双方向関連

3916 ワード

  • One-To-One  

  •     
    @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