почему Spring ORM JpaTransactionManager использует собственную фабрику менеджеров сущностей? - PullRequest
0 голосов
/ 30 августа 2018

Есть ли какая-либо конкретная причина при создании jps-транзакции менеджера сущностей с использованием собственного объекта?

   EntityManagerFactory emf = this.getEntityManagerFactory();
   if (emf instanceof EntityManagerFactoryInfo) {
            emf = 
           ((EntityManagerFactoryInfo)emf).getNativeEntityManagerFactory();
   }

Наше требование состоит в том, чтобы использовать прокси (Создан) вместо нативного объекта. Мы создали аспект вокруг метода getSession для динамического добавления идентификатора клиента (столбца дискриминатора) для запроса

Спасибо, Вишну

1 Ответ

0 голосов
/ 30 августа 2018

Объяснение к точке:

Причина, по которой нативный EntityManagerFactory развернут в JpaTransactionManager createEntityManagerForTransaction () , заключается в том, что при использовании прокси впоследствии будет создан расширенный EntityManager. один в области транзакций один. Последний - тот, который нам нужен в случае обычных транзакционных сеансов.

Что бы произошло, если бы мы все еще использовали прокси:

Поскольку прокси-сервер делегирует все вызовы ManagedEntityManagerFactoryInvocationHandler , вызов createEntityManager () , из которого мы надеемся получить менеджер сущностей в области транзакций, также будет делегирован.
Если мы посмотрим на реализацию вышеупомянутого метода invoke () , то увидим, что он вызывает invokeProxyMethod () из AbstractEntityManagerFactoryBean , где мы видим, что он в частности, инициирует создание расширенного диспетчера транзакций вместо одного в области транзакций. Это, вероятно, просто дизайнерский выбор разработчиков Spring.

Object invokeProxyMethod(Method method, @Nullable Object[] args) throws Throwable {
    // unrelated code here
    if (method.getName().equals("createEntityManager") && args != null && args.length > 0 &&
            args[0] == SynchronizationType.SYNCHRONIZED) {
        EntityManager rawEntityManager = (args.length > 1 ?
                getNativeEntityManagerFactory().createEntityManager((Map<?, ?>) args[1]) :
                getNativeEntityManagerFactory().createEntityManager());
        // we get an extended entity manager
        return ExtendedEntityManagerCreator.createApplicationManagedEntityManager(rawEntityManager, this, true);
    }
    // more unrelated code here
    Object retVal = method.invoke(getNativeEntityManagerFactory(), args);
    if (retVal instanceof EntityManager) {
        EntityManager rawEntityManager = (EntityManager) retVal;
        retVal = ExtendedEntityManagerCreator.createApplicationManagedEntityManager(rawEntityManager, this, false);
    }
    // in the final path, we also get an extended entity manager
    return retVal;
}

Некоторые пути, по которым я хотел бы обойти вашу проблему:

Вы можете попытаться создать подкласс JpaTransactionManager и переопределить createEntityManagerForTransaction () с минимальными изменениями, которые будут учитывать упомянутое вами использование аспектов позже. Однако простое не развертывание прокси EntityManagerFactory, вероятно, не будет тем, что вы намереваетесь, из-за приведенного выше объяснения, относящегося к расширенным менеджерам сущностей.

Еще одна вещь, которую вы, возможно, захотите рассмотреть, - это изменение аспектов, о которых вы упомянули, чтобы они не требовали использования прокси-сервера entityManagerFactory в Spring и хорошо работали с нативным объектом. В качестве последнего средства вы можете попытаться создать подкласс и переопределить методы нескольких классов ORM Spring, упомянутые в этом решении, чтобы вы могли учесть как поведение Spring, так и ваши аспекты.

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