2014-07-21 38 views
2

我是hibernate/JPA的新手,併爲此noob問題道歉。我有如下關係與實體休眠ManyToMany結果笛卡爾產品

  • 經理有許多與工人
  • 工人一對多的關係有許多與任務

許多關係以下是ERD

enter image description here

以下是我的java類

@Entity 
@table(name="manager") 
public class Manager { 

private long id; 

private String name; 

@ManyToMany(fetch = FetchType.EAGER) 
@JoinTable(name = "manager_worker", joinColumns = { @JoinColumn(name = "manager_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "worker_id") }) 
private ArrayList<Worker> workers = new ArrayList<Worker>(); 

// ......getter setter 
} 

@Entity 
@Table(name = "worker") 
public class Worker { 

@Id 
private long id; 

private String name; 
@ManyToMany(fetch = FetchType.EAGER) 
@JoinTable(name = "worker_task", joinColumns = { @JoinColumn(name = "worker_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "task_id") }) 
private ArrayList<Task> tasks = new ArrayList<Task>(); 
    ........................... 
} 

@Entity 
@Table(name = "task") 
public class Task { 

@Id 
private long id; 

private String title; 
      ................. 
} 

我有以下數據:

  • 經理M1有工人W1和W2
  • W1具有任務TW1,TW2,TW3
  • W2具有任務TW2和TW2

當我獲得Id M1的Manager對象,結果爲Worker和Task的笛卡爾乘積,即W1數據重複3次,W2數據重複2次,即Manager.worker數組列表有5個工作對象而不是2個。

要加載我使用Session.get()方法

public E find(final K key) { 
    return (E) currentSession().get(daoType, key); 
} 

誰能告訴我怎樣才能解決這個問題,並指向我,我應該在這種情況下使用的最佳做法的數據。

感謝

+0

嘗試'@ManyToMany(取= FetchType.LAZY)''用於在'Wokrer' CLAS tasks'秒。 –

+0

你能告訴我們你如何保存對象嗎? – shazin

+0

@Shazin我還沒有編碼保存。數據已經在數據庫中,我正在試圖查詢它。 – amique

回答

2

發生這種情況是因爲兩個@ManyToMany關係都是急切加載的。

這將導致所有三個表的外連接。該查詢的結果是五行,其中W1出現三次,W2出現兩次。到目前爲止一切都是正確的

但由於某種原因,Hibernate只是將所有工作人員放入集合中,即使他們是重複的。它甚至在FAQ中描述。

有解決此問題的多種選擇:

  • 改變延遲加載
  • 的關係之一,而不是使用列表的設置(你不應該使用ArrayList類型變量反正特別當使用Hibernate時)
  • 使用@Fetch(FetchMode.SELECT)tasks
+0

謝謝@Jimmy。更改爲設置可解決問題。 – amique

2

哪裏是你的targetEntity@ManyToMany關係?

你應該是這樣的:

@ManyToMany(targetEntity = Task.class) 
@JoinTable(name = "worker_task", joinColumns = { @JoinColumn(name = "worker_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "task_id") }) 
private ArrayList<Task> tasks = new ArrayList<Task>(); 

我建議你反正更改爲@OneToMany@ManyToOne關係。這個概念與數據庫設計更加兼容,當人們看待ERD時更容易理解。因此Manager與Manager_Worker具有一對多的關係,因此manager_worker與經理具有多對一的關係。對其他實體保持不變。