没有Hibernate Session绑定到线程,并且配置不允许在这里创建非事务性的 [英] No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
问题描述
当我调用一个使用 SessionFactory.getCurrentSession()
的DAO方法时,我得到这个异常。 DAO类用 @Transactional
注释,我还有< tx:annotation-driven />
声明应用程序上下文配置文件。
我可以调用执行HQL查询的DAO方法,但每当我调用一个首先获取Hibernate会话的DAO方法时,我都会遇到这个问题例外:
SEVERE:保存对象失败。
org.hibernate.HibernateException:没有Hibernate Session绑定到线程,并且配置不允许在这里创建非事务性的$ b $ org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java: 63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)
at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.getCurrentSession(GenericDaoHibernateImpl.java:56)
at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.saveOrUpdate(GenericDaoHibernateImpl.java:187)
我有以下应用程序上下文配置文件:
<?xml version =1.0encoding = UTF-8 >?;
< beans xmlns =http://www.springframework.org/schema/beans
xmlns:aop =http://www.springframework.org/schema/aop
xmlns:flex =http://www.springframework.org/schema/flex
xmlns:tx =http://www.springframework.org/schema/tx
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation =http://www.springframework.org/schema/beans
http:// www。 springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/flex
http://www.springframework.org/schema/flex/ spring-flex-1.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd >
<! - - ~~~~~~~~~~~ 〜 - >
<! - 用于bean属性的加载值 - >
<! - ~~~~~~~~~~~~~~~~~~~~~~& - > ;
< bean class =org.springframework.beans.factory.config.PropertyPlaceholderConfigurer>
< property name =locations>
< value> applicationContext.properties< / value>
< / property>
< / bean>
<! - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~>>
<! - 其中对象将被持久保存的数据源 - >
<! - 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 ~~~ - >
< bean id =dataSourceclass =org.springframework.jdbc.datasource.DriverManagerDataSource>
< property name =usernamevalue =$ {datasource.username}/>
< property name =passwordvalue =$ {datasource.password}/>
< property name =urlvalue =$ {datasource.url}/>
< property name =driverClassNamevalue =$ {datasource.driver}/>
< / bean>
<! - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~ - >
<! - 用于休眠会话的工厂bean - >
<! - - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>>
< bean id =hibernateSessionFactoryclass =org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean>
< property name =dataSourceref =dataSource/>
< property name =annotatedClasses>
< list>
<值> gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvg< /值>
<值> gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlObservations< /值>
<值> gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlStation< /值>
< / list>
< / property>
< property name =hibernateProperties>
<道具>
< prop key =hibernate.dialect> $ {hibernate.dialect}< / prop>
< prop key =hibernate.show_sql> false< / prop>
< prop key =hibernate.format_sql> true< / prop>
< prop key =hibernate.use_sql_comments> true< / prop>
< prop key =hibernate.jdbc.batch_size> 50< / prop>
< prop key =hibernate.query.substitutions> true 1,false 0< / prop>
< prop key =hibernate.max_fetch_depth> 6< / prop>
< prop key =hibernate.hbm2ddl.auto> $ {hibernate.hbm2ddlauto}< / prop>
< prop key =hibernate.cache.use_second_level_cache> $ {hibernate.use_second_level_cache}< / prop>
< /道具>
< / property>
< / bean>
<! - - ~~~~~~~~~~~~~~~~~~~~~~~ - >
<! - 事务管理器bean - >
<! - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - >
< bean id =transactionManagerclass =org.springframework.orm.hibernate3.HibernateTransactionManager>
< property name =sessionFactoryref =hibernateSessionFactory/>
< / bean>
<! - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 - >
<! - 启用基于注释的事务行为配置 - >
<! - 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 - >
< tx:注解驱动的事务管理器=transactionManager/>
<! - 〜~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - >> ;
<! - DAO用于ESRL工作站对象 - >
<! - 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 - >
< bean id =esrlStationDaoclass =gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlStationDaoHibernateImpl>
< property name =sessionFactoryref =hibernateSessionFactory/>
< property name =persistentClassvalue =gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlStation/>
< / bean>
<! - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~ - >
<! - DAO for ESRL Observations objects - >
<! - - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>>
< bean id =esrlObservationsDaoclass =gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlObservationsDaoHibernateImpl>
< property name =sessionFactoryref =hibernateSessionFactory/>
< property name =persistentClassvalue =gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlObservations/>
< / bean>
<! - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ - >
<! - DAO用于ESRL日常平均物品 - >
<! - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - >
< bean id =esrlDailyAvgDaoclass =gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlDailyAvgDaoHibernateImpl>
< property name =sessionFactoryref =hibernateSessionFactory/>
< property name =persistentClassvalue =gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvg/>
< / bean>
< / beans>
泛型DAO类(从我的程序中使用的DAO扩展)如下所示:
package gov.noaa.ncdc.cmb.persistence.dao;
导入gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
/ **
*这个类是GenericDao< T,PK>使用Hibernate。
* /
public class GenericDaoHibernateImpl< T extends PersistentEntity< PK>,PK extends Serializable>
实现GenericDao< T,PK>
{
private SessionFactory sessionFactory;
static private Log log = LogFactory.getLog(GenericDaoHibernateImpl.class);
私人课程< T>对PersistentClass;
/ **
*可以在子类中用作方便的方法。
*
* @param criterionList根据
查找的标准* @返回符合指定条件的元素列表
* /
protected List< T> findByCriteria(final List< Criterion> criterionList)
{
Criteria criteria = getCurrentSession()。createCriteria(persistentClass); (标准标准:标准清单)
{
criteria.add(标准);
}
return criteria.list();
protected String getCanonicalPersistentClassName()
{
return persistentClass.getCanonicalName();
}
/ **
*获取当前的Hibernate Session对象。
*
* @return
* /
protected Session getCurrentSession()
{
return sessionFactory.getCurrentSession();
}
/ *
*此方法仅提供界面兼容性。不建议与大批量
*一起使用(这是一个效率低下的实现,并且使用Hibernate执行批处理操作有点困难)。
*
*(非Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#batchInsert(java.util.Collection)
* /
@Override
public int [] batchInsert(final Collection< T> entityCollection)
{
int [] updateCounts = new int [entityCollection.size()];
int i = 0; (T entity:entityCollection)
{
try
{
saveOrUpdate(entity);
updateCounts [i] = 1;
i ++;
}
catch(Exception ex)
{
clear();
抛出新的RuntimeException(ex);
}
}
flush();
clear();
返回updateCounts;
}
/ *
*此方法仅提供界面兼容性。不建议与大批量
*一起使用(这是一个效率低下的实现,并且使用Hibernate执行批处理操作有点困难)。
*
*(非Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#batchUpdate(java.util.Collection)
* /
@Override
public int [] batchUpdate(final Collection< T> entityCollection)
{
return batchInsert(entityCollection);
}
/ **
*完全清除会话。退出所有加载的实例并取消所有未决的保存,更新和删除。
*不能关闭打开的迭代器或ScrollableResults的实例。
* /
public void clear()
{
getCurrentSession()。clear();
}
/ *
*(非Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#delete(gov。 noaa.ncdc.cmb.persistence.entity.PersistentEntity)
* /
@Override
public void delete(final T persistentObject)
{
getCurrentSession()。delete (持久性对象);
}
/ *
*(非Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#findAll()
* /
@Override
public List< T> findAll()
{
return getCurrentSession()。createQuery(from+ persistentClass.getName())。list();
}
/ **
*查找与示例实例相匹配的实体对象的集合,减去应从匹配中排除的任何指定属性。
*
* @param exampleInstance
* @param excludeProperty
* @return
* /
public List< T> findByExample(final T exampleInstance,
final String [] excludeProperty)
{
Criteria criteria = getCurrentSession()。createCriteria(persistentClass);
示例示例= Example.create(exampleInstance);
if(excludeProperty!= null)
{
for(String exclude:excludeProperty)
{
example.excludeProperty(exclude);
}
}
criteria.add(example);
return criteria.list();
}
/ *
*(非Javadoc)
*请参阅com.sun.cloud.lifecycle.core.persistence.dao.GenericDao#findById( java.io.Serializable)
* /
@Override
public T findById(final PK id)
{
return(T)getCurrentSession()。load(persistentClass , ID);
}
/ **
*强制本次会话刷新。必须在工作单元结束时调用,然后提交事务并
*关闭会话(取决于flush-mode,Transaction.commit()调用此方法)。
*
* Flushing是将持久存储器与持久存储器中的持久存储器进行同步的过程。
* /
public void flush()
{
getCurrentSession()。flush();
}
/ *
*(非Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#saveOrUpdate(gov。 noaa.ncdc.cmb.persistence.entity.PersistentEntity)
* /
@Override
public T saveOrUpdate(final T entity)
{
try
{
entity.setUpdatedDate(new Date());
getCurrentSession()。saveOrUpdate(entity);
返回实体;
}
catch(Exception ex)
{
String errorMessage =无法保存对象。
log.error(errorMessage,ex);
抛出新的RuntimeException(errorMessage,ex);
}
}
/ **
*用于persistentClass属性的Setter。
*
* @param persistentClass
* /
public void setPersistentClass(final Class< T> persistentClass)
{
this.persistentClass = persistentClass;
}
/ **
*属性设定器。
*
* @param sessionFactory
* /
public void setSessionFactory(final SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
}
我的应用程序从应用程序上下文:
//加载Spring应用程序上下文,获取DAOs
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String [] {dailyAveragingApplicationContext.xml});
esrlDailyAvgDao =(EsrlDailyAvgDao)applicationContext.getBean(esrlDailyAvgDao);
esrlObservationsDao =(EsrlObservationsDao)applicationContext.getBean(esrlObservationsDao);
当我尝试保存一个实体时遇到异常:
esrlDailyAvgDao.saveOrUpdate(esrlDailyAvg);
DAO类本身使用Transactional注释:
@Transactional
public class EsrlDailyAvgDaoHibernateImpl
extends GenericDaoHibernateImpl< EsrlDailyAvg,Long>
implements EsrlDailyAvgDao
异常堆栈跟踪如下所示:
SEVERE:无法保存对象。
org.hibernate.HibernateException:没有Hibernate Session绑定到线程,并且配置不允许在这里创建非事务性的$ b $ org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java: 63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)
at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.getCurrentSession(GenericDaoHibernateImpl.java:56)
at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.saveOrUpdate(GenericDaoHibernateImpl.java:187)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun。反射.NativeMethodAccessorImpl.invoke(未知源)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(未知源)
在java.lang.reflect.Method.invoke(未知源)
at org。 springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.spri ngframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
at $ Proxy19.saveOrUpdate(Unknown Source)
at gov.noaa.ncdc.cmb.esrl.ingest.EsrlDailyAvgProcessor.main( EsplDailyAvgProcessor.java:469)
@Transactional
添加到基本/泛型Hibernate DAO实现类(实现由我在主程序中使用的DAO继承的saveOrUpdate()方法的父类),即<需要在实现该方法的实际类上指定code> @Transactional 。我的假设是,如果我在子类上声明 @Transactional
,那么它包含了子类继承的所有方法。但是,似乎 @Transactional
注释仅适用于在类中实现的方法,而不适用于由类继承的方法。
I am getting this exception when I call a DAO method which uses SessionFactory.getCurrentSession()
. The DAO class is annotated with @Transactional
and I also have <tx:annotation-driven/>
declared in the application context configuration file.
I can call my DAO methods which perform HQL queries, but whenever I call a DAO method which first gets the Hibernate session then I run into this exception:
SEVERE: Failed to save the object.
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)
at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.getCurrentSession(GenericDaoHibernateImpl.java:56)
at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.saveOrUpdate(GenericDaoHibernateImpl.java:187)
I have the following application context configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:flex="http://www.springframework.org/schema/flex"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/flex
http://www.springframework.org/schema/flex/spring-flex-1.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- load values used for bean properties -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>applicationContext.properties</value>
</property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- DataSource where objects will be persisted -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
<property name="url" value="${datasource.url}" />
<property name="driverClassName" value="${datasource.driver}" />
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- Factory bean for Hibernate Sessions -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvg</value>
<value>gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlObservations</value>
<value>gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlStation</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.jdbc.batch_size">50</prop>
<prop key="hibernate.query.substitutions">true 1, false 0</prop>
<prop key="hibernate.max_fetch_depth">6</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddlauto}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.use_second_level_cache}</prop>
</props>
</property>
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- Transaction Manager bean -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernateSessionFactory" />
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- enable the configuration of transactional behavior based on annotations -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- DAO for ESRL Station objects -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<bean id="esrlStationDao" class="gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlStationDaoHibernateImpl">
<property name="sessionFactory" ref="hibernateSessionFactory" />
<property name="persistentClass" value="gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlStation" />
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- DAO for ESRL Observations objects -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<bean id="esrlObservationsDao" class="gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlObservationsDaoHibernateImpl">
<property name="sessionFactory" ref="hibernateSessionFactory" />
<property name="persistentClass" value="gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlObservations" />
</bean>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- DAO for ESRL daily average objects -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<bean id="esrlDailyAvgDao" class="gov.noaa.ncdc.cmb.esrl.domain.dao.EsrlDailyAvgDaoHibernateImpl">
<property name="sessionFactory" ref="hibernateSessionFactory" />
<property name="persistentClass" value="gov.noaa.ncdc.cmb.esrl.domain.entity.EsrlDailyAvg" />
</bean>
</beans>
The generic DAO class (from which the DAO being used in my program is extended) looks like this:
package gov.noaa.ncdc.cmb.persistence.dao;
import gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
/**
* This class is an implementation of GenericDao<T, PK> using Hibernate.
*/
public class GenericDaoHibernateImpl<T extends PersistentEntity<PK>, PK extends Serializable>
implements GenericDao<T, PK>
{
private SessionFactory sessionFactory;
static private Log log = LogFactory.getLog(GenericDaoHibernateImpl.class);
private Class<T> persistentClass;
/**
* Can be used within subclasses as a convenience method.
*
* @param criterionList the criteria to find by
* @return the list of elements that match the specified criteria
*/
protected List<T> findByCriteria(final List<Criterion> criterionList)
{
Criteria criteria = getCurrentSession().createCriteria(persistentClass);
for (Criterion criterion : criterionList)
{
criteria.add(criterion);
}
return criteria.list();
}
protected String getCanonicalPersistentClassName()
{
return persistentClass.getCanonicalName();
}
/**
* Gets the current Hibernate Session object.
*
* @return
*/
protected Session getCurrentSession()
{
return sessionFactory.getCurrentSession();
}
/*
* This method only provided for interface compatibility. Not recommended for use with large batches
* (this is an inefficient implementation, and it's somewhat difficult to perform batch operations with Hibernate).
*
* (non-Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#batchInsert(java.util.Collection)
*/
@Override
public int[] batchInsert(final Collection<T> entityCollection)
{
int[] updateCounts = new int[entityCollection.size()];
int i = 0;
for (T entity : entityCollection)
{
try
{
saveOrUpdate(entity);
updateCounts[i] = 1;
i++;
}
catch (Exception ex)
{
clear();
throw new RuntimeException(ex);
}
}
flush();
clear();
return updateCounts;
}
/*
* This method only provided for interface compatibility. Not recommended for use with large batches
* (this is an inefficient implementation, and it's somewhat difficult to perform batch operations with Hibernate).
*
* (non-Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#batchUpdate(java.util.Collection)
*/
@Override
public int[] batchUpdate(final Collection<T> entityCollection)
{
return batchInsert(entityCollection);
}
/**
* Completely clear the session. Evict all loaded instances and cancel all pending saves, updates and deletions. Do
* not close open iterators or instances of ScrollableResults.
*/
public void clear()
{
getCurrentSession().clear();
}
/*
* (non-Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#delete(gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity)
*/
@Override
public void delete(final T persistentObject)
{
getCurrentSession().delete(persistentObject);
}
/*
* (non-Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#findAll()
*/
@Override
public List<T> findAll()
{
return getCurrentSession().createQuery("from " + persistentClass.getName()).list();
}
/**
* Finds a collection of entity objects which match to the example instance, minus any specified properties which should be excluded from the matching.
*
* @param exampleInstance
* @param excludeProperty
* @return
*/
public List<T> findByExample(final T exampleInstance,
final String[] excludeProperty)
{
Criteria criteria = getCurrentSession().createCriteria(persistentClass);
Example example = Example.create(exampleInstance);
if (excludeProperty != null)
{
for (String exclude : excludeProperty)
{
example.excludeProperty(exclude);
}
}
criteria.add(example);
return criteria.list();
}
/*
* (non-Javadoc)
* @see com.sun.cloud.lifecycle.core.persistence.dao.GenericDao#findById(java.io.Serializable)
*/
@Override
public T findById(final PK id)
{
return (T) getCurrentSession().load(persistentClass, id);
}
/**
* Force this session to flush. Must be called at the end of a unit of work, before commiting the transaction and
* closing the session (depending on flush-mode, Transaction.commit() calls this method).
*
* Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.
*/
public void flush()
{
getCurrentSession().flush();
}
/*
* (non-Javadoc)
* @see gov.noaa.ncdc.cmb.persistence.dao.GenericDao#saveOrUpdate(gov.noaa.ncdc.cmb.persistence.entity.PersistentEntity)
*/
@Override
public T saveOrUpdate(final T entity)
{
try
{
entity.setUpdatedDate(new Date());
getCurrentSession().saveOrUpdate(entity);
return entity;
}
catch (Exception ex)
{
String errorMessage = "Failed to save the object.";
log.error(errorMessage, ex);
throw new RuntimeException(errorMessage, ex);
}
}
/**
* Setter for the persistentClass property.
*
* @param persistentClass
*/
public void setPersistentClass(final Class<T> persistentClass)
{
this.persistentClass = persistentClass;
}
/**
* Property setter.
*
* @param sessionFactory
*/
public void setSessionFactory(final SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
}
My application gets the DAO from the application context:
// load the Spring application context, get the DAOs
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] { "dailyAveragingApplicationContext.xml" });
esrlDailyAvgDao = (EsrlDailyAvgDao) applicationContext.getBean("esrlDailyAvgDao");
esrlObservationsDao = (EsrlObservationsDao) applicationContext.getBean("esrlObservationsDao");
And the exception is encountered when I try to save an entity:
esrlDailyAvgDao.saveOrUpdate(esrlDailyAvg);
The DAO class itself uses the Transactional annotation:
@Transactional
public class EsrlDailyAvgDaoHibernateImpl
extends GenericDaoHibernateImpl<EsrlDailyAvg, Long>
implements EsrlDailyAvgDao
The exception stack trace looks like this:
SEVERE: Failed to save the object.
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)
at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.getCurrentSession(GenericDaoHibernateImpl.java:56)
at gov.noaa.ncdc.cmb.persistence.dao.GenericDaoHibernateImpl.saveOrUpdate(GenericDaoHibernateImpl.java:187)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
at $Proxy19.saveOrUpdate(Unknown Source)
at gov.noaa.ncdc.cmb.esrl.ingest.EsrlDailyAvgProcessor.main(EsrlDailyAvgProcessor.java:469)
I resolved this by adding @Transactional
to the base/generic Hibernate DAO implementation class (the parent class which implements the saveOrUpdate() method inherited by the DAO I use in the main program), i.e. the @Transactional
needs to be specified on the actual class which implements the method. My assumption was instead that if I declared @Transactional
on the child class then it included all of the methods that were inherited by the child class. However it seems that the @Transactional
annotation only applies to methods implemented within a class and not to methods inherited by a class.
这篇关于没有Hibernate Session绑定到线程,并且配置不允许在这里创建非事务性的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!