CDI + JPA多个@OneToMany - LAZY / EAGER - LazyInitializationException或无法实例化多个行李

时间:2013-05-18 18:25:26

标签: hibernate jpa cdi one-to-many

我正在使用Jboss AS 7,CDI,JPA和其他一些捆绑的资源开发应用程序。

我的问题是:当我使用maven-jboss-webapp-archetype在Eclipse中创建项目时,它会生成一些文件,我一直在广泛研究并尝试相处。问题是,有时我看到自己有点困惑我是否使用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,那么它会部署我的应用程序,但它无法正常运行,因为当我尝试从数据库中获取List时,它会给出错误: LazyInitializationException ,当我尝试使用FetchType.EAGER将它们全部放入时,它只是没有部署,因为它给出了错误:无法实例化多个包。

所以我的问题与以下内容有关:

1)Maven-jboss-webapp-archetype使用hibernate还是jpa还是两者兼而有之? 2)如何解决在实体中使用多个@OneToMany关系的问题?虽然我知道急切地获取模型中的集合并不是最好的方法,因为当系统增长时,我可能会遇到性能问题吗?那么我怎样才能正确使用Lazy加载?

1 个答案:

答案 0 :(得分:3)

首先,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关联,但其中只有一个可以是一个包(即Collection或List)。我一般不会建议热切的收藏品。但如果你真的想要它们,那就把它们设为集合而不是集合。