2012-10-24 69 views
1

我試圖測試我的應用程序的樂觀鎖定實現。但結果不是我所期望的。我把測試的步驟如下休眠3:樂觀鎖定單元測試

  • 負載的實體從數據庫
  • 設置版本屬性爲一個小於存在於數據庫中
  • 改變另一個屬性那只是一個字符串,別的東西
  • 保存實體

我現在預期staleException,但是實體只是被保存,版本增加至線下。

這裏是我救的一小段摘錄

public <T extends DomainObject> T save(T objectToSave) { 
     Session currentSession = null; 
     try { 
      currentSession = sessionFactory.getCurrentSession(); 
      currentSession.save(objectToSave); 
      return objectToSave; 
     } catch (Exception ex) { 
      logger.error("save error",ex); 
     } 
     return null; 
    } 

我加載與經過我的整個應用程序命名查詢通過ID對象與下面的代碼

@SuppressWarnings("unchecked") 
public <T extends Object> List<T> query(Class<T> returnClass, String query, List<String> namedParams, List<? extends Object> params, Integer limit) { 
    Session currentSession = null; 
    try { 
     currentSession = sessionFactory.getCurrentSession(); 
     Query namedQuery = currentSession.getNamedQuery(query); 
     if(limit != null){ 
      namedQuery.setMaxResults(limit); 
     } 
     namedQuery.setCacheable(true); 
     if (namedParams != null && namedParams.size() > 0) { 
      addParams(namedQuery, namedParams, (List<Object>) params); 
     } 
     return namedQuery.list(); 
    } catch (Exception ex) { 
     logger.error("query error",ex); 
    } 
    return null; 
} 

這是我的SessionFactory的配置

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="entityInterceptor" ref="auditInterceptor" /> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="hibernateProperties"> 
     <value> 
      hibernate.dialect=${hibernate.dialect} 
      hibernate.show_sql=${hibernate.show_sql} 
      hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider 
      hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.EhCacheRegionFactory 
      hibernate.cache.use_query_cache=true 
      hibernate.cache.use_second_level_cache=true 
      hibernate.cache.provider_configuration_file_resource_path=ehcache.xml 
      hibernate.generate_statistics=true 
      hbm2ddl.auto=${hbm2ddl.auto} 
      hibernate.c3p0.min_size=${hibernate.c3p0.min_size} 
      hibernate.c3p0.max_size=${hibernate.c3p0.max_size} 
      hibernate.c3p0.timeout=${hibernate.c3p0.timeout} 
      hibernate.c3p0.max_statements=${hibernate.c3p0.max_statements} 
      hibernate.c3p0.idle_test_period=${hibernate.c3p0.idle_test_period} 
     </value> 
    </property> 
    <property name="schemaUpdate"> 
     <value>true</value> 
    </property> 
    <property name="annotatedClasses"> 
     <list> 
      <value>com.mbalogos.mba.domain.site.Site</value> 
     </list> 
    </property> 
</bean>   

有什麼我在配置上遺漏的東西sessionFactory或我測試它完全錯誤,我應該以不同的方式測試它嗎?

在此先感謝

回答

1

迴歸的版本字段是危險的,因爲它是進入休眠模式控制(如果你使用JPA版本的功能)。加載一個實體,分離它(也許使用session.evict(obj)),修改一個屬性。加載到同一個實體中,保留它,修改它,保存它。重新連接第一個實體並嘗試保存它(我認爲Merge會這樣做)。您應該看到StaleObjectStateException異常。

+0

嘿,我正在使用導入javax.persistence.Version;註釋確實是JPA版本控制。但是當你說脫離你的意思是把它交給它或別的東西?我簡化了我的問題,因爲整個故事有點複雜。我正在使用一個REST服務加載一個domainobject fe:站點版本爲1.然後我從domainobject轉換爲Json值對象並通過spring mvc發送給客戶端。 json對象發生了變化。它會將REST樣式與網站的ID一起發送回服務。 – kenny

+0

我從數據庫加載站點將所有屬性從新的jsonobject複製到加載的站點對象,然後保存站點。我希望這是明確的?在文本中解釋有點複雜。 – kenny

+0

您正在有效地使用JSON創建DTO。版本屬性是否在DTO中正確設置,並在保存時正確反序列化?您應該從相同版本的DTO進行兩次真正的更新,而不是試圖回退版本號。即進行兩次調用以獲取DTO(都是相同版本),進行更改,通過RESTful界面更新第一個DTO,然後更新第二個DTO,嘗試保存它。這應該引發異常,如果它不在某處可能有缺陷。 –