为什么集合检索为空?
Why are Collections retrieved as null?
我有一个使用 JDO 的 Google App Engine 项目,当我检索到一个包含集合集合的 class 时,每个集合都是空的,而 class 中更简单的字段被检索到 OK .
我的工作基础是我使用了错误的注释,因此增强器礼貌地忽略了 运行 时间的字段 - 但看不到哪里。
当我调试通过时,我可以看到我对 makePersistent 的调用更新了对这些字段的引用,并且它们保持非空并已填充。当我使用持久对象中的 ID 再次检索它时,字段为空。
我的持久对象子class是下面的通用持久对象。
@PersistenceCapable
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
public abstract class PersistentObject {
@PrimaryKey
@Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
protected Long id;
// getters and setters omitted
}
我正在尝试存储和检索的子class 看起来像这样。名称字段(案例 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 有一个扩展Serializable 的接口。 None 实现 DataSelection 的 class 是在注解中引用的,其中 none 是 @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 属性中的 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
我有一个使用 JDO 的 Google App Engine 项目,当我检索到一个包含集合集合的 class 时,每个集合都是空的,而 class 中更简单的字段被检索到 OK .
我的工作基础是我使用了错误的注释,因此增强器礼貌地忽略了 运行 时间的字段 - 但看不到哪里。
当我调试通过时,我可以看到我对 makePersistent 的调用更新了对这些字段的引用,并且它们保持非空并已填充。当我使用持久对象中的 ID 再次检索它时,字段为空。
我的持久对象子class是下面的通用持久对象。
@PersistenceCapable
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
public abstract class PersistentObject {
@PrimaryKey
@Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
protected Long id;
// getters and setters omitted
}
我正在尝试存储和检索的子class 看起来像这样。名称字段(案例 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 有一个扩展Serializable 的接口。 None 实现 DataSelection 的 class 是在注解中引用的,其中 none 是 @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 属性中的 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