代码之家  ›  专栏  ›  技术社区  ›  Jay

关闭持久性管理器后,如何使查询结果可用

  •  5
  • Jay  · 技术社区  · 15 年前

    public class Notes {
        public List<Note> getAll() {
        PersistenceManager pm = PMF.instance().getPersistenceManager();
    
        try {
            Query query = pm.newQuery("select from com.uptecs.google1.model.Note order by subject");
            return (List<Note>) query.execute();
        } finally {
            pm.close();
        }
        }
    }
    

    Object Manager has been closed
    org.datanucleus.exceptions.NucleusUserException: Object Manager has been closed
        at org.datanucleus.ObjectManagerImpl.assertIsOpen(ObjectManagerImpl.java:3876)
        at org.datanucleus.ObjectManagerImpl.getFetchPlan(ObjectManagerImpl.java:376)
        at org.datanucleus.store.query.Query.getFetchPlan(Query.java:497)
    
    3 回复  |  直到 15 年前
        1
  •  9
  •   bakkal    15 年前

    试着用 detachable="true" :

    @PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true")
    public class Note {
        @PrimaryKey
        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
        private Long key;
    ...
    }
    

    我完全理解这样做的必要性,有时需要检索控制器中的对象和列表,关闭控制器中的PM,然后将模型传递给视图。在我知道更好的解决方案之前,这就是我在JDO/GAE上所做的,到目前为止没有任何问题。

    在我看来,如果你想使用列表中的所有项目,你就必须把它们分开 . 我会用这个来得到具体的物品清单。满满的 getAll() 可以很大。

    public List<Note> getList(){
        List<Note> detachedList=null, list=null;
        try {
            String query = "select from " + Note.class.getName();
            pm = PMF.get().getPersistenceManager();
            list = (List<Note>)pm.newQuery(query).execute();            
            detachedList = new ArrayList<Note>();
            for(Note obj : list){
                detachedList.add(pm.detachCopy(obj));
            }
    
        } finally {
            pm.close();
        }
        return detachedList;
    
    }
    

    按键:

    public Note findByKey(Long key) {
        Note detachedCopy=null, object=null;
        try{
            pm= PMF.get().getPersistenceManager();
            object = pm.getObjectById(Note.class,key);
            detachedCopy = pm.detachCopy(object);
        }catch (JDOObjectNotFoundException e) {
            return null; // or whatever
        } 
        finally {
            pm.close(); // close here
        }
        return detachedCopy;
    
    }
    

    结束后,你有一个独立的副本,你可以用它工作。

    参考文献: http://www.datanucleus.org/products/accessplatform_1_1/jdo/attach_detach.html

        2
  •  1
  •   Eugene Ryzhikov    15 年前

    当在列表中返回结果时,对象将被延迟地检索(仅当您请求时)。由于持久性管理器已关闭,因此会出现一个异常。通过“分离”对象,您可以有效地告诉持久性管理器立即检索它们。

        3
  •  0
  •   Gaël Oberson    13 年前

    除了bakkal的回答,我想说你绝对需要 detachable="true" pm.detachCopyAll(your_query_result_list)

    下面是我目前在上一个应用程序中使用的一个工作示例(查询中使用的键是一个编码字符串):

    pm = PMF.get().getPersistenceManager();
    
    Query query = pm.newQuery(TandemSubscription.class);
    query.setFilter("groupSubscriptionKey==groupSubscriptionKeyParam");
    query.setOrdering("dateRDV desc");
    query.declareParameters("String groupSubscriptionKeyParam");
    
    // Get Data
    @SuppressWarnings("unchecked")          
    List<TandemSubscription> savedSubscriptions = 
         (List<TandemSubscription>) query.execute(Key);
    
    // Detach all objects in the list
    savedSubscriptions = 
         (List<TandemSubscription>) pm.detachCopyAll(savedSubscriptions);
    
    pm.close();
    
    // Now you can use the list and its content.
    

    我希望这有点帮助。