Жизненный цикл EntityManager при использовании виртуальной частной базы данных Oracle - PullRequest
0 голосов
/ 28 июля 2011

У меня было несколько вопросов, связанных с тем, как менеджер сущностей создается и используется в приложении в отношении Virtual Private Databases, который является функцией в Oracle DB, которая обеспечивает безопасность на уровне строк.

  1. В сессионном компоненте мы обычно имеем в качестве участника менеджер сущностей, и он обычно внедряется контейнером.Как этот диспетчер сущностей управляется контейнером - я имею в виду, если мы хотим реализовать Virtual Private Database, тогда мы должны убедиться, что Virtual Private Database -контекст остается действительным для всего сеанса пользователя, и нам не нужно устанавливатьэтот контекст каждый раз, прежде чем мы запускаем запрос.(чтобы включить больше словоблудия здесь: сессионный компонент реализует пару функций, и каждая из этих функций использует один и тот же диспетчер сущностей; теперь не должно быть случая, чтобы мы устанавливали виртуальную частную базу данных каждый раз в каждой из этих функций, которые выполняют некоторыеМанипуляции с БД).

  2. В дополнение к # 1, поскольку диспетчер сущностей кэшируется в сессионном компоненте, нужно ли явно закрывать диспетчер сущностей в любом сценарии?(как мы делаем для соединений JDBC?)

  3. Кроме того, мне было интересно, каким должен быть сценарий использования (или критерии разработки) для использования JTA или источника данных не-JTA.Зависит ли способ создания менеджера сущностей от этого?

Чтобы добавить требования к VPD: было бы неплохо, если бы EM, управляемый контейнером, каким-то образом можно было заставить применять VPD согласнопользователь.Обратите внимание, что EM вводится сюда, поэтому должен существовать механизм для установки VPD для соединения (и позднее извлекать то же соединение для «этого» пользователя в «этом» сеансе).

Без встроенного EM, я думаю, можно использовать ссылку на EMF, а затем установить свойства для EM.Что-то вроде: ((org.eclipse.persistence.internal.jpa.EntityManagerImpl) em.getDelegate ()). SetProperties

Было бы излишним, если VPD устанавливается каждый раз до запуска запроса, скореесоединение должно «поддерживать» контекст VPD во время сеанса пользователя, а затем освобождать соединение (после очистки VPD) обратно в пул.

1 Ответ

2 голосов
/ 28 июля 2011

В сессионном компоненте внедренный менеджер сущностей управляется контейнером и по умолчанию имеет объем транзакции.

Это означает, что когда вы вызываете любой метод в сессионном компоненте, и транзакция запускается, запускается контекст персистентности менеджера сущностей. Когда транзакция зафиксирована или откатана, она заканчивается. Таким образом, не существует сценария, в котором вы должны явно закрывать менеджер сущностей.

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

Сессионные компоненты с сохранением состояния имеют другую опцию, и это extended persistence context. Этот элемент связан с областью действия компонента с состоянием, а не с отдельными транзакциями. Вам все еще не нужно закрывать себя здесь.

Затем вы также можете ввести EntityManagerFactory (используя @ PersistenceUnit ), а затем получить от него менеджер сущностей: в этом случае у вас будет application managed entity manager. В этом случае вам придется явно закрыть его.

Источники данных JTA (транзакционные источники данных) по умолчанию используются с менеджерами управляемых объектов контейнеров. Контейнер позаботится обо всем здесь. не-JTA источники данных предназначены для ситуаций, когда вам нужны отдельные соединения с БД, возможно, вне какой-либо выполняемой транзакции, для которых вы можете сами установить режим автоматической фиксации, фиксации, отката и т. д.

Эти два разных типа источника данных могут быть определены в orm.xml для единицы сохраняемости. Если вы определяете персистентную единицу с источником данных, отличным от JTA, вы обычно создаете для него менеджер сущностей, используя фабрику, а затем управляете всем самостоятельно.

Обновление:

Что касается Virtual Private Database, то здесь вам, по-видимому, нужно индивидуальное соединение для каждого менеджера сущностей, но обычный способ сделать это - подключить блок персистентности к общему источнику данных. Я думаю, что здесь может понадобиться источник данных, который знает о контексте пользователя, когда запрашивается соединение.

Если вы полностью обойдете контейнер и даже в значительной степени обойдете абстракцию JPA, вы можете перейти непосредственно в Hibernate. У него есть провайдеры, которых вы можете зарегистрировать по всему миру, например DriverManagerConnectionProvider и DatasourceConnectionProvider. Если вы предоставите свои собственные реализации для них с установщиком для фактического соединения, вы можете запросить их у конкретного экземпляра диспетчера сущностей непосредственно перед его использованием, а затем установить в нем собственное соединение.

Это выполнимо, но, разумеется, немного хакерски. Надеюсь, кто-то другой может дать более «официальный» ответ. Конечно, лучше всего, если Oracle предоставит официальный плагин для, например, EclipseLink для поддержки этого. Этот документ намекает, что он делает:

TopLink / EclipseLink: поддержка фильтрации данных через их @AdditionalCriteria аннотации и XML. Это позволяет произвольный JPQL фрагмент, который будет добавлен ко всем запросам для объекта. Фрагмент может содержать параметры, которые могут быть установлены через единицу сохранения или свойства контекста во время выполнения. Oracle VPD также поддерживается, включает Проверка подлинности прокси Oracle и изолированные данные.

См. Также Как использовать EclipseLink JPA с аутентификацией Oracle Proxy .

...