使用spring整合hibernate时出现错误 No Session found for current thread
BaseDAO接口的实现代码
package common.dao.impl;
import java.io.Serializable;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import common.dao.BaseDao;
public class BaseDaoImpl<T> implements BaseDao<T>
{
// DAO组件进行持久化操作底层依赖的SessionFactory组件
private SessionFactory sessionFactory;
// 依赖注入SessionFactory所需的setter方法
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
public SessionFactory getSessionFactory()
{
return this.sessionFactory;
}
// 根据ID加载实体
@SuppressWarnings("unchecked")
public T get(Class<T> entityClazz , Serializable id)
{
return (T)getSessionFactory().getCurrentSession()
.get(entityClazz , id);
}
// 保存实体
public Serializable save(T entity)
{
return getSessionFactory().getCurrentSession()
.save(entity);
}
// 更新实体
public void update(T entity)
{
getSessionFactory().getCurrentSession().saveOrUpdate(entity);
}
// 删除实体
public void delete(T entity)
{
getSessionFactory().getCurrentSession().delete(entity);
}
// 根据ID删除实体
public void delete(Class<T> entityClazz , Serializable id)
{
getSessionFactory().getCurrentSession()
.createQuery("delete " + entityClazz.getSimpleName()
+ " en where en.id = ?0")
.setParameter("0" , id)
.executeUpdate();
}
// 获取所有实体
public List<T> findAll(Class<T> entityClazz)
{
return find("select en from "
+ entityClazz.getSimpleName() + " en");
}
// 获取实体总数
public long findCount(Class<T> entityClazz)
{
List<?> l = find("select count(*) from "
+ entityClazz.getSimpleName());
// 返回查询得到的实体总数
if (l != null && l.size() == 1 )
{
return (Long)l.get(0);
}
return 0;
}
// 根据HQL语句查询实体
@SuppressWarnings("unchecked")
protected List<T> find(String hql)
{
return (List<T>)getSessionFactory().getCurrentSession()
.createQuery(hql)
.list();
}
// 根据带占位符参数HQL语句查询实体
@SuppressWarnings("unchecked")
protected List<T> find(String hql , Object... params)
{
// 创建查询
Query query = getSessionFactory().getCurrentSession()
.createQuery(hql);
// 为包含占位符的HQL语句设置参数
for(int i = 0 , len = params.length ; i < len ; i++)
{
query.setParameter(i + "" , params[i]);
}
return (List<T>)query.list();
}
/**
* 使用hql 语句进行分页查询操作
* @param hql 需要查询的hql语句
* @param pageNo 查询第pageNo页的记录
* @param pageSize 每页需要显示的记录数
* @return 当前页的所有记录
*/
@SuppressWarnings("unchecked")
protected List<T> findByPage(String hql,
int pageNo, int pageSize)
{
// 创建查询
return getSessionFactory().getCurrentSession()
.createQuery(hql)
// 执行分页
.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize)
.list();
}
/**
* 使用hql 语句进行分页查询操作
* @param hql 需要查询的hql语句
* @param params 如果hql带占位符参数,params用于传入占位符参数
* @param pageNo 查询第pageNo页的记录
* @param pageSize 每页需要显示的记录数
* @return 当前页的所有记录
*/
@SuppressWarnings("unchecked")
protected List<T> findByPage(String hql , int pageNo, int pageSize
, Object... params)
{
// 创建查询
Query query = getSessionFactory().getCurrentSession()
.createQuery(hql);
// 为包含占位符的HQL语句设置参数
for(int i = 0 , len = params.length ; i < len ; i++)
{
query.setParameter(i + "" , params[i]);
}
// 执行分页,并返回查询结果
return query.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize)
.list();
}
}
下面是实体代码
package domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="tb_news")
public class News {
@Id @Column(name="news_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String name;
private String titel;
private String neirong;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitel() {
return titel;
}
public void setTitel(String titel) {
this.titel = titel;
}
public String getNeirong() {
return neirong;
}
public void setNeirong(String neirong) {
this.neirong = neirong;
}
public News(String name, String titel, String neirong) {
super();
this.name = name;
this.titel = titel;
this.neirong = neirong;
}
public News() {
super();
// TODO Auto-generated constructor stub
}
}
然后继承BaseDAO接口
package domain;
import common.dao.BaseDao;
public interface NewsDao extends BaseDao<News> {
}
package domain.impl;
import common.dao.impl.BaseDaoImpl;
import domain.News;
import domain.NewsDao;
public class NewsDaoImpl extends BaseDaoImpl<News> implements NewsDao{
}
beans.xml配置代码
<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 配置名为person的Bean,其实现类是org.crazyit.app.service.Person类 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:configLocation="classpath:hibernate.cfg.xml"/>
<bean id="newsDao" class="domain.impl.NewsDaoImpl"
p:sessionFactory-ref="sessionFactory"/>
</beans>
hiberntae.cfg.xml中的代码
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--
指定数据库方言,更好的操作数据库
MySQL5.5之前使用org.hibernate.dialect.MySQLInnoDBDialect
MySQL5.5之后使用org.hibernate.dialect.MySQL5InnoDBDialect
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- 驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 数据库URL -->
<property name="hibernate.connection.url">jdbc:mysql:///try_db</property>
<!-- 用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 密码 -->
<property name="hibernate.connection.password">root</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="hibernate.format_sql true">true</property>
<mapping class="domain.News"/>
</session-factory>
</hibernate-configuration>
最后向数据库中写入数据是出现错误,谁能帮忙解答一下到底是那个地方的错误呢?
public class Save {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
NewsDao nd = ac.getBean("newsDao", NewsDao.class);
nd.save(new News("孙悟空", "大闹天宫", "打仗"));
}
}
错误如下
Exception in thread "main" org.hibernate.HibernateException:No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at common.dao.impl.BaseDaoImpl.find(BaseDaoImpl.java:80)
at common.dao.impl.BaseDaoImpl.findAll(BaseDaoImpl.java:59)
at Main.Save.main(Save.java:18)
------解决思路----------------------
这应该是hibernate联合spring时CurrentSessionContext具体实现问题,应该是要在hibernate配置文件加这样一句话:<property name="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</property>
以前我遇到过一次,但我在hibernate配置文件加这句后又报另一个错误(具体什么错误忘了);然后就没用hibernate配置文件,直接在spring的配置文件配置hibernate配置属性,同样加上这个属性
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
问题解决
------解决思路----------------------
你这样的配置我没见过 错误没有遇到过
但是我看到的是 spring中没有配置事物管理transactionManager
希望你能解决 分享一下。
------解决思路----------------------
我也是菜鸟,水平有限,openSession相比getCurrentSession每次都获取新的session,而且不和线程绑定,还得手动关闭,所以很少用。我觉得的话如果你的数据库操作没问题,应该还是事务的问题,我也是菜鸟,水平有限,说错了包涵