2017-01-23 125 views
0

項目使用播放框架1.3.3 我有一個這樣的控制器:播放框架1.3.3和Hibernate的緩存

public static void save(Item item) { 
    if (item.id != null) { //It means that item is not new, it is being edited 
     Item existingOldItem = Item.findById(item.id); 
     //Here I should have an old version of an item as "existingOldItem" 
     //and new one coming from http request as "item" 
    } 

但問題是項目和existingOldItem是非常一致的。 Item.findById行不會返回數據庫中的舊項目,但會從http請求中返回新項目(與JPA.em()。createQuery相同)。我想play framework會在緩存中發送一個新項目,而findById將從緩存中返回項目,而不是從數據庫中返回。請有人能向我解釋其背後的邏輯以及如何解決問題的方法。

回答

3

問題是項目和existingOldItem非常相同。 Item.findById行不返回我從數據庫中的舊項目

這是預期的行爲。 Item.findById()返回由HTTP客戶端修改的舊項目。在Play中看看JPA object binding!文檔來查看調用模式。

請,可能有人解釋我這背後的邏輯...

總之,HTTP客戶端預計將提供HTTP請求的項目記錄的ID和它的新的屬性值。玩!設置準備保存的item 參數,在數據庫中查找該項目並根據POST參數修改其屬性。所以你不應該有一個「舊」和「新」項目,你應該有一個 「項目」對象,可能是舊的或新的,這取決於HTTP客戶端提供的ID是否在 數據庫。您所有的控制器操作都需要調用item.save()

神奇的是JPAPlugin.bind。正如你猜測的那樣,它首先在數據庫中查找對象。 如果找到該對象,則使用該對象調用Item.edit()。這也是神奇的,並且默認實現設置了具有匹配的HTTP參數的Item的所有屬性。

...以及如何解決問題的方法。

我不知道你認爲的問題,但如果你想一老一新的項目,那麼客戶端不應該提供一個 item.id參數。如果你不喜歡那個Play!挖掘數據庫以實例化item參數,然後您可以提供自定義的 活頁夾或讓控制器操作接受類似外觀的POJO類,而不是JPA類。

+0

謝謝!這是使用JPA的任何Web框架的正常行爲,還是僅僅是一個Play!事情? –

+0

這是玩!具體。如果其他Web框架做同樣的事情,這是巧合。如果任何其他框架這樣做,我會感到驚訝,因爲item.save()是一個Play!並不是JPA實體通常如何工作。如果其他框架在內存中修改JPA對象,Hibernate可能會將更改刷新到數據庫,而不會給應用程序邏輯一個拒絕它們的機會。但在Play!中,應用程序邏輯必須調用save()才能刷新所做的更改。 –