Hibernate:获取没有多个包的对象集合

时间:2012-12-14 13:10:50

标签: java hibernate jpa hibernate-mapping

当我尝试获取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

2 个答案:

答案 0 :(得分:1)

触发此异常是因为您正在接收员工并急切地获取员工的主题和员工的项目。

首先,确保你真的需要两者。

其次,要意识到通过这样做,你就会制作一个笛卡尔积。如果员工有100个项目和100个主题,则查询将仅为该员工返回10,000行。也许您应首先使用其项目(100行)获取员工,然后使用其主题(再次100行)重新获取员工。

第三,如果笛卡儿产品确实是您想要的,那么至少将其中一个集合设为Set而不是List。

答案 1 :(得分:0)

您可以在DAO中使用Hibernate.initialize()来获取与您的主对象相关的特定属性,这可以避免加载数据,可能您不需要这样的内容:

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