管理休眠会话的策略
Posted
技术标签:
【中文标题】管理休眠会话的策略【英文标题】:Strategy for manage Hibernate Session 【发布时间】:2015-10-31 23:07:40 【问题描述】:我使用 Hibernate 开发了一个 Java Web 应用程序。这是一些代码:
hibernate.cfg.xml
<property name="hibernate.dialect">org.hibernate.dialect.mysqlDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&connectionCollation=utf8mb4_general_ci</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<!--<property name="hibernate.connection.autocommit">true</property>-->
<property name="hibernate.current_session_context_class">thread</property>
BaseDAO.class
public class BaseDAO
public Session getSession()
return HibernateUtil.getSessionFactory().openSession();
我为插入、更新、删除、查找编写了一个通用类
public class GenericDAO<T, K extends Serializable> extends BaseDAO implements IGenericDAO<T, K>
private Class<T> type;
protected Class<T> getType()
return this.type;
protected String getClassName()
return type.getName();
@SuppressWarnings("unchecked")
public GenericDAO()
Type t = getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType) t;
type = (Class<T>) pt.getActualTypeArguments()[0];
@Override
public K save(T t)
Session session = getSession();
Transaction tran = session.beginTransaction();
try
K k = (K) session.save(t);
tran.commit();
return k;
catch (Exception e)
if (tran.isActive())
tran.rollback();
System.out.println("Sql Error : " + e.getMessage());
return null;
@Override
public void saveOrUpdate(T t)
Session session = getSession();
Transaction tran = session.beginTransaction();
try
session.saveOrUpdate(t);
tran.commit();
catch (Exception e)
if (tran.isActive())
tran.rollback();
System.out.println("Sql Error : " + e.getMessage());
@Override
public void update(T t)
Session session = getSession();
Transaction tran = session.beginTransaction();
try
session.update(t);
tran.commit();
catch (Exception e)
if (tran.isActive())
tran.rollback();
System.out.println("Sql Error : " + e.getMessage());
@Override
public void delete(T t)
Session session = getSession();
Transaction tran = session.beginTransaction();
try
session.delete(t);
tran.commit();
catch (Exception e)
if (tran.isActive())
tran.rollback();
System.out.println("Sql Error : " + e.getMessage());
@Override
public void delete(K k)
Session session = getSession();
Transaction tran = session.beginTransaction();
try
T t = (T) session.get(type, k);
session.delete(t);
tran.commit();
catch (Exception e)
if (tran.isActive())
tran.rollback();
System.out.println("Sql Error : " + e.getMessage());
@SuppressWarnings("unchecked")
@Override
public T find(K id)
Session session = getSession();
Transaction tran = session.beginTransaction();
try
T t = (T) session.get(type, id);
tran.commit();
return t;
catch (Exception e)
if (tran.isActive())
tran.rollback();
System.out.println("Sql Error : " + e.getMessage());
return null;
@SuppressWarnings("unchecked")
@Override
public List<T> findAll()
Session session = getSession();
Transaction tran = session.beginTransaction();
try
Query query = session.createQuery("from " + type.getSimpleName());
List<T> list = query.list();
tran.commit();
return list;
catch (Exception e)
if (tran.isActive())
tran.rollback();
System.out.println("Sql Error : " + e.getMessage());
return new ArrayList<>();
@SuppressWarnings("unchecked")
@Override
public List<T> findAllWithOrder(String column, String orderType)
Session session = getSession();
Transaction tran = session.beginTransaction();
try
if (orderType == null && orderType.equals(""))
orderType = "ASC";
Query query = session.createQuery(
String.format("from %s order by %s %s", type.getSimpleName(),
column, orderType));
tran.commit();
return query.list();
catch (Exception e)
if (tran.isActive())
tran.rollback();
System.out.println("Sql Error : " + e.getMessage());
return new ArrayList<>();
你可以看到,我没有在每个方法之后关闭会话。此代码适用于插入、更新和查找。但是当我想删除一个对象时:
TblUser user = (TblUser)find(id);
delete(user);
这是抛出异常,因为我为此函数使用了两个会话。 然后尝试在每个方法中关闭会话:
finally
session.close();
现在我可以删除对象,但我不能使用延迟加载,因为每个事务的会话都已关闭。
那么,我该如何管理会话来克服这些情况!!!
【问题讨论】:
【参考方案1】:由于您已激活该属性:
<property name="hibernate.current_session_context_class">thread</property>
你为什么不使用:
public Session getSession()
return HibernateUtil.getSessionFactory().getCurrentSession();
而不是打开一个新会话?通过这样做,您无需担心关闭会话,因为 Hibernate 会在您关闭 sessionFactory 时关闭它。
但请注意,这不是线程安全的,因此如果您在多线程环境中工作,这不是一个好的选择。
【讨论】:
是的,我做到了。但是我在使用这个选项时不能使用延迟加载。以上是关于管理休眠会话的策略的主要内容,如果未能解决你的问题,请参考以下文章