2011-09-20 57 views
0

我正在開發一個Grails應用程序(服務器)來跟蹤Wi-Fi網絡中的移動設備。用戶將向在grails應用程序(服務器)上運行的web服務發送請求以及Mobileid和Wi-Fi IP地址。無法打開Hibernate Session進行交易

在我的grails應用程序中,我正在盯着多個外部java線程,每個線程將ping每個移動設備的Wi-Fi IP地址(每個設備跟蹤一個線程)。如果有任何設備IP無法訪問,那麼我會將數據庫中的移動狀態從外部線程更新爲「斷開連接」。這裏只我面臨的問題,如果一個以上的設備是不可達那麼多線程要更新每個設備在同一個表使用domain.withTransaction方法,而我得到以下異常

狀態

org.springframework.transaction.CannotCreateTransactionException:無法爲事務打開Hibernate Session;嵌套的異常是顯示java.lang.NullPointerException 在org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:596) 在org.codehaus.groovy.grails.orm.hibernate.GrailsHibernateTransactionManager.super $ 3 $ doBegin(GrailsHibernateTransactionManager .groovy作爲) 在sun.reflect.GeneratedMethodAccessor492.invoke(未知來源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在java.lang.reflect.Method.invoke(Method.java:597) 在org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88) 在groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) 在groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java: 1058) 在groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1070) 在org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN(ScriptBytecodeAdapter.java:127)

我的代碼:

執行ping在數據庫中的螺紋元件

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

將讀取移入事務,否則它們將處於斷開連接的會話中,而不是事務創建的會話。此外,這是最好的呼籲類,而不是一個實例(在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() 
    } 
} 
+0

@伯特:我仍得到相同的異常。是否由於在多個線程之間使用相同的hibernate會話?如果是這樣,是否有任何方法來增加在grails中創建hibernate會話?我沒有配置任何東西休眠?你能告訴我在grails中更好的配置hibernate嗎? –

+0

不,這是整個問題 - Hibernate會話在新線程中不可用。但是使用'withTransaction'(即使你沒有更新)是一個快速的修復,因爲它創建和綁定了一個新的會話,並且在持續時間內保持已加載的實例的連接。你可以試試'grails clean'並再次運行? –

+0

@BurtBeckwith除非事件最近(2.0?)發生更改,否則NewSession和withTransaction都不會在新創建的線程上綁定或創建一個hibernate會話。這就是Executor Plugin和之前的Background Thread插件存在的原因。 –

0

無需我來傳播錯誤信息和做事的方式不好。伯特和格雷姆的答案都能奏效。我只寫了一個quick test app to prove this

1

而不是使用Tiggerizzy建議的詳細綁定代碼。這是更好地使用內置的withNewSession法域類:

Mobile.withNewSession { 
    // your code here 
} 
+0

當我使用Domain.withNewSession時,我收到以下異常:org.springframework.dao.DataAccessResourceFailureException:無法打開Hibernate Session;嵌套的異常是org.hibernate.SessionException:Session被關閉! \t在org.springframework.orm.hibernate3.SessionFactoryUtils.getNewSession(SessionFactoryUtils.java:527) \t在org.springframework.orm.hibernate3.HibernateTemplate.getSession(HibernateTemplate.java:454) \t在org.springframework.orm .hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:393) –

+0

@EaswaramoorthyKanagaraj的代碼聽起來像是在非Grails創建的線程上運行,所以不會創建一個上下文。使用我建議的詳細和不完美的代碼或Executor插件是在隨機線程上實現休眠會話的最佳方式。 –

相關問題