2013-04-17 133 views
1

我對於stackoverflow和JPA都是新手,所以我會盡力解釋這一點。JPA,不希望insertable = false,updatable = false,解決方法?

在一個實體中,我想通過給定int值來設置外鍵,但是我想通過給出一個對象來設置它。這裏有一些代碼可以更好地解釋它。

@Entity 
public class Thread implements Serializable { 

    @ManyToOne 
    @JoinColumn(name = "accountId", referencedColumnName = "id", nullable = false) 
    public Account getAccount() { 
     return account; 
    } 

    @Column(name = "accountId") 
    @Basic 
    public int getAccountId() { 
     return accountId; 
    } 
} 

我已經嘗試了幾種方法,但上面的代碼是我嘗試實現的最好的例子。我明白,在兩種方法中的任何一種中設置insert = false和update = false,使得這些代碼在編譯和運行時都可以工作。但我希望能夠通過使用Account對象並通過設置實際的int accountId來插入accountId。

原因是因爲有時候,在我的服務器中,我只有accountId,有時候我有Account對象。

我也明白,最好的解決方案可能是在創建線程和設置accountId時使用account.getId()。但是,在我的服務器中使用該對象在邏輯上會更好。

在此先感謝!

+0

請參閱http://stackoverflow.com/questions/16043761/java-hibernate-entity-allow-to-set-related-object-both-by-id-and-object-itself – axtavt

+0

我只是使用對象並忘記使用該ID。如果您試圖超級優化應用程序,請使用會話緩存並嘗試使用'em.getReference()'來防止數據庫命中。 –

回答

3

我認爲你在應用程序中遇到了一個概念性問題。您應該堅持設置實體,並且在使用JPA時不要使用任何外鍵值。問題的原因是您的應用程序僅在某個時間提供accountId。

這可能是由於不同的原因。如果這是因爲只提供accountId的應用程序部分是遺留的,那麼我認爲使用適配器將accountId轉換爲Account實體並設置該實體是完全正確的。也不是說適配器可以創建一個JPA代理,這樣就不需要實際的數據庫訪問。我能想到的另一個原因是,應用程序在處理過程中的某個時刻丟失了信息。當應用程序在某個地方使用帳戶並且僅將代碼交給代碼時,可能會出現這種情況。然後這樣的代碼應該被重構以移交實體。

在您的具體情況下,您也可以同時使用帳戶作爲實體和外鍵作爲屬性,並且可以插入和更新。您只需確保accountId屬性值與指向由帳戶實體表示的行的外鍵一致。 JPA提供者應該能夠處理這個(我知道OpenJPA就是這樣)。然而,你對此有點限制。例如,您只能讀取accountId屬性值,因爲將其設置爲不同的值會導致帳戶實體值不一致。

+0

感謝您的回覆!在我學習了更多的東西之後,我已經意識到我可以使用getReference()來獲得代理。 不幸的是,我已經偶然發現了懶惰加載的新問題,這似乎並不工作,因爲我明白它應該。我發佈了兩個不同的問題,我嘗試以兩種不同的方式來解決問題。這裏是鏈接,如果你想檢查出來。 http://stackoverflow.com/questions/16266256/jpa-hibernate-want-lazy-load-to-return-empty-collection http://stackoverflow.com/questions/16294572/jpa-hibernate-collections-not -lazily加載的 –

相關問題