2011-09-29 45 views
1

我無法描述我的問題,我用例子再次嘗試:Hibernate的一對多的關係與非唯一鍵

我有兩個實體(表):。兩個表都有一個字段代碼這是不是唯一的

我該如何才能定義 manyToMany 雙向關係這些表之間?

  1. Departmen具有收藏者返回的所有實體與Person.CODE EQ Department.CODE
  2. 合作伙伴具有收集部門返回的所有實體與Department.CODE EQ Partner.CODE

我需要的關係定義 - 不需要sql或hpql查詢。

---------原來的問題-------

我需要創建Hibernate的關係,一個部門和個人(一個部門有很多的人)之間有許多。部門和人員有時間有效性(validFrom,validTill)

class Department { 
    Long id; 
    String code; 
    String name; 
    Date validFrom; 
    Date validTill; 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "departmentId") 
    @OnDelete(action = OnDeleteAction.CASCADE) 
    private Set<Person> persons = new HashSet<Person>(); 
} 


class Person { 
     Long id; 
     String name; 
     String surname; 
     Date validFrom; 
     Date validTill; 
    } 


沒有ORM(休眠)很容易在指定的日期來選擇特定的部門人數:

select P.* from Person P, Deparment d 
where d.code = ? and 
p.department_id = d.department_id and 
? between d.validFrom and d.validTill and 
? between p.validFrom and p.validTill 

該關係必須使用非唯一鍵(CODE)而不是部門ID。

是否有可能做類似的休眠?

我不需要分開的對象並自己構造查詢。

我想使用的ORM提供的所有功能(延遲加載,cascase堅持...)

+0

請添加映射 – ssedano

+0

您只想檢索數據,或者插入一個與現有更新所有關係相同的代碼的新部門? – ssedano

+0

兩者。檢索數據,當我插入一個新部門時,我想用CODE爲其分配屬於部門的所有人員。 – Vlada

回答

2

修訂

首先,你提到你想使用的ORM的全部功能。如果是這種情況,那麼你需要使用Hibernate友好的模式。 JPA持久性API和特定於Hibernate的API都提供了註釋,使您可以更輕鬆地使用「傳統」數據庫。但是如果你想完全正確地使用Hibernate,那麼你必須根據Hibernate的期望來設計你的模式。

在這種情況下,您可以通過使用連接公式代替連接列來處理關係。連接公式是一個有效的SQL片段(這可能會降低可移植性)。我在下面的例子中留下了實際的SQL。

public class Person { 
    ... 
    @OneToMany 
    @JoinFormula("sql fragment") 
    private List<Department> departments; 
    ... 
} 

public class Department { 
    ... 
    @OneToMany 
    @JoinFormula("sql fragment") 
    private List<Person> people; 
    ... 
} 

你也應該考慮治療碼作爲一個Hibernate對象:

@Embeddable 
public class Code { 
    ... 
    @Column(nullable = false, length = 20) 
    private String code; 
    ... 
} 

,而不僅僅是一個字符串,以便在實體關係中使用的代碼是由Hibernate持久性方面更有效的管理和行映射過程。

最後,請考慮實際將Person和Department之間的關係映射爲架構中的連接表。然後,您可以利用@ManyToMany@JoinTable批註在您的實體中執行實際的基於模式的關係。

+0

對不起。我不明白。 oneToMany和ManyToOne關係使用主鍵和外鍵。但我不需要這個。我的問題是我需要沒有PK-FK的關係。 – Vlada

+0

我已經更新了我的答案,以顯示使用沒有「真正的」外鍵的Hibernate關係。 – Jeff

+0

謝謝。很好的解釋。你能否提供使用CODE連接兩個表的sql片段? – Vlada

2

您可以定義一個Filter。它允許您將檢查添加到您執行的每個查詢中,或者如果您願意,可以將其禁用。

實施例:

<class name="Department" ...> 
    ... 
    <many-to-one name="person" column="person_id" class="Person"/> 
    <property name="validFrom" type="date" column="validFrom"/> 
    <property name="validTill" type="date" column="validTill"/> 
    <property name="code" type="string" column="code"/> 
    ... 
    <!-- 
     Note that this assumes non-terminal records have an eff_end_dt set to 
     a max db date for simplicity-sake 
    --> 
    <filter name="effectiveDate" 
      condition="code = :code and :asOfDate BETWEEN validFrom and validTill"/> 
</class> 

問候。

+0

過濾器不能正常工作:(因爲這個註解是主鍵(部門)和外鍵(person - departmentId)之間的關係,但我需要人員參考非唯一部門「代碼」 – Vlada

+0

這只是一個例子,但它適合你的問題的描述你可以在過濾器中放置任何東西(帶有命名參數的sql) – ssedano

+1

...或者可以使用HQL或動態添加標準 –