GWT JDO 关系问题 - 数据存储中对象的子级为空
我在尝试实现 GWT JDO 功能时遇到问题。假设有一个包含 Item
对象的 Data
对象。在数据存储中,这将创建一对一的关系。
问题是,当我尝试从数据存储区获取对象时,“item”字段始终为 null。当然,我将该对象放入包含初始化的 Item
对象的数据存储中(列表末尾)。查看数据存储时,Data
和 Item
实体确实存在。
我是否对一对一关系处理不当?还需要什么?同样的情况是当我尝试创建一对多关系(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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我花了几个小时试图理解这一点。
子对象不会随其父对象一起加载,因为它们是延迟加载的。
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 adata0.getItem()
, for instance). In your case, your're trying to access the child object after you close thePersistenceManager
, so they're aren't loaded.我在数据存储上的 JDO 中经历过类似的用例,并进行了以下解决工作。
因此,如果您想在任何情况下从持久性管理器中分离数据存储对象并读取子对象。最好先读取子对象,然后分离尤其是。如果子对象不是默认的获取组对象/实体。
例如。
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.