SelectQuery期间丢失的数据

时间:2014-09-23 13:39:08

标签: apache-cayenne

示例: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 感谢

1 个答案:

答案 0 :(得分:0)

实际上这种行为是预料之中的。一对一关系的失效是在select上完成的,以保证对它们的全新视图,并且前提是在需要时应该很容易从内存缓存中恢复它们。因此,当你打电话给getB&#39;时,为了一个简单的FK关系。或者&#39; getC&#39;,您将获得故障的对象,但您不会看到数据库查询。

由于某些原因,可能会发生异常(读取一对一时的意外查询)。最可能的一个是ObjectContext本地缓存的急切垃圾收集。为了防止它,Cayenne 3.1和3.2提供了将保留策略设置为'cayenne.server.object_retain_strategy'属性的功能。你可以尝试“努力”。策略并查看是否存在任何差异。

如果您知道访问和刷新A的所有方案,则上述解决方案才可以。通常,它可能会导致数据刷新难以调试。