2013-03-01 2 views
1

Поддерживает ли JPA дополнительные единицы измерения продолжительности и, если да, как это настроить?Опциональный блок сохранения в JPA (при использовании нескольких единиц хранения)

У меня есть одна единица сохранения, которая является моей основной базой данных.

Затем я настроил еще один, где я только что прочитал объекты из базы данных, чтобы выполнить некоторые проверки. Чтобы избежать беспорядка с транзакциями в нескольких источниках данных, я устанавливаю второй источник данных jta="false".

Но мне нравится проверять, был ли вообще определен второй источник данных и использовать его только в том случае, если он есть. Если он не определен, я бы просто пропустил мои проверки.

Проблема в том, что я не могу найти способ сделать это необязательным. Если второй источник данных не настроен я получаю сообщение об ошибке New missing/unsatisfied dependencies от сканера развертывания в Jboss при развертывании моя война:

service jboss.naming.context.java.secondDatasource (missing) dependents: [service jboss.persistenceunit."de.my.war#secondDatasource"] 

(BTW: Я использую JBoss 7.1.0 и настроил источники данных в standard.xml - если эта информация имеет какое-либо значение.)

Любые подсказки?

ответ

3

Я не уверен, что это возможно с конфигурацией XML, которая в основном является соглашением о том, как JPA следует использовать в большинстве случаев. Попытайтесь найти программный подход.

Возможно, вы могли бы программно искать источник данных в качестве ресурса JNDI, и если он найден, вы могли бы build an EntityManager самостоятельно. С помощью CDI это может быть даже не так сложно, как вы думаете.

@Produces 
@MyAlterNativeEntityManager 
public EntityManager getEntityManager { 
    EntityManager entityManager = null; 
    if(jndiLookupMySecondDatasource()){ 
     entityManager = buildEntityManagerProgrammatically(...); 
    } 
    return entityManager; 
} 

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

+0

спасибо за идею. Я думаю, что это уже происходит, когда обрабатывается мой 'persistence.xml'. Но я проверю это ... – Jens

+0

Конечно, но так вы даже не должны объявлять второй источник данных в 'persistence.xml'! –

+0

@ Balzás Mária Németh: Извините за мой отложенный ответ на этот вопрос. Я попробовал ваше решение о создании «EntityManager» самостоятельно, если через JNDI найден «источник данных». Но: я не знаю, как установить найденный «источник данных» на моем самосоздаваемом «EntityManager» или. 'EntityManagerFactory'. Он принимает только свойства, чтобы их создать. Но у меня есть 'datasouce' под рукой. Я думал о том, чтобы отображать все необходимые свойства самостоятельно, но пароль - это то, что я не могу найти в 'datasource'. Есть ли способ позволить созданному 'EntityManager' использовать мой' datasource'? – Jens

1

В стандарте JPA:

  • Каждый EntityManagerFactory (ЭДС) должна относиться к одному PersistentUnit (PU) - не представляется возможным, чтобы иметь несколько PersistenceUnits, ни нулевых PersistenceUnits.
  • Каждый экземпляр EntityManager (EM) создается из EMF и поэтому также имеет один PU. Конечно, можно создать несколько EM из EMF, используя один и тот же PU.
  • Можно настроить, какие PU использовать явно против каждого EMF с помощью жесткого кодирования

    EntityManagerFactory эдс = Persistence.createEntityManagerFactory ("EmployeeService");

    или путем инъекции ЭДС с использованием аннотаций

    @PersistenceUnit ("EmployeeService") EntityManagerFactory эдс;

    или может оставить его пустым и просто выбрать PU по умолчанию, как указано в файле persistence.xml.

  • Может настроить, какой PU использовать явно против каждого EM, введя EM, используя аннотации.Здесь код вообще не относится к ЭМП (позволяя контейнеру ссылаться на ЭДС незаметно)

    @PersistenceContext (unitName = "EmployeeService") EntityManager em;

В целом, идея необязательных PU не имеет никакого смысла. Если вы используете JPA EM, вы должны зафиксировать PU.

Варианты:

  1. Редактировать persistence.xml иметь тот же логический блок живучесть «переключатель» между двумя различными экземплярами физических баз данных. Не соответствует полным требованиям - по-прежнему будут считывать значения из альтернативного источника данных.
  2. Поиск/вставка переменной среды («отладка» или нет) и программным образом перемещаться между различными источниками данных в соответствии с решением Balazs Maria Nemeth. Не соответствует полным требованиям, поскольку он все равно будет считывать значения из альтернативного источника данных.
  3. Поиск/ввод переменной среды («отладка» или нет) и запуск/исключение кода для вашей альтернативной ЭМ надлежащим образом.

3 - это только вариант, который отвечает всем требованиям. Например .:

// Inject environment setting. Resource annotation works with/without CDI - 
// just doesn't give scoping support, which isn't required here. 
@Resource boolean debugMode; 

if (debugMode) { 
    @PersistenceContext(unitName="DebugPersistenceUnit") 
    EntityManager debugEM; 

    Employee emp = debugEM.find(Employee.class, empId); 
} 

Затем в web.xml или ejb.xml включают ENV-запись:

<env-entry> 
    <description> 
    Only set this true in a debugging environment 
    </description> 
    <env-entry-name>debugMode</env-entry-name> 
    <env-entry-type>java.lang.Boolean</env-entry-type> 
    <env-entry-value>true</env-entry-value> 
</env-entry> 
Смежные вопросы