CDI + JPA 多个 @OneToMany - LAZY/EAGER - LazyInitializationException 或无法实例化多个包
Posted
技术标签:
【中文标题】CDI + JPA 多个 @OneToMany - LAZY/EAGER - LazyInitializationException 或无法实例化多个包【英文标题】:CDI + JPA Multiple @OneToMany - LAZY/EAGER - LazyInitializationException OR Cannot instantiate multiple bags 【发布时间】:2013-05-13 17:09:29 【问题描述】:我正在使用 Jboss AS 7、CDI、JPA 和其他一些捆绑资源开发应用程序。
我的问题是:当我在 Eclipse 中使用 maven-jboss-webapp-archetype 创建一个项目时,它会生成一些文件,我一直在广泛研究并试图与之相处。问题是,有时我觉得自己是在使用 Hibernate 资源还是 JPA 资源有点困惑。
第二个问题:当我在同一个实体中使用多个 @OneToMany 关系时,我注意到两种行为:
a) 如果没有为 Fetch 指定 EAGER 类型,它会部署应用程序,但是当我尝试使用该列表时,它给了我 LazyInitializationException 错误,因此在这里进行了广泛讨论。
b) 当我在 @*ToMany 关系上为 FetchType 指定 Eager 时,它只是不部署应用程序。它给了我错误:无法实例化多个包。
这是有问题的代码:
@OneToMany(cascade = CascadeType.ALL, mappedBy = "teamUser" , fetch = FetchType.EAGER)
private Collection<Users> usersCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "teamRanking" , fetch = FetchType.LAZY)
private Collection<Ranking> rankingCollection;
@NotNull
@OneToMany(cascade = CascadeType.ALL, mappedBy = "teamModality" , fetch = FetchType.LAZY)
private Collection<Modality> modalitiesCollection;
public Teams()
public Teams(Long id_team , String name)
this.id = id_team;
this.name = name;
我一直在阅读这方面的内容,人们告诉我 JPA 不支持 FetchType.EAGER 用于同一实体中的多个关系。但是我需要在这个实体中具体使用多个关系。我不知道该怎么办了,因为我尝试了几种方法,Lazy fetching,所有这些方法都存在某种问题。例如,如果我在课堂上只留下一个 FetchType.EAGER,那么它会部署我的应用程序,但它无法正常运行,因为当我尝试从数据库中获取列表时,它会给我错误:LazyInitializationException,当我尝试使用 FetchType.EAGER 将它们全部放入时,它只是没有部署,因为它给出了错误:无法实例化多个包。
所以我这里的问题与:
1) Maven-jboss-webapp-archetype 使用 hibernate 或 jpa 还是两者兼而有之? 2)如何解决在实体中使用多个@OneToMany 关系的问题?尽管我知道急切地获取模型中的集合并不是最好的方法,因为当系统增长时,我可能会遇到性能问题,对吧?那么如何才能正确使用延迟加载呢?
【问题讨论】:
您使用的是什么 JPA 实现?休眠? 是的,我使用的是捆绑在 JBoss AS 7 中的 hibernate,我认为它是 Hibernate 4。感谢您的回答 John 你可能应该看看这个 SO 作为参考:***.com/questions/10769656/… 它使用 Hibernate 特定的注释,但可以做你需要的。 【参考方案1】:首先,Hibernate 是 JPA 规范的一种实现,是 JBoss 中的默认实现。因此,您使用的是 JPA,并使用 Hibernate 作为实现。
其次,您会得到一个 LazyInitialization 异常,因为您在关闭会话后访问了一个延迟加载的集合,而在会话仍处于打开状态时没有初始化此集合。如果您有两个惰性集合并且您知道客户端代码都需要初始化,请在返回实体和关闭会话之前初始化它们(即当您仍在事务服务方法中时):
SomeEntity e = em.find(SomeEntity.class, someId);
e.getFirstCollection().size(); // initialize the first collection
e.getSecondCollection().size(); // initialize the second collection
return e;
您可以一次获取多个 toMany 关联,但其中只有一个可以是包(即集合或列表)。我一般不建议急切的收藏。但是,如果您真的想要它们,请将它们设置为集合而不是集合。
【讨论】:
JB Nizet 非常感谢您的解释。这让事情变得更加清晰。你能看看我的DAO方法之一吗?因为我不知道您所说的事务服务方法到底是什么意思。因为我没有使用诸如 commit 之类的方法从数据库中检索数据。 [code] public List以上是关于CDI + JPA 多个 @OneToMany - LAZY/EAGER - LazyInitializationException 或无法实例化多个包的主要内容,如果未能解决你的问题,请参考以下文章
在 Java SE 中拥有 CDI 和 JPA 的最简单方法是啥?