2

假设我有一个非常简单的经典设置:GAE(1.7.4) + GWT(2.5.0) 应用程序,在本地 Jetty(开发服务器)上运行,使用 JDO 进行持久化。

假设我只有 2 个@PersistenceCapable 类:Person 和 Color。每个人都有一个最喜欢的颜色,但这并不意味着这个人拥有这个颜色 - 许多不同的人可以有相同的最喜欢的颜色。众所周知的颜色数量有限,即使不是任何人最喜欢的颜色也可能存在。

为了对此建模,我应该使用@Unowned 关系——如果我错了,请纠正我:

@PersistenceCapable
public class Color { // just the most regular Entity class

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    String rgb;

    // getter, setter, no constructor
}

@PersistenceCapable
public class Person {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    String surname;

    @Persistent
    @Unowned // here is the tricky part
    Color color;

    // getters, setters, no constructor
}

通过一些简单的、众所周知的、基于 PersistentManager 的代码,我能够成功地创建和持久化 Color 类的实例。我在 GAE 开发控制台 -> 数据存储查看器中看到它,具有很好的生成密钥和 ID/名称 (13),以及我分配的 RGB。

使用非常相似的代码,我能够创建 Person 类的实例(在另一个请求中),将预先存在的 Color 分配为他最喜欢的颜色(它预先存在,我通过 pm.getObjectById() 获得它)并将其持久化. 我在 Datastore Viewer 中看到它,我生成的密钥和 ID/名称为 (15),我分配的姓氏和 color_key_OID 为 (13)。这看起来很有希望。

但是,当我从数据库中取回 Person(15) 时(简单的 pm.getObjectById(),没有事务),它正确地分配了我的姓氏,但有 null 而不是 Color(13)!对 - 数据存储查看器可以正常工作,但我的代码没有。

哦,有问题的代码?“人 p = pm.getObjectById(Person.class, key);”。

(旁注:@Unowned 集合也有同样的问题(数据存储查看器中的值列表很好,但我的代码中的集合字段为空。)我在类路径上的 JDO jar 是“datanucleus-api-jdo-3.1.1. jar”和“jdo-api-3.0.1.jar”,所以我假设它们支持@Unowned。not-@Unowned 字段没有问题。在持久化或获取时我没有遇到任何异常,只是将纯空值作为字段值。)

4

4 回答 4

3

要么将颜色标记为“急切地获取”

@Persistent(defaultFetchGroup="true")
@Unowned
Color color

或像这样定义自己的 fetchgroup:

@FetchGroup(name="eager", members={@Persistent(name="color")})
@PersistenceCapable
public class Person {

并在需要时通过指定要获取的组来使用它:

PersistenceManager pm = pmf.getPersistenceManager();
pm.getFetchPlan().addGroup("eager");
于 2013-04-24T21:55:19.793 回答
0

我在我的一个@Unowned 列表中遇到了同样的问题。我还有另外两个,数组被完美地提取了。

为我解决这个问题的方法是将属性名称更改为更大的名称。在您的情况下,就像将属性名称从“color”更改为更大的名称,例如“myfavoritecolor”。

于 2013-11-26T13:14:40.870 回答
0

我有你描述的同样的问题。DataNucleus 如何说您需要描述对象的整个生命周期。在我的情况下,问题已解决,强制在使用 close() 函数关闭 PersistenceManager 之前从 person 对象中获取颜色。

请记住 JDO 使用延迟加载技术来获取对象。

于 2013-04-15T13:31:54.240 回答
0

我能够通过将获取组添加到查询而不是持久管理器来解决这个问题。

    PersistenceManager pm = PMF.get().getPersistenceManager();
    logger.info("EVENTS FETCH GROUPS : " + pm.getFetchPlan().getGroups());
    /*pm.getFetchPlan().addGroup("eventFetchGroup");
    pm.getFetchPlan().setMaxFetchDepth(2);*/
    Query q = pm.newQuery(Event.class);
    q.getFetchPlan().addGroup("eventFetchGroup");
    logger.info("EVENTS FETCH GROUPS : " +q.getFetchPlan().getGroups());
    q.setFilter("date >= fromDate && date <= toDate");
    q.declareParameters("java.util.Date fromDate, java.util.Date toDate");
于 2016-01-09T16:15:02.813 回答