Служба, настроенная в spring / resources.groovy, не имеет сессии Hibernate - PullRequest
3 голосов
/ 12 сентября 2010

У нас есть приложение с плагином, который содержит сервис:

public class TaskService {

    public void doSomething( Task task ) {
        // do something with task
        task.save();
    }
}

Это отлично работает.


Для нашего «специального» клиента с его особыми требованиями у нас есть второе приложение, которое содержит плагин из первого приложения и еще один плагин со специальным сервисом для этого клиента, который расширяет исходный сервис и переопределяет некоторые методы:

public class SpecialTaskService extends TaskService{

    @Override
    public void doSomething( Task task ) {
        // do something special with task
        task.save();
    }
}

В каждом месте во втором приложении, где внедряется taskService, мы хотим иметь SpecialTaskService сейчас (также в плагине из первого приложения). Итак, мы добавили специальный ресурс к resources.groovy под grails-app / conf / spring:

beans = {
        taskService( SpecialTaskService )
}

Но теперь мы получаем HibernateException, когда мы вызываем "task.save ()" в специальном сервисе: org.hibernate.HibernateException: Сессия Hibernate не привязана к потоку, и конфигурация не позволяет создавать нетранзакционный сеанс здесь

Мы знаем, что могли бы внедрить SessionFactory в SpecialService, но когда мы вызываем sessionFactory.currentSession, мы получаем то же исключение.

Исключение также возникает, когда мы настраиваем службу в resources.groovy, которая не расширяет другую.

Есть ли способ сделать специальный сервис своего рода "hibernateSessionAware", чтобы мы могли вызывать save () и merge () для доменных объектов?

1 Ответ

5 голосов
/ 12 сентября 2010

Исходный сервис является транзакционным, поэтому он сохраняет сеанс Hibernate открытым на время вызова метода (если только он не активен и не присоединился к нему). Таким образом, вам нужно сделать транзакцию тоже, поскольку вы просто указываете Spring создать простой новый экземпляр с taskService(SpecialTaskService)

Самое простое, что нужно сделать - это аннотировать класс (или отдельные методы, если вы предпочитаете):

import org.springframework.transaction.annotation.Transactional

@Transactional
class SpecialTaskService extends TaskService {

   @Override
   void doSomething(Task task) {
      // do something special with task
      task.save()
   }
}

но вы также можете заключить блоки кода или целые методы в блоки withTransaction:

class SpecialTaskService extends TaskService {

   @Override
   void doSomething(Task task) {
      Task.withTransaction { status ->
         // do something special with task
         task.save()
      }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...