Не удалось открыть Hibernate Session для транзакции - PullRequest
0 голосов
/ 20 сентября 2011

Я разрабатываю приложение Grails (сервер) для отслеживания мобильного устройства, которое находится в сети Wi-Fi.Пользователи отправят запрос в веб-службу, которая работает на приложении (сервере) Grails вместе с IP-адресом Mobileid и Wi-Fi.

В моем приложении Grails я запускаю несколько внешних потоков Java, каждый поток будетпингует IP-адрес Wi-Fi каждого мобильного устройства (один поток на одно устройство для отслеживания).Если какой-либо IP-адрес устройства недоступен, я обновлю мобильный статус как «Отключен» в базе данных из внешнего потока.Вот только я сталкиваюсь с проблемой, если более одного устройства недоступно, то несколько потоков собираются обновить состояние каждого устройства в одной и той же таблице, используя метод domain.withTransaction , в то время как я получаю следующееисключение

org.springframework.transaction.CannotCreateTransactionException: не удалось открыть сеанс Hibernate для транзакции;Вложенное исключение - java.lang.NullPointerException в org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin (HibernateTransactionManager.java:596) в org.codehaus.groovy.grails.orm.hibernate.GrailsHibernateHrans) at sun.reflect.GeneratedMethodAccessor492.invoke (неизвестный источник) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) в java.lang.reflect.Method.invoke (Method.java: 59) atggroovy.reflection.CachedMethod.invoke (CachedMethod.java:88) в groovy.lang.MetaMethod.doMethodInvoke (MetaMethod.java:233) в groovy.lang.MetaClassImpl.invokeMethoytaglogloglogTyglogTyglogTyglogTyglogTyglogTygloj.invokeMethod (ExpandoMetaClass.java:1070) в org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN (ScriptBytecodeAdapter.java:127)

Мой код: 1013

1011 * 1011устройство в потоке
try {
    final InetAddress inet = InetAddress.getByName(ipAddress);
    boolean status = inet.isReachable(5000);
    if (status) {
        pool.run(MobileDeviceTracker.deviceMap.get(mobileId));
    } else {
         // Calling service to update the status of device as disconnected
        getUserMobileService().deviceDisconnected(mobileId, ipAddress);
    }
} catch (Exception e) { }

ОбновлениеСтатус в базе данных

class DisconnectionService implements UserMobileServiceInt{
     static transactional = true


    def void deviceDisconnected(String mobileId, String wifiIp){
        try{
            def mobile = Mobile.findByMobileId(mobileId)
            def userMobile = UserMobile.findByMobileAndWifiIp(mobile, wifiIp)
            userMobile.withTransaction {tx ->               
                userMobile.action = Constants.MOBILE_STATUS_DISCONNECTED
                userMobile.alarmStatus = Constants.ALARM_STATUS_TURNED_ON
                userMobile.modifiedDate = new Date()
                userMobile.save(flush: true)
        }
        }catch(Exception e){
            e.printStackTrace()
        }

Я пытаюсь последние 4 дня, но не могу решить эту проблему.

Ответы [ 3 ]

3 голосов
/ 20 сентября 2011

Переместите операции чтения в транзакцию, иначе они будут в отключенном сеансе, а не в том, который создает транзакция.Кроме того, лучше всего вызывать статические методы для класса, а не для экземпляра (как в Groovy, так и в Java):

void deviceDisconnected(String mobileId, String wifiIp){
   try {
      UserMobile.withTransaction { tx ->
         def mobile = Mobile.findByMobileId(mobileId)
         def userMobile = UserMobile.findByMobileAndWifiIp(mobile, wifiIp)
         userMobile.action = Constants.MOBILE_STATUS_DISCONNECTED
         userMobile.alarmStatus = Constants.ALARM_STATUS_TURNED_ON
         userMobile.modifiedDate = new Date()
         userMobile.save(flush: true)
      }
   }
   catch(e) {
      e.printStackTrace()
   }
}
1 голос
/ 21 сентября 2011

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

Mobile.withNewSession {
   // your code here
}
0 голосов
/ 21 сентября 2011

Мне не нужно распространять неверную информацию и плохие способы ведения дел. Оба ответа от Берта и Грэма будут работать. Я только что написал приложение для быстрого тестирования, чтобы доказать это .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...