为什么收集的集合为空?

时间:2015-09-06 12:57:23

标签: java google-app-engine jdo datanucleus

我有一个使用JDO的Google App Engine项目,当我检索包含集合集合的类时,每个集合都为null,而类中的较简单字段被检索为OK。

我的工作基础是我使用错误的注释,因此增强器在运行时礼貌地忽略了字段 - 但无法看到哪里。

当我通过调试时,我可以看到我对makePersistent的调用更新了对这些字段的引用,并且它们保持非空并填充。当我使用持久对象中的ID再次检索它时,字段为空。

我的持久对象子类是一个通用的持久对象,在下面。

@PersistenceCapable
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
public abstract class PersistentObject {
    @PrimaryKey
    @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
    protected Long id;

    // getters and setters omitted
}

我试图存储和检索的子类看起来像这样。检索名称字段(案例1),但taskToCommandMap,taskToDefaultCommandParams和taskToTransitions都返回null。

我已经尝试将集合集合标记为serializable =“true”,因为有关此question的DataNucleus注释。

@PersistenceCapable
public class ConcretePersistentObject extends PersistentObject {
    /** Case 1 - Stored and retrieved fine */
    @Persistent 
    private String name;

    /** Case 2 - A new object ref is visible in the debugger for this after the call to makePersistent , but when retrieved it's null */
    @Persistent 
    private Map<String, String> taskToCommandMap;

    /** Case 3 -  DataSelection is serializable */
    @Persistent 
    private Map<String, Map<String, DataSelection>> taskToDefaultCommandParams;

    /** Case 4 - Serialized because GAE doesn't support persisting Map values of type LinkedList or ArrayList. 
     */
    @Persistent(serialized="true")
    private Map<String, List<String>> taskToTransitions;

    // getters and setters omitted

引用的DataSelection有一个扩展Serializable的接口。实现DataSelection的类都没有在注释中引用,也没有一个是@PersistenceCapable。

public interface DataSelection extends Serializable {...}

编辑1:实际检索在通用DAO中进行,

public T get(Long id) {
    if(id == null) {
        return null;
    }
    PersistenceManager pm = pmf.getPersistenceManager();
    T persistentObject = null;
    try {
        persistentObject = (T) pm.getObjectById(persistentClass, id);

    } catch (Exception e) {
        logger.warning( e.toString() );
        e.printStackTrace();
        return null;

    } finally {
        pm.close();
    }

    return persistentObject;
}

我构建并存储一个实例,然后调用get方法,然后逐个测试字段:

ConcretePersistentObject cpo1 = buildAndStore();
ConcretePersistentObject cpo2 = concretePersistentObjectDao.get( cpo1.getId() );
assertEquals(cpo1.getName(), cpo2.getName(); // passes
assertEquals(true, cpo1.getTaskToCommandMap().keySet().equals(cpo2.getTaskToCommandMap().keySet())); // null pointer exception

此时,cpo1将填充原始数据。它引用了包含数据的HashMap。 cpo2是一个对象,它设置了简单的字段,但是地图现在为空。

为什么我会看到为这些字段返回的空值?我应该做些什么呢? ......朗姆酒在哪儿?

编辑2: 在比较时,两个对象都处于TRANSIENT状态。

我没有在任何地方设置detachAllOnClose,System.out.println(pmfInstance.getProperties())没有显示它设置,并且DataNucleus doco显示它默认为false。

在调用pm.getObjectById之前,FetchPlan看起来像这样:

FetchPlan.DetachmentOptions = 1
FetchPlan.MaxFetchDepth = 1
FetchPlan.FetchSize = 0

PMF属性中的

datanucleus.retainValues = true

0 个答案:

没有答案