2015-08-20 52 views
1

我試圖找出一種更簡潔的方式,只使用兩個聯接表的實體ID將聯接表保存回數據庫。我可以讓我的代碼按原樣工作,但我覺得應該有一個更清晰的方式。使用唯一的ID字段爲聯接表創建JPA註釋實體

想象我有代表一個簡單的SQL連接表的實體,所以是這樣的:

@Entity 
@Table(name = "FOOBAR") 
public class FooBar{ 

    @ManyToOne(fetch = FetchType.Lazy) 
    @JoinColumn(name = "FOO_ID) 
    public Foo foo; 

    @ManyToOne(fetch = FetchType.Lazy) 
    @JoinColumn(name = "BAR_ID) 
    public Bar bar; 

    public FooBar(Foo foo, Bar bar){ 
     this.foo=foo; 
     this.bar=bar; 
    } 
} 

我有這需要一個Foo ID和酒吧ID,並想通過一個FooBar的對象的方法到我的保存方法來保存連接。

一個幼稚的實現會查詢數據庫以找到基於它們的id的Foo和Bar對象,將它們傳遞到FooBar構造函數中,然後將新的FooBar傳遞給save方法。

但是,這很愚蠢,我的連接表需要的唯一的東西是foo和bar id,而不是完整的DB對象。我已經擁有了我所需要的所有東西,而無需點擊數據庫來獲取Foo和Bar。

事實上,我可以簡單地使用它們的公共ID構造一個Foo對象和條形對象,忽略這些對象的所有其他字段,從這兩個'空'foo和條形對象創建一個FooBar對象,並將其傳遞給保存和它會工作得很好,沒有額外的數據庫命中。

然而,它不知怎麼覺得有點不乾淨做到這一點。我以這種方式創建了兩個「虛擬」對象。我的foo和bar對象可能有一些可爲空的= false列,我的數據庫契約承諾永遠不會爲null,所以感覺錯誤構造一個foo對象,確實爲具有這些列的空字段;好像我打破了這些對象的合同。我不想想爲構造函數的任何對象只接受一個I​​D,因爲;我希望強迫他們在任何時候有人構建他們的時候遵守我的合同。我寧願不必故意創建違反我的承諾的對象。

我不知道是否有通過JPA的方式,或者一些飛快地寫着抽象我能做的,在某種程度上是乾淨的,交際和僅使用foo和bar ID創建我的FooBar的對象不違反任何Foo/Bar約束條件。畢竟,因爲Foo和Bar都是懶加載的,所以當我第一次得到一個FooBar對象時,它真正包含的就是foo和bar id,直到我調用getter;所以我已經包含儘可能多的信息作爲數據庫中的FooBar對象。

我可以創建一個只有它們的ID的FooBar對象,並將該對象綁定到數據庫,因此如果將getter調用就像從數據庫中獲得的FooBar一樣,它會延遲加載Foo和Bar對象嗎?

回答

1

entityManager#getReference似乎是你在找什麼。它創建並返回一個對象,可以在需要對實體進行引用的任何地方使用,並且可以(但在你的情況下不需要)懶惰地取得所有狀態。

1

有一個連接表的類是矯枉過正。

JPA有ManyToMany註釋,它會爲您創建關係。

您基本上需要選擇其中一個實體來「擁有」關係。這或多或少是哪個類定義了用於連接的表。

在這種情況下,我將選擇Foo作爲擁有該關係的人。

Foo,你可以這樣做:

@ManyToMany 
@JoinTable(name="FOOBAR", [email protected](name="FOO_ID"), 
    [email protected](name="BAR_ID")) 
public Set<Bar> bars; 

Bar

@ManyToMany(mappedBy="bars") 
public Set<Foo> foos; 

注意,雖然我以前Set,您可以使用List代替。

注意:ManyToMany默認爲懶惰......我建議以這種方式離開。

+0

謝謝你,如果我對你有什麼我一直誠實的話,這是一個很好的答案:)事實上,表格被用來做一個多一點,然後我認爲有充足的理由爲什麼我們有它。我簡化了那部分來表達我認爲的問題:)不過,我很感謝你的回答,因爲在我提出的問題上這是一個很好的答案;這是我的問題,要求缺乏能力:) – dsollen

+0

儘管'List'被理解爲更高性能,我明白Hibernate建議使用'Set'來獲得最大的正確性。 – scottb

+0

擁有一個映射連接表的實體主要用於確實與關係有關的附加狀態,而不是任何一個相關實體(認爲員工和公司實體的僱用日期)。我希望OP使用它,所以我沒有提及@ManyToMany映射:) – Apokralipsa