簡體   English   中英

管理休眠會話的策略

[英]Strategy for manage Hibernate Session

我使用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&amp;characterEncoding=UTF-8&amp;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();
}

現在我可以刪除對象,但不能使用延遲加載,因為會話已為每個事務關閉。

因此,我該如何管理會議以克服這些情況!

由於您已激活屬性:

<property name="hibernate.current_session_context_class">thread</property>

為什么不使用:

public Session getSession() {
    return HibernateUtil.getSessionFactory().getCurrentSession();
}

而不是打開一個新會話? 這樣,您不必擔心關閉會話,因為在關閉sessionFactory時,Hibernate會關閉它。

但是請注意,這不是線程安全的,因此,如果您在多線程環境中工作,則不是一個好的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM