Методы @Transactional в классе @Controller не рассматриваются как транзакционные

Я заметил, что следующее не работает в классе, помеченном как @Controller:

@Autowired
SessionFactory sessionFactory;

@ResponseBody
@Transactional
@RequestMapping(method = RequestMethod.GET , value = "/map")

public ArrayList<PhotoDTO> getPhotos(...someParams) {
   Entity result sessionFactory.getCurrentSession()... //do some manipulation

  return result;
}

когда я вызываю URL-адрес, я получаю сообщение о том, что метод не является транзакционным (хотя, как видите, он помечен как один)

Если я скопирую этот метод в другой класс под названием MyService и вызову его из контроллера, он отлично работает

Это какой-то совет Spring (заговор, чтобы заставить меня использовать больше классов более или менее)?

Ответ 1

Не делайте транзакций в своем контроллере. Поместите их в классы уровня обслуживания.

Отделите свой код в контроллере модели.

Да, это заговор. Он позволяет вам совместно использовать код между контроллерами/представлениями без повторения кода. А также отменяет откаты транзакций без необходимости (для исключений, не связанных с фактической транзакцией).

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

Ответ 2

Вероятно, здесь есть два контекста приложения: основной Spring контекст, загруженный ContextLoaderListener, и дочерний контекст, загруженный DispatcherServlet. Вы должны поместить <tx:annotation-driven /> в конфигурацию, загруженную детским контекстом. Если вы покажете нам свой файл web.xml, я могу помочь вам больше.

В любом случае, как говорит @NimChimpsky, обычно не является хорошей практикой для управления транзакциями на вашем уровне контроллера.