与JPA中的超类实体属性的双向关系

时间:2011-10-03 10:27:26

标签: hibernate inheritance jpa hibernate-mapping bidirectional-relation

我想用JPA实现一些树状结构。 我有一个“文件夹”实体和一个“测试”实体。文件夹可以包含文件夹和测试。测试不包含任何内容。

test和文件夹都有一个Node超类,如下所示:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Node implements TreeNode, Serializable{

    private Long id;    
    String description;    
    String name;

    @ManyToOne 
    Node parent;

    ...getters, setters and other stuff that doesnt matter...
}

这是Folder类:

@Entity
public class Folder extends Node{

    @LazyCollection(LazyCollectionOption.FALSE) 
    @OneToMany(cascade=CascadeType.ALL, **mappedBy="parent"**)
    List<Folder> folders;

    @LazyCollection(LazyCollectionOption.FALSE) 
    @OneToMany(cascade=CascadeType.ALL, **mappedBy="parent"**)
    List<Test> tests;

    ...
}   

所以主要的问题是mappedBy属性,它与祖先中未覆盖的超类属性有关,因为我得到了这样的异常:

Exception while preparing the app : mappedBy reference an unknown target entity property: my.test.model.Folder.parent in my.test.model.Folder.folders

对于Folder类的“文件夹”和“测试”属性,可能会有一些棘手的映射,我需要一些帮助。

编辑:我使用targetEntity = Node.class指定了Folder类的文件夹和测试属性:

    @LazyCollection(LazyCollectionOption.FALSE) 
    @OneToMany(cascade=CascadeType.ALL, mappedBy="parent",targetEntity=Node.class)
    List<Folder> folders;

    @LazyCollection(LazyCollectionOption.FALSE) 
    @OneToMany(cascade=CascadeType.ALL, mappedBy="parent",targetEntity=Node.class)
    List<Test> tests;

它开始工作了。但工作不顺利。现在,当我需要单独获取它们时,测试和文件夹都映射到两个属性(我不知道为什么我不会出现异常)。

所以我仍然在寻找合适的映射来实现这一目标。我会赞美任何帮助。

1 个答案:

答案 0 :(得分:0)

有趣的结构,可能包含许多挑战。但是关于与超类实体属性的关系的问题:遗憾的是你不能用Hibernate做到这一点。您设置targetEntityClass的方法也不起作用,因为它从实体映射的角度有效地更改了集合元素的类型。

幸运的是有解决方法。您可以拥有从实体到MappedSuperClass属性的关系,您可以将其扩展。可能你不想让Node成为MappedSuperClass,所以你必须添加新的。然后它必须位于节点和文件夹之间:Folder-&gt; MappedSuperClass-&gt;节点。它是这样的(这种方法至少适用于Hibernate 3.5.6,不知道它支持哪个版本):

public class Node {
      ... //without parent attribute, otherwise as before
}

@MappedSuperclass
public class SomethingWithParent extends Node {
    @ManyToOne
    Node parent;
}
public class Folder extends SomethingWithParent {
..
//as before
}

public class Test extends SomethingWithParent {
...//as before
}

顺便说一下,对于Parent,Node bit是不是太通用了?至少如果它仅用于此目的。所有的父母都是文件夹。