2009-08-31 64 views
2

我重構了一些從標準SQL到JPA/ORM使用的類。在大多數情況下,對象具有「真實」引用,但有時對其他對象的引用僅由未經檢查的數據庫id引用(無外鍵,只是簡單的引用另一個表id的字符串)提供。JPA參考重構

代碼如下:

@Entity 
public final class myEntity implements Serializable { 
    @Id 
    @GeneratedValue(generator = "system-uuid") 
    @GenericGenerator(name = "system-uuid", strategy = "uuid") 
    @Column(name = "ID") 
    private String id; 

    @OneToOne 
    @JoinColumn(name = "OBJREF", nullable = false) 
    private otherObject objReference; /* Nice object reference */ 

    @Column(name = "OTHEROBJREF") 
    private String otherObjReference; /* Damn db reference used by legacy code */ 
} 

我應該如何處理otherObjReference?該屬性由需要靜態getter/setter構造和String的遺留系統使用!如果我留在ID中,我會遇到JPA查詢問題,我不能簡單地分配一個對象並堅持下去。

我曾想過如何讓String瞬變並使用@PrePersist和@PreLoad加載「真實」對象引用,這樣我就可以同時使用它們。但在這些方法中,我無法訪問EntityManager(並且在這種情況下,持久性不應該是此pojo的任務......如果我在此處加載引用,它會聞起來像不好的設計)。

由於「otherObjReference」是私有的,我也可以使用getters和setter從我的真實參考加載數據。但其他圖層與對象一起工作,所以當他們調用getOtherObjReference()方法時,它們會失敗,因爲它們沒有數據庫連接來加載對象。

回答

2

這也是可能的(至少與toplink essentials)將同一列映射到兩個字段,只要其中一個是可更新和可插入的即可。

@Column(name = "OBJREF", nullable = false) 
private String otherObjectId; 

@ManyToOne(fetch=FetchType.LAZY) 
@JoinColumn(name = "OBJREF", nullable=false, updatable=false, insertable=false) 
private OtherObject otherObject; 

在你setOtherObject方法還可以設置otherObjectId。這種方法唯一的問題是,如果你只設置了字符串字段,那麼當你保存並從數據庫重新加載實體時,對象只會被更新。

+0

哇,我會試試看! – 2009-09-01 17:59:01

+0

請更新,如果它沒有工作,這是非常有趣的討論 – 2009-09-02 05:30:11

+0

@Jorn +1真的很有趣 – 2009-09-02 05:31:43

1

你真的嘗試過最後的解決方案嗎?

I.E.做一個正常的JPA映射,然後讓getter返回這樣的id?

public ID getOtherObjId() { 
    return otherObj.getId(); 
} 

即使離開會話邊界後,實際上它仍然有效。我不確定它今天是如何工作的,但至少在一些較早版本的hibernate中,它會在加載實體時將惰性代理放入其他Obj參考中,並且該延遲代理將包含所引用對象的ID。所以當你只訪問otherObj的id時,它會足夠聰明,不會加載對象。

如果這不起作用,您可以始終強制加載objectRef。 這有點貴,但它可能是值得的。

(順便說一句,如果你正在使用@OneToOne和可空= true時總是會急切地加載對方見here(尋找「一比一」)的一些簡短的說明)

+1

get方法非常簡單!主要的問題是set()方法應該從給定的ID中初始化一個實體。所以實體本身必須加載其引用(實體管理器注入),這看起來像代碼味道。如果: * otherObj在get()中爲「null」? *構造函數簽名也獲得一個ID? *客戶端(無db連接)調用setOtherObjId()來分配一個otherObj?它因爲沒有連接而失敗! – 2009-08-31 17:16:14

+1

@Martin你是對的,我忘記了set()用例。我希望我知道如何解決這個問題...... – 2009-09-02 05:31:09