Как связать сессию Hibernate с потоком в Grails?

Я пишу многопоточное приложение в Grails, а дополнительные потоки нуждаются в доступе к GORM/Hibernate. Когда они пытаются получить доступ к GORM, я получаю сообщение об ошибке "org.hibernate.HibernateException: нет сеанса Hibernate Session, связанного с потоком, а конфигурация не позволяет создавать не транзакционные файлы здесь".

Хорошо честно, может ли кто-нибудь направить меня на лучший способ установить потоки для доступа? Сообщение об ошибке почти похоже на то, что вам просто нужно изменить некоторые параметры конфигурации, но я чувствую, это не так просто...

Ответы

Ответ 1

В приложениях Grails под названием "persistenceInterceptor" есть bean, которые могут быть использованы для этого.

См. этот пример из плагина JMS о том, как его использовать:

http://github.com/gpc/grails-jms/blob/master/src/groovy/grails/plugin/jms/listener/adapter/PersistenceContextAwareListenerAdapter.groovy#L21

Вот интерфейс:

https://github.com/grails/grails-core/blob/master/grails-core/src/main/groovy/grails/persistence/support/PersistenceContextInterceptor.java

И Hibernate impl:

https://github.com/grails/grails-data-mapping/blob/master/grails-datastore-gorm-support/src/main/groovy/org/grails/orm/hibernate4/support/HibernatePersistenceContextInterceptor.java

Ответ 3

withNewSession также будет работать. В моем случае у меня есть обновления с низким приоритетом, где последнее обновление всегда может "выиграть". version: false также важен здесь, чтобы избежать исключения StaleObjectException:

     Thread.start {
        try {
            Widget.withNewSession {
                xxx()
                log.info "Asynchronously did some updates."
            }
        } catch (Exception ex) {
            log.error "Failed to asynchronously do something...", ex
        }
    }