首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在JPA中映射自定义集合?

如何在JPA中映射自定义集合?
EN

Stack Overflow用户
提问于 2010-07-04 10:32:47
回答 2查看 8.8K关注 0票数 12

在使用JPA (Hiberante provider)映射自定义集合时,我遇到了问题。例如,当我使用带有属性的对象时

代码语言:javascript
运行
复制
List<Match> matches;

使用

代码语言:javascript
运行
复制
<one-to-many name="matches">
    <cascade>
        <cascade-all />
    </cascade>
</one-to-many>

在我的ORM文件中,它是可以的;但是如果我将"List matches;“替换为

代码语言:javascript
运行
复制
private Matches matches;

,其中“匹配”的定义如下:

代码语言:javascript
运行
复制
public class Matches extends ArrayList<Match> {

    private static final long serialVersionUID = 1L;
}

它会产生以下错误:

代码语言:javascript
运行
复制
Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: by.sokol.labs.jpa.MatchBox.matches

感谢您的关注!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-07-04 10:44:13

您可以,但您必须将其称为公共集合之一- ListSet

因此:

代码语言:javascript
运行
复制
private List matches = new Matches();

为什么?例如,Hibernate对集合进行代理以启用延迟加载。因此,它创建了PersistentListPersistentSetPersistentBag,它们是List,但不是Matches。因此,如果您想要向该集合添加其他方法,那么您不能。

检查这篇文章为您提供更多细节。

不过,你有个解决办法。不要使用继承,要使用组合。例如,您可以向实体添加一个名为getMatchesCollection()的方法(除了传统的getter),如下所示:

代码语言:javascript
运行
复制
 public Matches getMatchesCollection() {
    return new Matches(matches);
 }

您的Matches类看起来类似于(使用google-集合ForwardingList):

代码语言:javascript
运行
复制
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的所有方法

如果不需要任何额外的方法来对结构进行操作,那么就不要定义自定义集合。

票数 8
EN

Stack Overflow用户

发布于 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.Setjava.util.Collectionjava.util.Listjava.util.Mapjava.util.SortedSetjava.util.SortedMap或您喜欢的任何东西(“任何您喜欢的”意味着您必须编写org.hibernate.usertype.UserCollectionType的实现)。 注意实例变量是如何使用HashSet实例初始化的。这是初始化新实例化(非持久性)实例的集合值属性的最佳方法。当您使实例持久时,例如通过调用persist(),Hibernate实际上将用Hibernate自己的Set实现的实例来替换HashSet

所以你的第二种方法是不可能的,至少不像你声明的那样。但老实说,我不太明白重点。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3174379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档