Как получить entity manager или транзакцию в прослушивателе jpa
я использовал прослушиватель событий Hibernate, как PostDeleteEventListener, PostInsertEventListener, PostUpdateEventListener
для выполнения некоторых операций во время вставки, удаления и обновления. Теперь я хотел бы использовать JPA listener для этого, потому что, если мне нравится переходить из спящего режима в любой другой поставщик JPA, мой слушатель должен работать. Hibernate слушатель дает мне event
из которого я могу получить транзакцию и проверить, совершена ли она или откат. Прослушиватели JPA предоставляют мне только объект сущности. Теперь, как я могу получить транзакцию или сеанс или Entity manger в Слушатель JPA?? Заранее спасибо!! Я использую Jboss в качестве своего CMT.
3 ответов
Это не поддерживается с JPA 2.0.
в JPA 2.1 (планируется в Java EE 7) поставщик сохраняемости будет рассматривать прослушиватели сущностей как компоненты CDI в управляемой среде (например, сервер приложений JBoss). От предлагаемый окончательный проект спецификации JPA 2.1, стр. 96:
классы прослушивателя сущностей в средах Java EE поддерживают зависимость инъекция через контексты и API инъекции зависимостей (CDI) [ 10 ] Когда содержащий архив-это бобовый архив. Сущность слушателя класс, использующий инъекцию CDI, также может определять жизненный цикл методы обратного вызова, аннотированные PostConstruct и PreDestroy комментарии. Эти методы будут вызваны после того как впрыска принимала место и перед уничтожением экземпляра прослушивателя сущности соответственно
Итак, в JPA 2.1, если вы создаете производитель CDI, который предоставляет EntityManager (просто аннотируя поле @PersistenceContext с помощью @Produces), вы можете просто @ввести EntityManager в прослушиватель.
в то же время, я не знаю ни одного чистого или приятное решение. "Наименее худшая" вещь, о которой я могу думать, - это настроить EntityManager для привязки к JNDI, а затем получить его через поиск JNDI из прослушивателя.
в моем случае я использую этот код:
ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext();
auditLogService = (AuditLogService) ctx.getBean("auditLogService");
Это хорошо работает для меня.
код этого приложения доступен для загрузки по адресуhttps://bitbucket.org/macielbombonato/apolo
Я надеюсь, что это может помочь вам.
вы можете использовать все прослушиватель pre/post load, insert, update или delete в JPA двумя способами:
-
С помощью аннотаций. Простой пример использования прослушивателя может быть, когда сущность имеет переходную переменную, которая должна быть заполнена после сохранения, обновления или загрузки сущности, например:
public class AvailableCreditListener { @PostLoad @PostPersist @PostUpdate public void calculateAvailableCredit(Account account) { account.setAvailableCredit( account.getBalance().add( account.getOverdraftLimit())); } }
класс сущности будет аннотирован @EntityListeners:
@EntityListeners({AvailableCreditListener.class}) public class Account extends BaseEntity { private BigDecimal balance; private BigDecimal overdraftLimit; @Transient private BigDecimal availableCredit; // getters and setters }
С помощью настойчивости.XML конфигурационный файл.
наконец, вместо аннотаций можно использовать и развертывать XMl-файл сопоставления с приложением для указания прослушивателей по умолчанию. (На этот файл сопоставления ссылается persistence.XML-файл.) Но сущность может использовать аннотацию @ExcludeDefaultListeners, если она не хочет использовать прослушиватели по умолчанию.
@ExcludeDefaultListeners
@Entity
public class Account extends BaseEntity {
....
}
В вашей настойчивости.XML-код:
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="samples.AvailableCreditListener"/>
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>