java ee 7 @Transactional в методе сервлета

У меня есть сервлет java ee 7 с аннотацией webservlet. Я пометил один из методов сервлета как @Transactional. Диспетчер сущностей также предоставляется сервлету с контекстом постоянства.

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

Этот метод вызывается из сервлета при обработке HTTP-запроса. Glassfish4 выдает исключение о том, что транзакция недоступна.

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

Я внедрил этот объект в сервлет и вызвал метод из сервлета, и все работает нормально. em вводится в компонент CDI, транзакция инициируется, и em.persist работает нормально.

Означает ли это, что объект сервлета не может иметь аннотацию @Transactional в своих методах?


person user2980548    schedule 11.11.2013    source источник
comment
Я не уверен, может быть, сервлеты нельзя проксировать.   -  person Amir Pashazadeh    schedule 12.11.2013
comment
Правильно, более-менее. Transactional определен для использования CDI и EJB. я не думаю, что это будет работать с управляемыми компонентами Faces, сервлетами и т. д.   -  person John Ament    schedule 12.11.2013


Ответы (2)


Мне удалось заставить @Transactional работать с @WebServlet и CDI на Wildfly 10, но только когда @Transactional установлено на уровне класса. Он не работает, когда он установлен на уровне метода.

Итак, следующий пример работает нормально:

@Transactional
@WebServlet("/transactional")
public class TransactionalServlet extends HttpServlet
{
   /** The entity Manager */
   @Inject
   @AppStoreDatabase
   private EntityManager m_entityManager;

   @Override
   public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException
   {
      final Person person = new Person();
      person.setFirstName("FirstName");
      person.setLastName("LastName");

      m_entityManager.persist(person);

      response.getWriter().println("OK");
   }
}

При аннотировании только метод НЕ работает:

   @Transactional // Throws a TransactionRequiredException!
   @Override
   public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException
   {
      final Person person = new Person();
      person.setFirstName("FirstName");
      person.setLastName("LastName");

      m_entityManager.persist(person);

      response.getWriter().println("OK");
   }

Я буду исследовать.

person Rouliboy    schedule 06.01.2018
comment
Тот же результат с TomEE plume 7.0.4 с использованием компонента CDI в области сеанса в приложении JSF. - person Panu Haaramo; 10.01.2018

Я пробовал это с шлейфом TomEE 7.0.4. Он не выдает исключение, но в моих тестах не было ни фиксации, ни отката.

Вывод таков, что @Transactional не работает в @WebServlet.

Изменить: в этих тестах @Transactional находился на уровне метода. Кажется, это работает на уровне класса, см. ответ @Rouliboy.

person Panu Haaramo    schedule 03.01.2018
comment
Относительно javadoc The javax.transaction.Transactional annotation provides the application the ability to declaratively control transaction boundaries об управляемых компонентах CDI, а также о классах, определенных как управляемые компоненты в спецификации Java EE. Так что это должно работать на @WebServlet, поскольку это управляемый компонент. Я попробую на wildfly и weblogic. - person Rouliboy; 04.01.2018
comment
Связано: это также не работает с компонентами CDI, управляемыми JSF, в TomEE 7. Сообщите нам, если вы увидите другие результаты. - person Panu Haaramo; 04.01.2018
comment
Я протестировал его на Wildfly, и он работает, когда @Transactional установлен на уровне класса. Он не работает, когда он установлен на уровне метода. - person Rouliboy; 06.01.2018