I’m trying to test my optimistic locking implementation of my application. However the result is not what I expect. The steps I take to test are the following
- load an entity from the database
- set the version attribute to one less than present in the database
- change another attribute thats just a string to something else
- save the entity
I expected a staleException now, however the entity just gets saved and the version increases to the next in line.
Here is a small extract of my save code
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;
}
I load objects by id with named queries thru my entire application with following code
@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;
}
And this is the configuration of my 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>
Is there anything I missed on the configuration of the sessionFactory or do I test it completly wrong and should I test it in a different way ?
Thanks in advance
Regressing the version field is dangerous as it is Hibernate controlled (if you’re using the JPA versioning functionality). Load in an entity, detach it (maybe use session.evict(obj)), alter an attribute. Load in the same entity, keep it attached, alter it, save it. Reattach the first entity and attempt to save it (I think Merge will do this). You should then see the StaleObjectStateException exception.