2009-07-13 21 views
1

我目前正在將JPA實體中沒有JPA/Hibernate經驗的人創建的100多個Java對象工作。它們的對象基於類中的外鍵引用其他對象。所有主鍵均在數據庫之外生成。Hibernate/JPA - 對象本身的外鍵索引

,例如(只是爲了說明)

汽車

@Entity 
@Table(name="CAR") 
public class Car { 

    private Integer id; 
    private String name; 

    @Id 
    @Column(name="CAR_ID") 
    public Integer getId() { 
     return id; 
    } 
    public void setId(Integer id) { 
     this.id = id; 
    } 

    @Column(name="CAR_NAME") 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 

} 

引擎

@Entity 
@Table(name="ENGINE") 
public class Engine { 

    private Integer id; 
    private String name; 
    private Integer carId; 

    @Id 
    @Column(name="ENGINE_ID") 
    public Integer getId() { 
     return id; 
    } 
    public void setId(Integer id) { 
     this.id = id; 
    } 

    @Column(name="ENGINE_NAME") 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 

    @Column(name="CAR_ID") 
    public Integer getCarId() { 
     return carId; 
    } 
    public void setCarId(Integer carId) { 
     this.carId = carId; 
    } 

} 

這裏的架構是什麼樣子:

CREATE TABLE CAR(CAR_ID INTEGER NOT NULL PRIMARY KEY,CAR_NAME VARCHAR(255)) 
CREATE TABLE ENGINE(ENGINE_ID INTEGER NOT NULL PRIMARY KEY,CAR_ID INTEGER,ENGINE_NAME VARCHAR(255)) 
ALTER TABLE ENGINE ADD FOREIGN KEY (CAR_ID) REFERENCES CAR(CAR_ID) ON DELETE CASCADE ON UPDATE CASCADE 

測試代碼

Car c = new Car(); 
    c.setId(100); 
    c.setName("Dodge Intrepid"); 
    em.persist(c); 

    Engine e = new Engine(); 
    e.setId(999); 
    e.setName("V6"); 
    e.setCarId(c.getId()); 
    em.persist(e); 

    Object entity = em.find(c.getClass(),c.getId()); 
    em.remove(entity); 

因此,汽車ID保存在數據庫引擎的參考。丟失延遲加載不是什麼大問題,因爲我們使用的是TRANSACTIONAL實體管理器。我已經測試過了,它似乎工作正常。

這是我有什麼明顯的問題,我失蹤了? 我知道它並不完全符合JPA/Hibernate規範,但我認爲它可行。

+0

用id關係替換對象引用後你的收益是多少? –

+0

這個好處是,我不必經過並更新100多個對象來使用@OneToOne或@OneToMany註釋 – systemoutprintln

回答

3

您失去的主要原因是通過對象圖輕鬆導航,而無需通過數據訪問層始終通過ID顯式獲取關聯對象。我知道你不願意將所有的對象ID轉換爲對象引用,但從長遠來看,你可能會更好地進行這種投資。通過繼續使用當前的設計,每次需要瀏覽關聯時,最終都會編寫大量額外的數據訪問代碼以獲取相關對象。另外,當對象未保存在數據庫中時(例如,在構建新的對象圖或單元測試時),它將使建模對象關係變得更加困難。你也放棄了級聯(傳遞)保存和更新。

總之,我認爲從長遠來看,您的系統將會更加難以維護,除非您解決這個設計問題,否則導航對象圖將非常尷尬。

+2

對於downvoting而言,不過我相信您不會考慮保留對象圖的缺點。雖然您正確地反對完整的對象圖更容易導航**,但在某些情況下,您永遠不會真正需要導航圖,至少對於實體中的少數引用而言。在這種情況下,如果你只需要被引用實體的ID,你可以加載整個被引用的實體,或者迫使Hibernate懶加載它來檢查它的ID –

+0

@djechelon我剛剛遇到你的評論。那麼是否有解決您剛纔描述的問題的方法?我想通過對象圖輕鬆導航,但有時候我只需要這個ID就可以測試對象的相等性。謝謝。 – Yang

+1

還有:http://stackoverflow.com/questions/15945944/hibernate-loading-a-lazy-proxy-but-i-only-need-the-pk –

1

沒有任何映射關係將使您幾乎不可能在HQL查詢或條件中進行任何連接。一個簡單的Select工作,但你不能這樣做

from Engine as eng where eng.car.name = 'DODGE' 

如果你至少可以得到的重大關係編碼它將使從長遠來看,事情變得更加簡單。