2012-12-14 28 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);