2010-08-22 81 views
4

我有一點麻煩映射下映射對象:休眠屬於其他兩個對象(含2個父母對象)

public class Operation { 
    private Integer id; 
    private String name; 
    private List<Item> items = new ArrayList<Item>(); 
    //set/getters/hashcode/etc. omitted 

    public void addItem(Item i,Operation end) { 
    i.setOperationStart(this); 
    i.setOperationEnd(end}; 
    items.add(i); 
    end.getItems().add(i); 
    } 

public class Item { 
    private Integer id; 
    private String name; 
    private Operation operationStart; 
    private Operation operationEnd; 
    //set/getters/hashcode/etc. omitted 
} 

所以基本上的操作有一堆物品,以及項目屬於2個操作。 另外,如果其中一個操作不存在,那麼它就沒有意義了,即如果我刪除了其中一個操作,我想從其它存儲的任何其他位置刪除該項目。

有沒有人有指示我如何映射上述類,或者可以指向我的一些示例,顯示如何映射有2個父母的子對象?

回答

2

從什麼被表示的視圖中的面向對象的點看起來像ItemOperation之間 ManyToOne協會,他們都是雙向的一個。這可以這樣映射:

@Entity 
public class Item { 
    @Id private Integer id; 
    private String name; 
    @ManyToOne 
    private Operation operationStart; 
    @ManyToOne 
    private Operation operationEnd; 

    //set/getters/hashcode/etc. omitted 
} 

@Entity 
public class Operation { 
    @Id private Integer id; 
    private String name; 

    @OneToMany(cascade = CascadeType.REMOVE, mappedBy="operationStart") 
    private List<Item> items = new ArrayList<Item>(); 

    //set/getters/hashcode/etc. omitted 
} 

這將導致一個[ITEM]表有兩個FKS指着[OPERATION]。並且填充items集合將導致SELECT僅限於其中一個(上例中的開始操作的ID)。

我不知道這個場景是否有意義,但這是IMO Hibernate可以處理的唯一場景。如果這不是你想要的,那麼我認爲你應該在Operation方有兩個集合(你可以隱藏在友好方法後面)。

無論你使用hbm.xml還是註釋都沒有什麼區別。

1

這聽起來像是項目和操作之間的多對多關係以及一個項目和兩個操作之間的三元關係的組合。

  • 如果你想要一個乾淨的對象模型,然後創建一個:

    假設你的業務邏輯每個項目正好兩個操作,並沒有比這更固定,如下所示我想解決這個問題中間對象來保存兩個操作的引用,並且它應該將一個項目作爲組件保存。

  • 映射hbm中的項目。基本上,每個操作應該有一箇中間對象的列表,並且每個中間對象都有一個Item。刪除中間對象時,將刪除級聯到該項目,而不是操作。

如你所說,棘手的部分是當你刪除一個操作。無論您是否使用中間對象,您都需要使用all-delete-orphan將刪除級聯到列表中。但是,我懷疑由於第二級緩存會導致一些問題。我知道周圍的唯一途徑是這樣的:

  • 刪除操作之前op1,遍歷對象圖,並從其其他操作op2分離的每個中間對象,才把齊平。否則,hibernate將拒絕刪除中間對象,因爲它們仍然保存在其他操作中的某些集合中。