Java 对于hibernate来说,紧凑的反模式、基于分离标准的DAO实用程序有多危险?

Java 对于hibernate来说,紧凑的反模式、基于分离标准的DAO实用程序有多危险?,java,hibernate,dao,utilities,detachedcriteria,Java,Hibernate,Dao,Utilities,Detachedcriteria,很久以前,我使用DetachedCriteria创建了一个单类hibernate util,以简化我在非常小的应用程序上的工作,如下所示: import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibe

很久以前,我使用DetachedCriteria创建了一个单类hibernate util,以简化我在非常小的应用程序上的工作,如下所示:

import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.DetachedCriteria;

/* WARNING: This utility was projected only for applications of one operation per use per mapping!
Using it for multiple operations characterizes the anti-pattern "session-per-operation". */
public class HibernateUtil {
    private static final int SEARCH = 0;
    private static final int LIST = 1;
    private static final int SAVE = 2;
    private static final int UPDATE = 3;
    private static final int SAVE_OR_UPDATE = 4;
    private static final int DELETE = 5;
    private static final int MERGE = 6;
    private static SessionFactory SESSION_FACTORY;

    // Single session factory instantiation
    static {SESSION_FACTORY = new Configuration().configure().buildSessionFactory();}

    // Opens the session and executes only one operation on the transaction
    private static Object executeTransaction(Object object, int operation) {
        Object output = null;
        Session session = SESSION_FACTORY.openSession();
        Transaction transaction = null;
        try {
            transaction = session.beginTransaction();
            switch (operation) {
                case SEARCH: output = ((DetachedCriteria) object).getExecutableCriteria(session).uniqueResult(); break;
                case LIST: output = ((DetachedCriteria) object).getExecutableCriteria(session).list(); break;
                case SAVE: session.save(object); break;
                case UPDATE: session.update(object); break;
                case SAVE_OR_UPDATE: session.saveOrUpdate(object); break;
                case DELETE: session.delete(object); break;
                case MERGE: session.merge(object); break;
                default: throw new HibernateException("No operation was executed on the database.");
            }
            transaction.commit();
        } finally {
            session.close();
        }
        return output;
    }

    // Usable methods, named accordingly to the operation:
    public static Object searchCriteria(DetachedCriteria criteria) {return executeTransaction(criteria, SEARCH);}
    public static List<?> listCriteria(DetachedCriteria criteria) {return (List<?>) executeTransaction(criteria, LIST);}
    public static void save(Object object) {executeTransaction(object, SAVE);}
    public static void update(Object object) {executeTransaction(object, UPDATE);}
    public static void saveOrUpdate(Object object) {executeTransaction(object, SAVE_OR_UPDATE);}
    public static void delete(Object object) {executeTransaction(object, DELETE);}
    public static void merge(Object object) {executeTransaction(object, MERGE);}
}
import java.util.List;
导入org.hibernate.hibernateeexception;
导入org.hibernate.Session;
导入org.hibernate.SessionFactory;
导入org.hibernate.Transaction;
导入org.hibernate.cfg.Configuration;
导入org.hibernate.criteria.DetachedCriteria;
/*警告:此实用程序仅适用于每个映射每次使用一个操作的应用程序!
将其用于多个操作是反模式“每个操作会话”的特点*/
公共类HibernateUtil{
私有静态最终整数搜索=0;
私有静态最终整数列表=1;
私有静态最终整数保存=2;
私有静态最终整数更新=3;
私有静态最终整数保存或更新=4;
私有静态最终整数删除=5;
私有静态最终整数合并=6;
私有静态会话工厂会话工厂;
//单会话工厂实例化
静态{SESSION_FACTORY=new Configuration().configure().buildSessionFactory();}
//打开会话并仅对事务执行一个操作
私有静态对象executeTransaction(对象对象,int操作){
对象输出=null;
Session Session=Session_FACTORY.openSession();
事务=空;
试一试{
事务=session.beginTransaction();
开关(操作){
案例搜索:输出=((DetachedCriteria)对象).getExecutableCriteria(会话).uniqueResult();中断;
案例列表:输出=((DetachedCriteria)对象).getExecutableCriteria(会话).LIST();中断;
案例保存:会话。保存(对象);中断;
案例更新:会话更新(对象);中断;
案例保存或更新:session.saveOrUpdate(对象);break;
案例删除:会话。删除(对象);中断;
案例合并:session.MERGE(对象);break;
默认值:抛出新的HibernateException(“没有对数据库执行任何操作”);
}
commit();
}最后{
session.close();
}
返回输出;
}
//可用方法,根据操作命名:
公共静态对象搜索条件(DetachedCriteria条件){返回executeTransaction(条件,搜索);}
公共静态列表listCriteria(DetachedCriteria条件){return(List)executeTransaction(criteria,List);}
公共静态无效保存(对象对象){executeTransaction(对象,保存);}
公共静态无效更新(对象对象){executeTransaction(对象,更新);}
公共静态无效保存或更新(对象对象){executeTransaction(对象、保存或更新);}
公共静态void delete(对象对象){executeTransaction(对象,删除);}
公共静态无效合并(对象对象){executeTransaction(对象,合并);}
}
这允许我通过调用
HibernateUtil.searchCriteria()/listCriteria()/save()/update()/saveOrUpdate()/delete()/merge()
,与数据库进行交互,但实际上我在非常罕见的情况下(小型应用程序)使用它,因为它的会话取决于操作的性质

问题是,我刚刚发现我的同事们已经在更大的应用程序中使用了它,使用了正确的DAO模式。是我的错。我担心可能的副作用,如开销或过载,但我不知道我应该担心什么问题。对于我来说,在他们的应用程序中重新设计DAO的风险是否足够大

你们中一些更有经验的程序员或DBA可以和我分享一些信息吗?非常感谢

编辑


将其更改为关闭会话。为了避免延迟初始化错误,我现在要做的是在hbm.xml中的每个多对一映射中设置
lazy=“false”

我认为您应该担心的主要问题是事务完整性。我敢打赌,您会发现许多用例,其中几个safe/update/saveOrUpdate/delete操作应该在一个事务中,但由于这个helper类,每个操作都是在自己的事务中完成的

另一个问题是使用这个helper类会强制使用两个会话工厂而不是一个,因为这个helper类使用它自己的私有会话工厂

我将删除这个类,使用Spring或EJB进行声明性事务管理,并使用session per transaction模式或open session in view模式,这两种模式都确保会话在某个时间关闭