我在绘制以下内容时遇到了一些麻烦:
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
}
所以基本上一个Operation有一堆Items,一个Item属于2个Operations。 此外,如果其中一个操作不存在,则项目存在没有意义,即,如果我删除其中一个操作,我想从其存储的任何地方删除该项目。
有没有人指出我如何映射上面的类,或者可以指出一些示例来说明如何映射具有2个父项的子对象?
答案 0 :(得分:2)
从面向对象的角度来看,所表示的内容与ManyToOne
和Item
之间的两个 Operation
关联相似,一个他们是双向的。这可以像这样映射:
@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]
表有两个指向[OPERATION]
的FK。填充items
集合会导致SELECT
仅限于其中一个(上例中的ID
启动操作。)
我不知道这种情况是否有意义,但这是IMO Hibernate可以处理的唯一场景。如果这不是您想要的,那么我认为您应该在Operation
方面有两个集合(您可以隐藏在友好方法之后)。
无论使用hbm.xml还是注释都没有任何区别。
答案 1 :(得分:1)
这听起来像是项目和操作之间多对多关系的组合,以及一个项目和两个操作之间的三元关系。
假设您的业务逻辑仅针对每个项目的两个操作进行修复,而不是更多,我将按如下方式解决此问题:
正如你所说,棘手的部分是你删除一个操作。无论您是否使用中间对象,都需要使用all-delete-orphan将删除级联到列表中。但是,我怀疑你会因为二级缓存而遇到一些问题。我知道的唯一方法就是:
op1
之前,遍历对象图并将每个中间对象与其他操作op2
分离,然后才刷新。否则,hibernate将拒绝删除中间对象,因为它们仍保留在其他操作中的某些集合中。