在使用JPA (Hiberante provider)映射自定义集合时,我遇到了问题。例如,当我使用带有属性的对象时
List<Match> matches;
使用
<one-to-many name="matches">
<cascade>
<cascade-all />
</cascade>
</one-to-many>
在我的ORM文件中,它是可以的;但是如果我将"List matches;“替换为
private Matches matches;
,其中“匹配”的定义如下:
public class Matches extends ArrayList<Match> {
private static final long serialVersionUID = 1L;
}
它会产生以下错误:
Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: by.sokol.labs.jpa.MatchBox.matches
感谢您的关注!
发布于 2010-07-04 10:44:13
您可以,但您必须将其称为公共集合之一- List
或Set
。
因此:
private List matches = new Matches();
为什么?例如,Hibernate对集合进行代理以启用延迟加载。因此,它创建了PersistentList
、PersistentSet
和PersistentBag
,它们是List
,但不是Matches
。因此,如果您想要向该集合添加其他方法,那么您不能。
检查这篇文章为您提供更多细节。
不过,你有个解决办法。不要使用继承,要使用组合。例如,您可以向实体添加一个名为getMatchesCollection()
的方法(除了传统的getter),如下所示:
public Matches getMatchesCollection() {
return new Matches(matches);
}
您的Matches
类看起来类似于(使用google-集合‘ForwardingList
):
public class Matches extends ForwardingList {
private List<Match> matches;
public Matches(List<Match> matches) { this.matches = matches; }
public List<Match> delegate() { return matches; }
// define your additional methods
}
如果不能使用google集合,只需自己定义ForwardingList
--它调用底层List
的所有方法
如果不需要任何额外的方法来对结构进行操作,那么就不要定义自定义集合。
发布于 2010-07-04 10:56:58
Hibernate要求将持久化的集合值字段声明为接口类型(因为出于延迟加载的目的,它们将被Hibernate的实现所取代)。参考文件中:
6.1。持久化集合 Hibernate要求将持久化集合值字段声明为接口类型。例如: 公共类产品{私有字符串serialNumber;私有集部件=新的HashSet();公共集getParts() {返回部分;}getParts(集合部分){ this.parts = parts;}公共字符串getSerialNumber() {返回serialNumber;} setSerialNumber(String sn) { serialNumber = sn;}} 实际的接口可能是
java.util.Set
、java.util.Collection
、java.util.List
、java.util.Map
、java.util.SortedSet
、java.util.SortedMap
或您喜欢的任何东西(“任何您喜欢的”意味着您必须编写org.hibernate.usertype.UserCollectionType
的实现)。 注意实例变量是如何使用HashSet
实例初始化的。这是初始化新实例化(非持久性)实例的集合值属性的最佳方法。当您使实例持久时,例如通过调用persist()
,Hibernate实际上将用Hibernate自己的Set
实现的实例来替换HashSet
。
所以你的第二种方法是不可能的,至少不像你声明的那样。但老实说,我不太明白重点。
https://stackoverflow.com/questions/3174379
复制相似问题