简体   繁体   中英

Strategy for manage Hibernate Session

I develop a java web app using Hibernate. Here are some code :

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();
}

}

I write a generic class for insert, update, delete, find

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<>();
}
}

You can see, I don't close session after each method. This code work fine for insert, update and find . But when I want to delete a object :

TblUser user = (TblUser)find(id);
delete(user);

It's throw exception because I use two session for this function. Then try to close session in each method :

finally{
   session.close();
}

Now I can delete object but I can't use lazy load because session has closed for each transaction.

So, how I can manage session to overcome these situation !!!

Since you have activated the property:

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

why don't you use:

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

Instead of opening a new session? By doing this, you don't need to worry about closing your session since Hibernate will close it when you close your sessionFactory.

But be aware that this is not thread safe so if you are working in a multi-thread environment, this is not a good option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM