2012-12-14 23 views
0

当我试图让我的Employee实体我得到这个错误的清单:休眠:获取对象的集合,而不多袋

org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch 
multiple bags 

Employee实体类有不同对象的两个列表。我想有问题。

@ManyToMany 
@JoinTable(name = "employee_project", 
     joinColumns = {@JoinColumn(name = "employee_id", referencedColumnName = "employee_id")}, 
     inverseJoinColumns = {@JoinColumn(name = "project_id", referencedColumnName = "project_id")}) 
protected List<Project> projects; 

@OneToMany(cascade = CascadeType.ALL) 
@JoinColumn(name = "employee_id") 
protected List<EmployeeTheme> themes; 

我的实体Project没有在Employee对象的这一刻名单。但

public class EmployeeTheme implements Serializable { 

    @EmbeddedId 
    private EmployeeTheme PK id; 

    @ManyToOne 
    @JoinColumn(name = "employee_id", nullable = false, insertable = false, updatable = false) 
    protected Employee employee; 
} 

这是我为复合键类:

@Embeddable 
public class EmployeeThemePK implements Serializable { 

    @Column(name = "employee_id") 
    protected Long employeeId; 

    @Column(name = "theme") 
    protected String theme; 
} 

我怎样才能正确地配置这些关系?

编辑

我已经切换列表设置主题和项目。而且我已经排除了我的JSON主题,现在我又遇到了另一个异常。我还在我的DAO类中添加了criteria.setFetchMode("projects", FetchMode.JOIN);方法。

failed to lazily initialize a collection of role: com.package.Employee.projects, 
no session or session was closed 
org.hibernate.LazyInitializationException: failed to lazily initialize a 
collection of role: com.package.Employee.projects, no session or session 
was closed 


Exception caught during request processing: flexjson.JSONException: Error 
trying to deepSerialize 
flexjson.JSONException: Error trying to deepSerialize 

回答

1

这个异常是因为你得到了员工并且急于提取员工的主题和员工的项目而引发的。

首先,确保你确实需要两者。

其次,要意识到通过这样做,你就可以制作笛卡尔产品。如果员工有100个项目和100个主题,则该查询将为此员工返回10,000行。也许你应该首先获取其项目的员工(100行),然后重新获取雇员的主题(100行)。第三,如果笛卡尔产品真的是你想要的,那么至少使其中一个集合成为集合而不是列表。

+0

我们怎么能强制Hibernate feach时,你所描述的数据? –

+0

基本上我需要主题和项目给员工,因为我正在用员工列表创建JSON。每个员工的主题和项目都应该存在于我的JSON中。我如何从第二条建议中执行操作?首先我只需要使用Set? – woyaru

+0

只要按照我的建议做:执行第一个查询,返回员工的项目。执行相同的查询,但是用其主题提取员工。 seond查询将填充已在会话中缓存的用户的主题。或者做一个笛卡尔产品,但是至少有一个列表必须转换成一个Set。 –

0

您可以使用Hibernate.initialize()在DAO取得与您的主要对象相关especific Atributes,这避免加载数据可能客人不愿意需要这样的东西:

q = this.entityManager.createQuery('SQL..'); 
employee= q.getSingleResult(); 
Hibernate.initialize(employee.themes);