2011-09-22 22 views
1

使用RequestFactory我獲取數據到View,然後在其他事務中有人將此對象更新到版本1(我的視圖仍然是版本0)。接下來,我更新一些值,並通過RequestFactory將更改推送到DAO層。問題是何時將更改的對象轉移到服務層:定位器調用find方法並獲取最新版本的對象(由其他人更改)。所以當我們在DAO層獲取更新方法時,對象與版本1合併,並從兩個事務中更改!在這種情況下,在正常情況下,Hibernate應該拋出異常,因爲對象應該有其他版本值(樂觀鎖)?GWT RequestFactory在定位器中Hibernate不必要的調用查找方法

定位:

@Component 
public class TaskItemLocator extends Locator<TaskItem, Long> {  
    @Autowired 
    private TaskItemDao taskItemDao; 

    @Override 
    public TaskItem find(Class<? extends TaskItem> aClass, Long id) { 
    return taskItemDao.findTaskItem(id); 
    } 
} 

DAO:

@Override 
@Transactional(propagation = Propagation.REQUIRED) 
public void updateTaskItems(List<TaskItem> taskItemToUpdate) { 
     for (TaskItem ti : taskItemToUpdate) { 
      getHibernateTemplate().update(ti); 
     } 
} 

當我模擬這種情況沒有RequestFactory調用find一切工作正常。其他事務更改我的對象時引發異常。但是如何在RequestFactory中獲得這種行爲?除了每次更新RequestFactory調用find方法之外,所以選擇DB都會執行。接下來轉到DAO層,hibernate調用exacly同樣的select查詢,因爲他檢查對象版本。所以一個選擇是不重複的,爲每個更新的對象!

回答

1

RequestFactory僅發送差異(即在客戶端對象上發生的變化),因此需要在服務器端調用服務方法之前將這些差異應用於服務器端的對象,這就是爲什麼它需要通過它的ID查找對象。另外,當你引用一個對象而不修改它(例如你將一個屬性對象A設置爲引用對象B,對象B沒有被修改)時,將使用相同的find()方法;在這種情況下,您可能不希望發生樂觀的鎖定錯誤(即,無法將find樂觀鎖定檢查放入find()中)。
樂觀鎖定很難做好,因爲你必須處理衝突(並且用戶不想閱讀「在你修改它的時候某人改變了這個東西,所以我會去改變你的改變並且讓你重新開始從最新版本「)。關於樂觀鎖和RequestFactory,請參閱http://code.google.com/p/google-web-toolkit/issues/detail?id=6046

相關問題