Embeddable和ElementCollection嵌套

时间:2014-03-02 10:24:16

标签: java hibernate jpa embeddable

我有一个相当典型的场景,其中有一个主要的@Entity,并且他内部的所有内容都是可嵌入的(所以内部的所有内容在没有父级的情况下都没有意义)。现在,JPA 2.0阻止我将@ElementCollection嵌套在另一个@ElementCollection中定义的@Embeddable中:

  

JSR-317   2.6可嵌入类和基本类型的集合   包含在元素集合中的可嵌入类(包括另一个可嵌入类中的可嵌入类)不得包含元素集合,也不能包含与多对一或一对一以外的实体的关系。关系

现在问题是:这是为什么?一个简单的例子:

@Entity
public class Tournament {
    @Id
    Long id;

    @ElementCollection
    @CollectionTable
    private List<Edition>;
}

@Embeddable
public class Edition {

    @ElementCollection
    @CollectionTable
    private List<Round>
}

@Embeddable
public class Round {

    blabla;
}

这有什么问题?这只是一个例子,您可以将Round和Edition定义为Entity并解决问题,但在我的情况下,出于多种原因我需要强制执行非嵌套的东西没有他父母的意义。

为什么JPA 2.0必须阻止我这样做?

1 个答案:

答案 0 :(得分:11)

您的情况违反了您粘贴的规范元素:

版本本身是@Embeddable,包含Round的元素集合,因此:

元素集合(Tournament.editions)中包含的可嵌入类(Edition)不得包含元素集合(Edition.rounds)。

至于为什么你不能这样做 - 如果你看一下来自http://en.wikibooks.org/wiki/Java_Persistence/ElementCollection的例子,那么你会看到孩子(版)将只用FK映射回给所有者(锦标赛。 id)没有自己的ID列 - 理由是作为弱实体,它没有自己的ID,只能通过参考锦标赛的ID来定义。

采取回合,如果它也是一个弱实体,那么它应该由FK参考版本定义 - 但是我们已经说过它没有自己的ID,所以你不能在数据库中映射它在版本中添加一个ID - 此时它本身就是一个实体,而不仅仅是@Embeddable。

从下面的评论中看维基百科的例子 - http://en.wikipedia.org/wiki/Weak_entity - 弱实体的例子有OrderNumber,CustomerNumber等 - 这些东西在嵌入另一个对象时才有意义。

您仍然可以拥有包含父映射的实体(即版本上的锦标赛参考)和/或双向引用。您可以强制在版本上使用@ManyToOne注释上的nullable = false属性定义父级,从而强制执行模型的要求。