рефакторинг дал с гибернацией, дао, сервисами и единицей работы: как поставить все вместе - PullRequest
0 голосов
/ 19 октября 2011

Я занимаюсь рефакторингом jsf-веб-приложения dal, которое использует hibernate и шаблон dao, в настоящий момент каждый класс доступа к данным обрабатывает свой собственный сеанс и транзакцию в каждом методе (например, сеанс для каждой операции antipattern?), Например:

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

Указанные выше классы можно использовать непосредственно в действиях компонента поддержки или с помощью некоторых методов классов бизнес-логики (например, создать новый отдельный объект, задать некоторые значения и сохранить их через объекты 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, который управляет сеансом гибернации (getcurrentSession, openSession и т. Д.).

Как я могу провести рефакторинг вышеуказанной архитектуры?я думал сделать следующее:

  1. удалить транзакцию из объектов DAO: я не могу поместить управление транзакциями в классы bl (xxxManager), поэтому я должен использовать класс, который просто создает, фиксируетили откатить транзакцию, инкапсулируя sessionFactoryUtil, и использовать ее в бинах (например, jta userTransaction)?
  2. Если кто-то попытается использовать объект DAO напрямую, как мне установить сеанс?Доступ к sessionFactoryUtil к методам DAOs?
  3. Безопасно ли вызывать getCurrentSession внутри DAOs?
  4. если я создаю класс для обработки логических транзакций бизнеса, как я могу быть уверен, что он безопасен для потоков?

Я думаю, что sessionFactoryUtil является потокобезопасным, поскольку он написан по образцу, предложенному в руководстве по гибернации:

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 Ответ

1 голос
/ 19 октября 2011

Транзакции не должны быть частью DAO. Они должны обрабатываться сервисным уровнем, который управляет DAO, модельными объектами и транзакциями для выполнения вариантов использования. Сервисный уровень владеет и управляет единицей работы.

DAO должны быть только о постоянстве. Им не нужно ничего знать о сессиях. Позвольте службе дать DAO все, что нужно для сохранения объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...