java - 为什么 Collections 检索为空?

标签 java google-app-engine jdo datanucleus

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

我正在工作,因为我使用了错误的注释,因此增强器在运行时礼貌地忽略这些字段 - 但看不到在哪里。

当我调试时,我可以看到对 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。

由于 DataNucleus 对此 question 的评论,我尝试将集合的集合标记为可序列化 =“true” 。

@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 中引用了一个扩展 Serialized 的接口(interface)。注解中没有引用任何实现 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

最佳答案

感谢 Neil Stockton 的评论,单元测试现已通过。

获取计划记录在此处:http://www.datanucleus.org/products/datanucleus/jdo/fetchgroup.html

空字段未加载,它们不是默认加载的数据类型(基元、字符串、日期、基元的对象包装器等)

为了使上面的代码正常工作,我通过在 @Persistance 注释上指定一个新属性 - defaultFetchGroup="true"将每个空字段移动到默认提取组中

@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(defaultFetchGroup="true") 
    private Map<String, String> taskToCommandMap;

    /** Case 3 -  DataSelection is serializable */
    @Persistent(defaultFetchGroup="true")
    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", defaultFetchGroup="true")
    private Map<String, List<String>> taskToTransitions;

    // getters and setters omitted

关于java - 为什么 Collections 检索为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32423825/

相关文章:

python - 应用引擎 : Step-by-Step Debugging

java - 由于 PMF,AppEngine JDO 无法创建持久对象

java - 在 GoogleEngine (Java) 上,在 JDO 中,如何根据父对象的 id 查询子对象列表?

mysql - 如何将 Strapi (GAE) 应用程序连接到 MySQL (GSC) 数据库?

java - 数据存储实体键冲突

java - 无法围绕 appengine 数据存储持久性

java - 获取给定时区的当前时间 : android

java - 如何在spring构造函数中初始化并传递Properties类

java - 低于 24 的 android api 级别不支持

java - 如何在 JFreeChart 中自定义 CategoryPlot 项目的工具提示?