2015-09-06 43 views
0

我有一個使用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)檢索OK,但taskToCommandMap,taskToDefaultCommandParams和taskToTransitions全部返回爲空。

由於DataNucleus對此question的評論,我試圖將collection的集合標記爲serializable =「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中引用了一個接口,它擴展了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

datanucleus.retainValues =在真PMF屬性

+0

定義「檢索」 。通過我的意思是你的持久性代碼來檢索字段,並且你在哪裏檢查字段值(在那個時候什麼是對象狀態?)。 –

+0

我還沒有與這些工作,但它看起來像我這些集合被定義爲「懶惰」,這意味着你需要以某種方式表明你想要的集合填充。另外,如果你實例化這些集合(例如'private Map taskToCommandMap = new HashMap <>();'),它可能會有所作爲。 –

+0

Thanks @ Sva.Mu我必須對從查詢返回的多個持久對象集合上的#size()方法進行調用才能使其填充 - 但我無法在每個對象的各個字段上調用方法 - 我只是得到一個空指針。 –

回答

1

感謝Neil Stockton的評論,單元測試現在通過了。

取計劃在這裏記載:http://www.datanucleus.org/products/datanucleus/jdo/fetchgroup.html

的空字段沒有加載它們不是由默認值(原語,字符串,日期,對象基元的包裝等加載的數據類型中)

爲了使上述工作的代碼,我移動每個空字段到默認的通過在@Persistance註釋指定一個新的屬性提取組 - defaultFetchGroup =「真」

@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 
相關問題