我有一個使用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屬性
定義「檢索」 。通過我的意思是你的持久性代碼來檢索字段,並且你在哪裏檢查字段值(在那個時候什麼是對象狀態?)。 –
我還沒有與這些工作,但它看起來像我這些集合被定義爲「懶惰」,這意味着你需要以某種方式表明你想要的集合填充。另外,如果你實例化這些集合(例如'private Map taskToCommandMap = new HashMap <>();'),它可能會有所作爲。 –
Thanks @ Sva.Mu我必須對從查詢返回的多個持久對象集合上的#size()方法進行調用才能使其填充 - 但我無法在每個對象的各個字段上調用方法 - 我只是得到一個空指針。 –