![](/img/trans.png)
[英]Why do contravariant collections only allow Object instances to be retrieved?
[英]Why are Collections retrieved as null?
我有一個使用JDO的Google App Engine項目,當我檢索包含集合集合的類時,每個集合為null,而檢索到該類中的簡單字段就可以了。
我在使用錯誤注釋的基礎上進行工作,因此增強器在運行時會禮貌地忽略字段-但看不到哪里。
當我調試通過時,我可以看到對makePersistent的調用更新了對這些字段的引用,並且它們保持為非空且已填充。 當我使用持久對象中的ID再次檢索它時,這些字段為null。
我的持久對象在下面子類化了一個通用的持久對象。
@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全部返回為null。
由於DataNucleus對這個問題的評論,我嘗試將集合的集合標記為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是一個對象,它設置了簡單的字段,但Maps現在為空。
為什么我看到這些字段返回空值? 我應該怎么做? ...朗姆酒在哪里?
編輯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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.