2011-10-25 41 views
1

我有一個簡單的客戶端(JavaSE,Swing) - 服務器(Java EE,EJB,JPA)架構。JPA客戶端 - 服務器複製/同步框架?

我想爲我的服務器端實體創建一個客戶端「緩存」。例如,如果我下載了一個實體,我將它存儲在一個嵌入式Derby數據庫(帶有客戶端JPA)中,所以當它下次需要時,客戶端可以首先在它自己的數據庫中查找並從那裏檢索實體以備用網絡通信。 (簡單複製)

我的問題從實體的ID開始:在客戶端和服務器端都有相同的ID聽起來是一個非常糟糕的做法,所以我應該爲客戶端ID和服務器端ID存儲一些映射的一個實體。 問題仍然存在,因爲我有很多實體(15〜20 ..)以及它們之間的關聯。

配售右ID-S向服務器通信(更新,合併)或者朝向客戶端促進有一些遞歸和也許反射碼,發動機,這使所映射的ID·s的跟蹤:

  • 如果我修改了客戶端實體,並且想要合併到服務器,在發送到服務器之前,它應該從服務器端替換實體集中的客戶端ID(在各種@OneToMany外鍵中)
  • ,問題是通過vica

有誰知道這樣的框架,特別是JPA用戶?或者你是否有一些實施技巧? //我想在應用程序的持久性水平來解決這個問題,如果可能的話

由於提前, 安德拉什升

回答

0

我最近編碼的客戶端必須與服務器同步實體,將它們存儲在本地的德比數據庫。客戶端也可以創建必須與服務器同步的新實體。另外客戶端和服務器都使用相同的實體類,DAO和服務層組件。我會分享我碰到的問題和我的解決方案。如果他們是相關的,我希望他們幫助。

我在客戶端和服務器上使用了相同的ID字段。

您可能遇到的一個問題是自動生成的密鑰。我的服務器密鑰是在MS SQL Server數據庫中自動生成的。我的實體被註釋爲這樣。

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 

我第一次同步的實體到我的本地Derby數據庫我需要一種方法來使用服務器有相同的ID。

爲此,我在客戶端應用程序上創建了一個允許直接輸入密鑰的orm.xml文件。 orm.xml將覆蓋註釋。

請參見:Sequence Generator in persistence.xml

當然,在上面的鏈接中,我指定了本地數據庫的自定義生成器。您將指定ID字段爲無自動生成。

我在客戶端需要一個生成器,因爲我正在創建新的實體。在這種情況下,我需要一種方法來生成新的密鑰並從服務器插入實體。我使用Hibernate作爲我的JPA提供者。這使我可以創建一個偵聽器,用來確定實體是新的還是已經有了ID。基於此,我要麼允許生成器創建ID,要麼使用實體已有的ID。

請參見:JPA ID Generation Strategy

接下來,我需要爲服務器知道實體的新的方式。從上面的鏈接你可以看到我的發電機開始於100000000.在我的的情況下,這個數字足夠高,因爲服務器長時間(如果有的話)的ID不會很高。當然,這不是最乾淨的解決方案,我嘗試在客戶端上爲所有ID使用負數,但由於錯誤,Hibernate不會正確創建序列。

參見:JPA/Hibernate/Derby TableGenerator use negative values

所以我檢查所有的實體來了,如果有的話都是上面的幻數(100000000)在服務器上,我之前保存空出自己的ID。這樣服務器將把它們添加爲新的,並且它們將從服務器獲得一個ID。然後他們必須同步回客戶端等。

希望這有助於。

+0

感謝您的提示!我想知道是否有框架,我可以跳過爲我的許多嵌套實體實現這樣的ID處理邏輯。 –

+0

hibernate偵聽器適用於所有實體。它在任何實體保存到數據庫時運行。唯一的其他ID邏輯位於從客戶端到服務器的同步。你也可以爲此寫一個監聽器。然後一切都包含在2個班級中。 – Allan

1

什麼不能使用相同的ID?似乎你不會有任何問題,如果你沒有嘗試有不同的...

+0

我使用相同ID的基本問題是離線可用性。當我在客戶端有一個新實體時,例如沒有服務器連接,我仍然需要首先在客戶端存儲實體,所以ID來自客戶端數據庫,然後在同步過程中,我必須再次處理ID-s .. –