Реализация шаблона «EntityManager-Per-Request» с помощью Spring - PullRequest
0 голосов
/ 06 мая 2019

Мы обязаны поддерживать Vaadin 7 и его JPAContainer s (устаревшие вещи, а не по выбору -.-).Мы также отказываемся от Thorntail в пользу Spring Boot (очень необходимые изменения).

Итак, я читал в документах JPAContainer, и одна вещь, которая поразила, это то, что у него есть Использование JPAContainer сHibernate раздел, в котором они пишут

Одна проблема с Hibernate заключается в том, что он предназначен для кратковременных сеансов, но время жизни менеджера сущностей обычно примерно такое же, как и у пользовательского сеанса.Проблема заключается в том, что если в сеансе или менеджере сущностей происходит ошибка, менеджер становится непригодным для использования.Это вызывает большие проблемы с долгоживущими сеансами.

И

Рекомендуемое решение - использовать шаблон EntityManager-per-Request.Настоятельно рекомендуется всегда при использовании Hibernate.

Для этого они определяют

public class LazyHibernateEntityManagerProvider implements EntityManagerProvider {
    private static ThreadLocal<EntityManager> entityManagerThreadLocal = new ThreadLocal<EntityManager>();

    ... non-static getter, static setter ...
}

, который они затем используют в фильтре сервлетов (или в каком-то переопределенном методе, ноони просто перечисляют код сервлета, вот что я копирую):

public class LazyHibernateServletFilter implements Filter {

    private EntityManagerFactory entityManagerFactory;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        entityManagerFactory = Persistence.createEntityManagerFactory("lazyhibernate");
    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain
        ) throws IOException, ServletException {
        try {
            // Create and set the entity manager
            LazyHibernateEntityManagerProvider.setCurrentEntityManager(entityManagerFactory.createEntityManager());

            // Handle the request
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            // Reset the entity manager
            LazyHibernateEntityManagerProvider.setCurrentEntityManager(null);
        }
    }

    @Override
    public void destroy() {
        entityManagerFactory = null;
    }
}

Пока все хорошо, я просто теряю счет того, кто чем управляет.И что я могу или не могу сделать без обхода Spring Transaction Manager (что я делаю , а не хочу обойти).

Итак, какой правильный шаг сделать здесь?

Могу ли я просто скопировать

entityManagerFactory = Persistence.createEntityManagerFactory("lazyhibernate")

?

Нужно ли вместо этого вводить фабрику?

Может быть, все это устарело, потому что Spring все равно делает это за кулисами??(Кажется, не могу найти никакой информации по этому поводу, поэтому я предполагаю, что это нет.)

Что-то еще полностью?(Класс конфигурации, обеспечивающий компоненты EntityManager?)

...