示例:s 我有一个与对象b,c和d有关的A类对象 如果我这样做:
SelectQuery query = new SelectQuery(A.class);
query.addPrefetch("b").setSemantics(PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
query.addPrefetch("c").setSemantics(PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
List<?> res = context.performQuery(query);
然后:
SelectQuery query = new SelectQuery(A.class);
query.addPrefetch("d").setSemantics(PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
List<?> res = context.performQuery(query);
从a到b和c的关系无效(参见DataRowUtils第115行)。
我使用的是Cayenne 3.0.2但版本3.1和3.2M1的行为似乎相同
有没有办法解决这个问题?
我的想法是用这个函数覆盖A类中的CayenneDataObject:
public void writePropertyDirectly(String propName, Object val) {
if(propName.equals("b") || propName.equals("c")) {
if(val instanceof Fault && readPropertyDirectly(propName) != null) {
return;
}
}
super.writePropertyDirectly(propName, val);
}
这是个坏主意吗?它似乎工作。
加载后,我根本不想从数据库中刷新b和c
感谢
答案 0 :(得分:0)
实际上这种行为是预料之中的。一对一关系的失效是在select上完成的,以保证对它们的全新视图,并且前提是在需要时应该很容易从内存缓存中恢复它们。因此,当你打电话给getB&#39;时,为了一个简单的FK关系。或者&#39; getC&#39;,您将获得故障的对象,但您不会看到数据库查询。
由于某些原因,可能会发生异常(读取一对一时的意外查询)。最可能的一个是ObjectContext本地缓存的急切垃圾收集。为了防止它,Cayenne 3.1和3.2提供了将保留策略设置为'cayenne.server.object_retain_strategy'属性的功能。你可以尝试“努力”。策略并查看是否存在任何差异。
如果您知道访问和刷新A的所有方案,则上述解决方案才可以。通常,它可能会导致数据刷新难以调试。