用hibernate,dao,服务和工作单元重构一个dal:如何把所有的东西都放在一边

时间:2011-10-19 09:27:26

标签: java hibernate design-patterns refactoring

我正在重构一个使用hibernate和dao模式的jsf web应用程序dal,目前每个数据访问类都将自己的会话和事务处理到每个方法中(每个操作的会话反模式是什么?) 例如:

public void saveEntity(ModelEntity entity) throws Exception {
    String entityName = getCleanClassName(entity.getClass());
    Session session = null;
    Transaction tx = null;
    try {
        session = SessionFactoryUtil.getInstance().openSession();
        tx = session.beginTransaction();
        session.saveOrUpdate(entity);
        session.flush();
        tx.commit();
    } catch (Exception ex) {
        tx.rollback();
                    ...
        throw new Exception(msg, ex);
    } finally {
        session.close();
    }
}

上面的类可以直接用于支持bean操作或通过一些业务逻辑类方法(例如创建新的分离对象,设置一些值并将它们存储在DAO对象中)。现在我发现一些业务逻辑类方法需要以原子方式执行,例如:

                       //inside some backing bean actionlistener
        DocumentoManager dm = new DocumentoManager();
        PraticaManager pm = new PraticaManager();
        Documento newDoc = new Documento();
        newDoc.setDataArrivo(new java.util.Date                           newDoc.setNote("...");
        Allegato newAll = new Allegato();
        newAll.setTitolo(newDoc.getNote());
                       //businness logic methods that should be executed atomically
        dm.creaDocumentoDaAllegato(newDoc,newAll,
            event.getFile().getContents(),
            event.getFile().getFileName(),
            "");
        pm.collegaDocumento(pratica, newDoc);

最后我有一个sessionFactoryUtil类来管理hibernate会话(getcurrentSession,openSession等等)。

我如何重构上述架构?我正在考虑做以下事情:

  1. 从DAO对象中删除事务:我无法放入 事务管理到bl类(xxxManager),所以我应该 使用只创建,提交或回滚事务的类, 封装sessionFactoryUtil,并在内部使用 豆(比如jta userTransaction)?
  2. 如果有人尝试直接使用DAO对象,我该如何设置会话?访问sessionFactoryUtil到DAOs方法?
  3. 在DAO中调用getCurrentSession是否安全?
  4. 如果我创建一个类来处理业务逻辑事务,我怎么能确定它的线程安全呢?
  5. 我认为sessionFactoryUtil是线程安全的,因为它是按照hibernate指南中建议的模式编写的:

    private SessionFactoryUtil() {
    }
    
    static {
        // Annotation and XML
        // sessionFactory = new
        // AnnotationConfiguration().configure().buildSessionFactory();
        // XML only
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Exception e) {
                      ...
        }
    
    }
    
    public static SessionFactory getInstance() {
        try{
            return sessionFactory;
        } catch (Exception ex)
        {
            return null;
        }
    }
    

1 个答案:

答案 0 :(得分:1)

交易不应该是DAO的一部分。这些应该由管理DAO,模型对象和事务的服务层来处理,以实现用例。服务层拥有并管理工作单元。

DAO应仅限于持久性。他们不需要了解会话。让服务为DAO提供持久化对象所需的内容。