Query vs Extent for retrieving data

#1

I'm running into a problem where data that is retrieved via a Query comes out null, but when I retrieve it using an Extent everything is present. We have a very simple class:

public class PositionReportManagerBean implements InstanceCallbacks {
   private int maxReports;
   private List<PositionReportBean> reports;
}

I have a test file with 5 instances of PositionReportManagerBean, each with maxReports set to 10 and 5 PositionReportBeans in reports. I can verify with the ObjectDB explorer that all of the data is there. If I call

Extent<PositionReportManagerBean> extent =
    pm.getExtent(PositionReportManagerBean.class, true);

I get an Extent back with all of the data as I would expect. However, if I execute a Query:

javax.jdo.Query q = pm.newQuery(PositionReportManagerBean.class, "");
Collection c = (Collection)q.execute();

Then the PositionReportManagerBeans that are part of the returned Collection have the maxReports set to 10 as I expect, but the List of PositionReportBeans is empty. Is there something I need to set on the Query? I'm really stumped by this one.

#2

I should note that no Exceptions are being thrown and the only entries in the ObjectDB log file indicate file opening and closing and I'm using ObjectDB 2.3.4.

#3

The difference between using Extent and queries in this case is unclear.

Could you please post a complete runnable test, based on the code in the posting instructions (but possibly using JDO) that demonstrates this issue?

ObjectDB Support
#4

Well I whipped up a standalone sample app, and of course now it works perfectly. I'm going to look over the deltas between what I came up with and our production code and see if I can come up with anything more.

#5

Ok, so I narrowed it down to closing the PersistenceManager prior to accessing any of the fields in the data. The following code block prints out all empty arrays for the lists of PositionReportBeans contained within the PositionReportManagerBean:

        PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(getProperties(filename));
        PersistenceManager pm = pmf.getPersistenceManager();
        List<PositionReportManagerBean> beans = new ArrayList<PositionReportManagerBean>();
       
        javax.jdo.Query q = pm.newQuery(PositionReportManagerBean.class, "");
        Collection c = (Collection)q.execute();
        for(Object o : c) {
            beans.add((PositionReportManagerBean)o);
        }
        q.closeAll();
       
        pm.close();
        pmf.close();
       
        for(PositionReportManagerBean bean : beans) {
            System.out.println(bean.getMaxReports() + "\t" + bean.getReports());
        }

But if I move the for loop that prints out the contents of the bean to just prior to closing the PersistenceManager, it works as I would expect. Is there something I need to set on the PersistenceManager? Right now my Properties that I use to initialize the PersistenceManagerFactory have javax.jdo.option.Optimisitic and javax.jdo.option.Multithreaded both set to true, but that's it.

#6

I should note that I tried moving the print loop to after the closing of the PersistenceManager, but before closing the PersistenceManagerFactory and got the same undesired results. This is why I believe it's tied to closing the PM.

Right now my code is set up to get a new PM from the PMF with each query and then close it when it's done. Is there a different technique I should use?

#7

This is the normal behavior. The ability to navigate through persistent references transparently, loading necessary objects from the database on the fly, is available only when the PersistenceManager is open.

Therefore, you must make sure that required fields are loaded before the PersistenceManager is closed. In JDO you can either annotate these fields with @Persistent(defaultFetchGroup="true"), or use fetch groups do define more complex fetch strategies.

ObjectDB Support

Reply