Проблема с EJB + POJO Helpers + EntitiyManager

Я работаю с EJB... Я делаю следующее и не знаю, почему введенный EntityManager не работает так, как можно было бы ожидать.

  1. EJB1 вызывает метод EJB2, который записывает данные в БД.
  2. когда EJB2 возвращает значение, EJB1 отправляет сообщение в MDB.
  3. MDB вызывает EJB3, который читает БД и выполняет некоторую работу.

Моя проблема в том, что EntityManager, введенный во все 3 EJB с @PersistenceContext, не работает должным образом. Вызов persist() в EJB2 не отражается на EntityManager, внедренном в EJB3. Что может быть не так? Надеюсь, я достаточно ясно изложил свою проблему. теперь работает с транзакциями, управляемыми контейнером.


person nico    schedule 04.11.2010    source источник
comment
Это использует JPA правильно? Я не очень хорошо знаком с JPA, но подозреваю, что каждый EJB получает отдельный экземпляр EntityManager. Когда вы вызываете persist, вы уверены, что объект не кэшируется и что он фиксируется в базе данных? Даже если объект зафиксирован в базе данных, он может не отображаться в другом экземпляре EntityManager, если вы не очистите его кеш и не перезагрузите все объекты.   -  person jthg    schedule 04.11.2010
comment
да, используя JPA. Не должно быть новых экземпляров EntityManager. Внедрение с использованием @PersistenceContext повторно использует тот же объект EntityManager, жизненный цикл которого управляется контейнером. Ну, я верю в то, что происходит, я не уверен на 100%.   -  person nico    schedule 04.11.2010
comment
Разве у каждого EJB нет собственного файла persistence.xml? Если да, то не означает ли это, что каждый компонент EJB должен иметь собственный экземпляр EntityManager?   -  person jthg    schedule 04.11.2010
comment
извините, я считаю, что это неправильно   -  person nico    schedule 04.11.2010


Ответы (1)


Моя проблема в том, что EntityManager, введенный во все 3 EJB с @PersistenceContext, не работает должным образом. Вызов persist() в EJB2 не отражается на EntityManager, внедренном в EJB3.

В среде Java EE обычным случаем является использование менеджера сущностей, управляемого контейнером, с областью действия транзакции. И с таким диспетчером сущностей контекст персистентности распространяется по мере распространения транзакции JTA.

В вашем случае я подозреваю, что вы используете атрибут транзакции REQUIRES_NEW для метода EJB3. Так:

  • при вызове EJB3#bar() контейнер приостановит транзакцию, начатую для EJB2#foo(), и запустит новую транзакцию
  • при вызове диспетчера сущностей из EJB3#bar() будет создан новый контекст сохраняемости.
  • поскольку транзакция, начатая для EJB2#foo(), еще не зафиксирована, изменения не "видимы" для нового контекста сохраняемости.

PS: Вы действительно создаете новые темы? Если да, небольшое напоминание: это запрещено спецификацией EJB.

person Pascal Thivent    schedule 08.11.2010
comment
Спасибо за ответ. собираюсь изучить это. о потоках ... только что изменил эту бизнес-логику на MDB, избегая новых потоков ... но проблема сохраняется. - person nico; 08.11.2010
comment
@nico Как уже говорилось, могут помочь некоторые подробности об атрибутах транзакций различных методов EJB. - person Pascal Thivent; 08.11.2010
comment
Я думаю, что тип SUPPORTS может подойти для моего случая. но я думаю, что при изменении атрибута не происходит никакого эффекта. Может быть, это потому, что у меня есть JDBCTransactionFactory, установленный в xml конфигурации гибернации? я должен изменить его на CMTTransactionFactory? - person nico; 08.11.2010
comment
@nico Ну, я думаю, вы должны упомянуть все важные детали, такие как эта ... И да, я бы использовал CMTTransactionFactory в контексте Java EE. - person Pascal Thivent; 08.11.2010
comment
Извини за это. Я новичок в платформе java EE, и я открываю ее на ходу. вернемся к проблеме... я установил CMTTransactionFactory, и атрибуты работают. но я не могу заставить entitymanager в MDB быть согласованным с entityManager, используемым для записи в БД на EJB без статистики, который также отправляет сообщение jms по тому же бизнес-методу. - person nico; 09.11.2010
comment
@nico Да, но MDB использует сообщение в другой транзакции. - person Pascal Thivent; 09.11.2010
comment
@Pascal Да, это кажется более вероятным ... поскольку это асинхронно, было бы неправильно распространять транзакцию. глупый я. Я собираюсь попробовать рефакторинг и сделать вызовы из EJB1 в EJB2 и отправить сообщение разными методами, чтобы принудительно зафиксировать транзакцию записи в БД. - person nico; 09.11.2010