我有一个具有某种复合模式的树状数据结构。对于抽象类Element,有一个CompositeElement和一个SingleElement。它看起来像这样:
@Entity
@DiscriminatorValue("Composite")
public class CompositeElement extends Element {
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinTable(name="Sub_Elements")
@MapKeyColumn(name="xxx")
protected Map<Integer, Element> subs;
...
}
到目前为止,这种关系是单向的。效果很好。但是现在出现了一个用例,我需要从子元素导航到父元素。所以我想做的是:
@Entity
@Inheritance
@DiscriminatorColumn("s_discriminator")
public class Element {
@ManyToOne(mappedBy="subs", fetch=FetchType.LAZY)
protected CompositeElement parent;
...
}
但是@ManyToOne注释不允许使用"mappedBy"属性。
从域视图来看,父对象拥有数据结构中的子对象。而不是反过来。急切获取和级联规则也强调了这一点。
如果关系的所有权在子端,那么child. setparent (p)将无法真正工作,因为这里我缺少映射的键。
是否有任何方法可以将关系的所有权保留在父方,但仍然使其双向?
看看如何将@JoinColumn
注释添加到您的@ManyToOne
和
@ManyToOne注释的javadocs
通常mappedby
会以另一种方式工作,其中@OneToMany将被@ManyToOne映射
看起来不可能像我想要的那样。
我改变了它,所以关系是属于孩子的。我在Element类中添加了一个属性"childIndex"。这个属性被@MapKey引用。
public class CompositeElement extends Element {
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="parent")
@MapKey(name="childIndex")
protected Map<Integer, Element> subs;
和
public abstract class Element {
protected Integer childIndex;
@ManyToOne(fetch=FetchType.LAZY)
protected CompositeElement parent;
解决方案有效,但我不喜欢它。我不喜欢子元素知道它的"childIndex"。当我对父对象中的子对象重新排序时,我需要修改每个子对象。我希望保留一个单独的数据库表来表示关系和索引列。
我想另一种选择是将关系建模为实体本身。