我打算用JPA实现一些树状结构。我有一个"文件夹"实体和一个"测试"实体。文件夹可以同时包含文件夹和测试。Test不包含任何内容
test和folder都有一个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;
...
}
所以主要的问题是mapappedby属性,它与父类属性有关,在祖先中没有被重写,因为我得到了这样的异常:
Exception while preparing the app : mappedBy reference an unknown target entity property: my.test.model.Folder.parent in my.test.model.Folder.folders
可能有一些棘手的映射文件夹类的"文件夹"one_answers"测试"属性,我需要一点帮助。
编辑:我指定文件夹和文件夹类的测试属性与targetEntity=Node.class:
@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;
它得到了功。但效果并不好。现在,当我需要分别获得它们时,测试和文件夹都映射到属性(我不知道为什么我没有得到异常)。
所以我仍然在寻找一个合适的映射来实现这一点。
有趣的结构,可能包含很多挑战。但是关于与超类实体属性的关系的问题:不幸的是,您不能在Hibernate中这样做。您设置targetEntityClass的方法也不起作用,因为它从实体映射的角度有效地更改了集合元素的类型。
幸运的是有解决方法。您可以从实体到您扩展的MappedSuperClass的属性建立关系。很可能您不想让Node成为MappedSuperClass,所以您必须添加new。然后它必须位于节点和文件夹之间:文件夹->MappedSuperClass->节点。它是这样的(这种方法至少适用于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
}
顺便说一下,Node对Parent来说是不是太通用了?至少如果它仅用于此目的。