2011-04-18 74 views
4

我會很感激,如果有人可以指點我的教程或最佳做法如何關閉 JDO連接。 每當我包含finally塊時,我總是得到javax.jdo.JDOUserException: Object Manager has been closed錯誤。
我的代碼是下面:如何解決對象管理器已關閉錯誤?

public static List<AgentEntity> findAgentEntityByString(String id) { 
    List<AgentEntity> agententity = new ArrayList<AgentEntity>(); 
    if (id == null) { 
     return null; 
    } 
    try { 
     Query q = pm.newQuery("select id from " + AgentEntity.class.getName()); 
     agententity = (List<AgentEntity>) q.execute(); 
    } catch(Exception ex) { 
     log.warning(ex.getMessage()); 
    } 
     return agententity; 
    } 

問候

+1

也許可以解釋「終於」發生了什麼(我沒有看到它在你的例子中)。也許事情正在分離?或者在PM結束之後訪問的東西? – DataNucleus 2011-04-18 12:48:17

+0

如果我包含finally塊,我得到的持久性管理器已關閉錯誤。所以我徹底刪除了它。當我這樣做時,代碼運行良好,但日誌仍抱怨「持久性管理器已關閉」。有了這個,我無法檢索存儲在Spring Controller GET請求中的ModelAttribute中顯示的數據。 – drecute 2011-04-19 10:26:06

+0

但是你還沒有說過在PM的「關閉」中發生了什麼,或者你的「finally塊」中有什麼代碼。日誌告訴你發生了什麼,但我們沒有看到它 – DataNucleus 2011-04-19 11:07:46

回答

3

的一種可能的解決方案來避免這種遲緩裝載問題是在關閉之前使用size()方法迫使PersistenceManager對象從數據存儲加載結果列表。

public static List<AgentEntity> findAgentEntityByString(String id) { 
    List<AgentEntity> agententity = new ArrayList<AgentEntity>(); 
    if (id == null) { 
     return null; 
    } 
    try { 
     Query q = pm.newQuery("select id from " + AgentEntity.class.getName()); 
     agententity = (List<AgentEntity>) q.execute(); 
     agententity.size() //Should populate the returned list 
     return agententity; 
    } finally { 
     pm.close(); 
    }   
    } 

參考here

+1

使用上面的代碼,我得到了下面的對象管理器已關閉 所致: javax.jdo.JDOUserException:對象管理器在org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:375)被關閉 \t \t 在org.datanucleus.jdo.JDOPersistenceManager.close( JDOPersistenceManager.java:281) \t at org.opevel.server.dao.AgentEntityDAOImpl.findAgentEntityByString(AgentEntityDAOImpl.java:95) \t at org.opevel.web.AgentController.h andleRequest(AgentController。的java:80) \t在sun.reflect.NativeMethodAccessorImpl.invoke0(本機方法) \t在sun.reflect.NativeMethodAcc' – drecute 2011-04-26 11:24:39

0

爲什麼你想在這裏關閉你的PersistenceManager? 如果您想關閉查詢,您應該使用 javax.jdo.Query.closeAll()javax.jdo.Query.close(Object result)。 所以你可以做的結果,無論是短暫的副本,不是關閉查詢,並將其結果:

public static List<AgentEntity> findAgentEntityByString(String id) { 
    if (id == null) { 
    return null; 
    } 
    Query q = null; 
    try { 
     q = pm.newQuery("select id from " + AgentEntity.class.getName()); 
     return new ArrayList<AgentEntity>((List<AgentEntity>) q.execute()); 
    } finally { 
    if(q!= null){ 
     q.closeAll(); 
    } 
    }   
} 

,或者您可以關閉結果後明確:

public static List<AgentEntity> findAgentEntityByString(String id) { 
    if (id == null) { 
    return null; 
    } 
    Query q = pm.newQuery("select id from " + AgentEntity.class.getName()); 
    return (List<AgentEntity>) q.execute(); 
    }   
} 
.... 
List agents = X.findAgentEntityByString("Foobar"); 
.... 
pm.close(agents); 
+0

我打電話的DAO方法findAgentEntityByString()從一個Spring控制器GET請求,在此示例中,這意味着我將不得不關閉春天的結果吧? – drecute 2011-04-19 10:32:42

+0

我試過上面的代碼,仍然沒有運氣。下面是錯誤堆棧:'持久性管理器已被關閉 引起: javax.jdo.JDOFatalUserException:持久性管理已在org.datanucleus.jdo.JDOPersistenceManager.assertIsOpen(JDOPersistenceManager.java:2125)被關閉 \t \t在org.datanucleus.jdo.JDOPersistenceManager.newQuery(JDOPersistenceManager.java:1247) \t在org.datanucleus.jdo.JDOPersistenceManager.newQuery(JDOPersistenceManager.java:1234) \t在org.opevel.server.dao.AgentEntityDAOImpl。 findAgentEntityByString(AgentEntityDAOImpl.java:107) \t at org.opevel.web.AgentController.handleRequest(' – drecute 2011-04-26 11:20:27

0

嘗試將剛取計劃獲取PM後,然後在執行查詢之前將其設置爲all:

import javax.jdo.FetchPlan;

pm = PMF.get().getPersistenceManager(); 
    FetchPlan fp = pm.getFetchPlan(); 
    fp.setGroup(FetchPlan.ALL); 
相關問題