如何在JPA中映射自定义集合?
我在使用 JPA(Hiberante 提供程序)映射自定义集合时遇到问题。例如,当我
List<Match> matches;
使用带有
<one-to-many name="matches">
<cascade>
<cascade-all />
</cascade>
</one-to-many>
在 ORM 文件中 属性的对象时,这是可以的;但是,如果我将 "List matches;" 替换为
private Matches 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
感谢您的关注!
I have problems in mapping custom collection with JPA (Hiberante provider). For example when I am using object with attribute
List<Match> matches;
with
<one-to-many name="matches">
<cascade>
<cascade-all />
</cascade>
</one-to-many>
in my ORM file, it is allright; But if I replace "List matches;" by
private Matches matches;
,where "Matches" is defined like:
public class Matches extends ArrayList<Match> {
private static final long serialVersionUID = 1L;
}
It produces following error:
Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: by.sokol.labs.jpa.MatchBox.matches
Thanks for your attention!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
可以,但必须将其作为常见集合之一进行引用 -
List
或Set
。所以:
为什么?例如,因为 Hibernate 为您的集合创建代理以启用延迟加载。因此它创建了
PersistentList
、PersistentSet
和PersistentBag
,它们是List
但不是Matches.因此,如果您想向该集合添加其他方法 - 嗯,您不能。
查看这篇文章了解更多详细信息。
不过,你有一个解决方案。不要使用继承,而使用组合。例如,您可以向实体添加一个名为
getMatchesCollection()
的方法(除了传统的 getter 之外),该方法如下所示:您的
Matches
类将如下所示(使用 google-collections'ForwardingList
):如果您不能使用 google 集合,只需自己定义
ForwardingList
- 它会调用底层List
的所有方法,如果您不需要任何其他方法来操作结构,然后不要定义自定义集合。
You can, but you have to refer to it as one of the common collections -
List
orSet
.so:
Why? Because Hibernate makes proxies to your collections to enable lazy loading, for example. So it creates
PersistentList
,PersistentSet
andPersistentBag
, which areList
but aren'tMatches
. So, if you want to add additional methods to that collection - well, you can't.Check this article for more details.
You have a solution, however. Don't use inheritance, use composition. You can, for example, add a method to your entity called
getMatchesCollection()
(in addition to the traditional getter), which looks like:And your
Matches
class would look like (using google-collections'ForwardingList
):If you can't use google collections, simply define the
ForwardingList
yourself - it's calling all the methods of the underlyingList
If you don't need any additional methods to operate on the structure, then don't define a custom collection.
Hibernate 要求将持久集合值字段声明为接口类型(因为出于延迟加载的目的,它们将被 Hibernate 的实现替换)。来自参考文档:
所以你的第二种方法是不可能的,至少不是你声明的方式。但说实话,我真的不明白这一点。
Hibernate requires persistent collection-valued fields to be declared as an interface type (because they will be replaced with Hibernate's implementation for lazy loading purposes). From the reference documentation:
So your second approach is not possible, at least not the way you declared it. But to be honest, I don't really see the point.