"one" 方拥有的 jpa 地图

jpa map owned by the "one" side

我有一个具有某种复合模式的树状数据结构。有了一个抽象的 class 元素,就有了一个 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;

  ...
}

到目前为止,关系是单向的。它运作良好。但是现在弹出一个用例,我需要从子元素导航到 parent 元素。所以我想做的是:

@Entity
@Inheritance
@DiscriminatorColumn("s_discriminator")
public class Element {

  @ManyToOne(mappedBy="subs", fetch=FetchType.LAZY)
  protected CompositeElement parent;
  ...
}

但是@ManyToOne 注解不允许 "mappedBy" 属性。

从域的角度来看,parent 拥有数据结构中的 children objects。不是相反。 eager fetch和级联规则也强调了这一点。

如果关系的所有权在 child 一方,那么 child.setParent(p) 将无法正常工作,因为我在这里缺少地图的密钥。

有什么方法可以在 parent 一侧保留关系的所有权,但仍使其成为双向的?

看看为您的 @ManyToOne
添加 @JoinColumn 注释 javadocs for the @ManyToOne 注释。

通常 mappedby 会以另一种方式工作,其中 @OneToMany 会被 @ManyToOne

映射

看来这不可能是我想要的方式。

我更改了它,因此关系归 child 所有。并且我在元素class中添加了一个属性"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;

该解决方案有效,但我不喜欢它。我不喜欢 child 元素知道它的 "childIndex"。当我re-orderchildren在parentobject时,我需要修改每个children。我很想保留一个单独的数据库 table 来表示关系和索引列。

我想另一种选择是将关系建模为实体本身。