GWT JDO 关系问题 - 数据存储中对象的子级为空

发布于 2024-09-18 05:39:07 字数 2860 浏览 6 评论 0原文

我在尝试实现 GWT JDO 功能时遇到问题。假设有一个包含 Item 对象的 Data 对象。在数据存储中,这将创建一对一的关系。

问题是,当我尝试从数据存储区获取对象时,“item”字段始终为 null。当然,我将该对象放入包含初始化的 Item 对象的数据存储中(列表末尾)。查看数据存储时,DataItem 实体确实存在。

我是否对一对一关系处理不当?还需要什么?同样的情况是当我尝试创建一对多关系(Item 的数组)


Data.java:

package com.rafalrybacki.jdotest.client.model;

import java.io.Serializable;
import java.util.ArrayList;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Data implements Serializable {

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;

@Persistent
private String symbol;

@Persistent
public Item item;

public Data(){}

// ...
}

Item.java:

package com.rafalrybacki.jdotest.client.model;

import java.io.Serializable;

import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Item implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
private String encodedKey;

@Persistent
public String title;

public Item(){}

public Item(String title){
    this.title = title;
}

// ...
}

服务器端实现:

public void save(Data data) {
    PersistenceManager pm = PersistenceManagerFactoryGetter.get().getPersistenceManager();
    try {
        pm.makePersistent(data);
    } finally {
        pm.close();
    }
    return;
}

public Item load() {
    PersistenceManager pm = PersistenceManagerFactoryGetter.get().getPersistenceManager();
    List<Data> datas = new ArrayList<Data>();
    Data data0 = null;
    try {
        Query q = pm.newQuery(Data.class);
        datas = (List<Data>) q.execute();
        if (datas.size() > 0)
            data0 = pm.detachCopy(datas.get(0)); // get first item only

    } finally {
        pm.close();
    }
    return data0.item;  // always null !!!!!
}

在客户端 我正在对这样创建的 data 对象(带有 item 字段不为空

Data d = new Data("data1");
d.item = new Item("item2");

service.save(d, ...); //rpc service call

// ...

service.load(...);

I encounter problems while trying to implement GWT JDO features. Let's say there is a Data object that contains an Item object. In the datastore this would create a one-to-one relationship.

The problem is that when I try to get the object from the datastore, the 'item' field is always null. Of course I put the object to the datastore that contains the initalized Item object (end of the listing). When viewing the datastore, both Data and Item entities do exist.

Do I manage the one-to-one relationship wrong? What else is needed? The same situation is when I try to create one-to-many relatioship (an array of Item's)


Data.java:

package com.rafalrybacki.jdotest.client.model;

import java.io.Serializable;
import java.util.ArrayList;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Data implements Serializable {

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;

@Persistent
private String symbol;

@Persistent
public Item item;

public Data(){}

// ...
}

Item.java:

package com.rafalrybacki.jdotest.client.model;

import java.io.Serializable;

import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Item implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
private String encodedKey;

@Persistent
public String title;

public Item(){}

public Item(String title){
    this.title = title;
}

// ...
}

server-side implementation:

public void save(Data data) {
    PersistenceManager pm = PersistenceManagerFactoryGetter.get().getPersistenceManager();
    try {
        pm.makePersistent(data);
    } finally {
        pm.close();
    }
    return;
}

public Item load() {
    PersistenceManager pm = PersistenceManagerFactoryGetter.get().getPersistenceManager();
    List<Data> datas = new ArrayList<Data>();
    Data data0 = null;
    try {
        Query q = pm.newQuery(Data.class);
        datas = (List<Data>) q.execute();
        if (datas.size() > 0)
            data0 = pm.detachCopy(datas.get(0)); // get first item only

    } finally {
        pm.close();
    }
    return data0.item;  // always null !!!!!
}

On client-side I'm operating on such created data object (with item field that is not null)

Data d = new Data("data1");
d.item = new Item("item2");

service.save(d, ...); //rpc service call

// ...

service.load(...);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

万劫不复 2024-09-25 05:39:07

我花了几个小时试图理解这一点。
子对象不会随其父对象一起加载,因为它们是延迟加载的。 query.execute() 不返回子字段。仅当您尝试访问它们时才会加载它们(例如,使用 data0.getItem())。在您的情况下,您在关闭 PersistenceManager 后尝试访问子对象,因此它们不会被加载。

I lost a few hours trying to understand this.
Child objects aren't loaded with their parents because they are lazily loaded. The query.execute() doesn't return the child fields. They are only loaded if you try to access it (with a data0.getItem(), for instance). In your case, your're trying to access the child object after you close the PersistenceManager, so they're aren't loaded.

夜声 2024-09-25 05:39:07

我在数据存储上的 JDO 中经历过类似的用例,并进行了以下解决工作。
因此,如果您想在任何情况下从持久性管理器中分离数据存储对象并读取子对象。最好先读取子对象,然后分离尤其是。如果子对象不是默认的获取组对象/实体。
例如。

public Item load() {
    PersistenceManager pm = 
    PersistenceManagerFactoryGetter.get().getPersistenceManager();
    List<Data> datas = new ArrayList<Data>();
   Data data0 = null;
try {
    Query q = pm.newQuery(Data.class);
    datas = (List<Data>) q.execute();
    if (datas.size() > 0)
        data0=datas.get(0);
        data0.getItem();//call getter for child object
        pm.detachCopy(data0); // then detach

} finally {
    pm.close();
}
    return data0.getItem();  // should return non-null !!!!!
}

I have experienced similar usecases in JDO on Datastore and following work around works.
So, if you want to detach datastore object from Persistence Manager in any case and read the child objects too. Better to first read the child objects and then detach esp. if child object is not the default fetch group object/entity.
For example.

public Item load() {
    PersistenceManager pm = 
    PersistenceManagerFactoryGetter.get().getPersistenceManager();
    List<Data> datas = new ArrayList<Data>();
   Data data0 = null;
try {
    Query q = pm.newQuery(Data.class);
    datas = (List<Data>) q.execute();
    if (datas.size() > 0)
        data0=datas.get(0);
        data0.getItem();//call getter for child object
        pm.detachCopy(data0); // then detach

} finally {
    pm.close();
}
    return data0.getItem();  // should return non-null !!!!!
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文