2013-11-09 4 views
3

Я экспериментирую с Java EE 7, CDI, JPA и JSF.Как получить транзакции в метод bean bean @PostConstruct

Когда начинается webapp, я хотел бы запустить метод инициализации в моем биде CDI (отмеченном @PostConstruct), который выполняет некоторую работу с базой данных (вставляет некоторые строки и т. Д.). Для этого мне нужна транзакция, но это было не так просто, как я ожидал.

Я попытался добавить @Transactional аннотацию к моему методу, но, видимо, он работает только с EJB. Я на самом деле пытался преобразовать свой bean-компонент в EJB вместо CDI bean, но я все еще не получил транзакции для моего метода @PostConstruct. Он работал с другими методами в компоненте, но не с моим методом инициализации @PostConstruct.

Затем я прочитал о создании метода перехватчик, чтобы получить сделки с CDI фасолью:

http://eubauer.de/kingsware/2012/01/16/cdi-and-transactions-e-g-in-jboss-7-0-2/

Я тоже пытался, но не повезло. Он тоже не работает.

Как можно получить транзакции с методом инициализации @PostConstruct в компоненте CDI?

+0

Почему вы говорите что он работает только с EJB? Java EE 7 добавила поддержку '@ Transactional' для CDI, переместив транзакции в свою собственную спецификацию. –

+0

Вы правы в отношении обычных методов, но по какой-то причине он, похоже, не работает с методом инициализации '@ PostConstruct'. Казалось бы, естественное место, чтобы выполнить некоторые операции инициализации, связанные с базой данных, требующие транзакции. Может быть, есть и другой способ сделать это? – StrangeLoop

+0

Это звучит как ошибка на вашем сервере приложений. Какой сервер приложений вы используете? –

ответ

2

Видимо, кажется, что:

В @PostConstruct (как с afterPropertiesSet от InitializingBean интерфейса) нет никакого способа, чтобы гарантировать, что вся постобработка уже сделана, так что (действительно) есть не может быть Транзакций. Единственный способ гарантировать, что это работает, - использовать таблицу TransactionTemplate .

Так что единственный способ сделать что-то с базой данных от @PostConstruct это сделать что-то вроде этого:

@Service("something") 
public class Something 
{ 

    @Autowired 
    @Qualifier("transactionManager") 
    protected PlatformTransactionManager txManager; 

    @PostConstruct 
    private void init(){ 
     TransactionTemplate tmpl = new TransactionTemplate(txManager); 
     tmpl.execute(new TransactionCallbackWithoutResult() { 
      @Override 
      protected void doInTransactionWithoutResult(TransactionStatus status) { 
       //PUT YOUR CALL TO SERVICE HERE 
      } 
     }); 
    } 
} 

Примечание: аналогичные нити, но ссылки Spring Framework @Transactional on @PostConstruct method

+0

В управляемом компоненте с областью приложения с запросами '@ManagedBean (eager = true)' и сохраняется, похоже, работает с EclipseLink 2.4.2, но не Hibernate 5.2.10.Final (вызывает 'LazyInitializationException'). –

Смежные вопросы