2012-07-16 23 views
0

我有三個表:Hibernate的多對多 - 只返回獨特的元素

Company 
id name 
1 Fred Co. 

Person 
id name 
1 Fred 

Employee 
id company_id person_id rank 
1 1   1   1 
2 1   1   2 

現在的等級是通過使用不同的應用程序,但我用什麼,我不關心它。我想要做的是創建一個hibernate映射(通過域模型),它將只返回唯一的員工。

我現在有

class Person { 
    @Column(name = "id") 
    Long id; 

    @Column(name = "name") 
    String id; 
} 

class Company { 
    @Column(name = "id") 
    Long id; 

    @Column(name = "name") 
    String id; 

    @ManyToMany(fetch = FetchType.LAZY) 
     @JoinTable(name = "EMPLOYEE", 
       joinColumns = { @JoinColumn(name = "COMPANY_ID") }, 
       inverseJoinColumns = { @JoinColumn(name = "PERSON_ID") }) 
    @LazyCollection(LazyCollectionOption.EXTRA) 
    List<Person> employees = new ArrayList<Person>(); 
} 

但這意味着fredCo.employees.size() == 2。我如何篩選,以便只有唯一的人返回?

我想通過域模型來做到這一點。

編輯:雖然上面的例子很小,但在現實生活中,Person對象非常大,每個公司有1000名員工(因此非常懶)。

現在我可以(和有)得到了

companyDao.getEmployeesFor(Company...) 
companyDao.getEmployeeCountFor(Company...) 

,但感覺有點噁心,我想這樣做不道。

回答

2

如果秩總是設置並且總是「1」的第一條記錄,那麼你可以添加一個簡單的@凡/ @ WhereJoinTable子句映射限制收集這些記錄與1

https://access.redhat.com/knowledge/docs/en-US/JBoss_Enterprise_Application_Platform/5/html/Hibernate_Annotations_Reference_Guide/entity-hibspec-collection.html

另一種方法是將集合更改爲Set,並在不涉及'rank'字段的Person上實現equals()方法。

更新:

好吧,正如你以前所說,這是行不通的。我做了一些測試,似乎@LazyCollection被定義在一個關聯上,@Where無論如何都會忽略對這個關聯的限制。在額外的懶集合上調用size()實際上會導致Hibernate針對數據庫發出一個count()查詢。附加條款不附加。

爲什麼@Where應該被忽略我不知道,但是這已經在別處詢問,似乎是一個懸而未決的問題:

https://forum.hibernate.org/viewtopic.php?f=9&t=988631&view=previous

https://hibernate.onjira.com/browse/HHH-3319

我覺得你還是可以做什麼您希望通過創建映射到使用先前的SQL內部查詢定義的VIEW的額外Employee實體 - 然後在db級別完成篩選。將實體映射到視圖與表格相同。

然後用公司和員工之間的兩個一對多關聯替換你的多對多關係。

+0

謝謝艾倫。排名不會總是一個。 設定的想法可行,但我不得不變得懶惰。我不會繼續這樣做,因爲它意味着加載1000個Person對象來獲得計數。 – 2012-07-16 13:35:29

+0

@where的另一種方法是定義一個過濾器。這將允許通過啓動和過濾以及在加載時間設置所需參數來實現動態限制,例如,從XYZ where rank =(從員工中選擇min(等級)where company_id =?和person_id =?) – 2012-07-16 13:45:48

+0

好主意,但它意味着我需要做hibernate.shakeMagicStick(fredCo); fredCo.employees.size();這對我來說有點不對勁,不如做companyDao.getEmployeesFor(fredCo)? – 2012-07-17 13:04:18