2012-04-11 35 views
0

JPA 2.0中是否有可能確定嵌入式對象僅嵌入一個對象,而不是嵌入對象?JPA 2.0:一個實體專用的嵌入式對象

在我的情況下,我有一個Address,我可以分配給Customer。我希望每個客戶都使用自己的地址對象,並希望創建一個約束,以確保沒有兩個客戶共享實際上相同的對象。

我的代碼如下所示:

@Entity 
public Customer { 
    @Id 
    @GeneratedValue 
    private Long id; 

    @Embedded 
    private Address address; 

    // .. 
} 

@Embeddable 
public Address { 
    private String street; 
    private String city; 

    // .. 
} 

目前,如果我創建了兩個客戶,併爲它們分配相同的Address對象,然後堅持和閱讀他們,他們再一次分享同一個身份的對象。我想禁止保存與其他客戶共享地址的這類客戶。

+0

如果我明白你的意思,你想創造一個獨特的地址輸入即使地址在數據方面是相同的? – Phani 2012-04-11 15:06:18

+0

@Phani正是。未來對地址的更改應僅影響擁有該地址的一位客戶,並且不會對其他客戶產生任何副作用。解決這個問題的一種Java方法是在設置地址時創建一個地址副本(我假設),但我正在尋找一個基於JPA的解決方案。 – riwi 2012-04-11 15:10:29

+1

如果您沒有重寫equals方法,則理想情況下應該將2個條目存儲到數據庫。請檢查爲該動作生成的sql,以確定是什麼導致它被存儲爲1。 – Phani 2012-04-11 15:12:38

回答

1

在這種情況下最簡單的方法是在Customer.setAddress()中創建一個Address對象的副本。

此外,我不確定當從數據庫中檢索到不同的Customer可以共享Address具有相同的身份。也許你會從會話緩存中獲得相同的對象,因爲你在同一個會話中保存並讀取它們。

1

嵌入式機制的本質是嵌入式類的嵌入式實例永遠不會在封閉類的不同實例之間共享。如果您在代碼中觀察到此行爲,那肯定是因爲您在從實體管理器讀取數據期間正在訪問緩存數據。 因此,即使將可嵌入類的同一實例分配給封閉類的多個實例,然後「persist()」,然後銷燬實體管理器和EntityManagerFactories,或者使緩存失效「entityManager.getEntityManagerFactory()。getCache ).evictAll()「,然後創建一個新的EntityManager和」find()「封閉對象,它們中的每一個都應該有自己的實例(在你的情況下)」地址「對象,即使它們的內容是相同的。

JPA規範說,在2.5節以下有關嵌入對象:

[...]這些類的實例,不像實體的情況下,沒有自己的 持久化標識。相反,它們只是作爲其所屬實體的狀態的一部分而存在。 [...]

如果你的JPA實現不符合的是,它是不是真的JPA標準兼容...

相關問題