我正在研究基于GAE的应用程序,它使用JDO来访问数据存储区。我需要在持久化对象之间实现多态关系。
有抽象的父类:
@PersistenceCapable
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
public abstract class Parent {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
String id;
// ....
还有几个孩子班:
@PersistenceCapable (identityType = IdentityType.APPLICATION)
public class Child extends Parent {
// ....
此外,还有一个类,应该引用其中一个子类。根据{{3}},实现此类关系的最佳方法是存储对象的键,因此该类以下列方式查找:
@PersistenceCapable (identityType = IdentityType.APPLICATION)
public class OtherClass {
@Persistent
private String reference;
// ....
我从OtherClass的实例中检索引用对象的字符串键。然后我想获得引用对象本身:它是一个Parent子类的实例。但是:
如果我使用"Polymorphic Relationships" section of "Entity Relationships in JDO" article方法执行此操作:
Object object = pm.getObjectById(reference);
抛出JDOObjectNotFoundException异常( javax.jdo.JDOObjectNotFoundException:没有这样的对象FailedObject:... )。
如果我使用pm.getObjectById(oid)方法执行此操作:
父对象= pm.getObjectById(Parent.class,reference);
抛出FatalNucleusUserException异常( org.datanucleus.store.appengine.FatalNucleusUserException:收到查找类型为Parent的对象的请求,但提供的标识符是kind类的Key 的String表示形式)
检索另一个实体中引用的子类之一的实例的正确方法是什么?
更新:我在GAE google网上找到了getObjectById(class, key)个帖子,但坦率地说,这对我没什么帮助。
答案 0 :(得分:1)
我发现JDO和App Engine存在同样的问题,所以我启动了一个为此实现解决方法的项目。 https://code.google.com/p/datanucleus-appengine-patch/ 我用我现在的代码进行的第一次测试看起来没问题,请随意尝试一下,给我一些反馈。
实际上我的解决方法可以通过两种方式解决您的问题。
@Persist public Collection<Key> myChildKeys; @NotPersistent @PolymorphicRelationship(keyField ="myChildKeys") public Collection<TestChild> myChildren;
答案 1 :(得分:1)
我使用这种相当癌症和恶臭的反模式来克服JDO / App Engine的这种限制。
@JsonIgnore
@Persistent(mappedBy="account")
private List<XProvider> xProviders;
@JsonIgnore
@Persistent(mappedBy="account")
private List<YProvider> yProviders;
// TODO: add extra providers here and in getProviders() below...
然后获得收藏:
public List<XProvider> getXProviders() {
if (xProviders == null) {
xProviders = new ArrayList<XProvider>();
}
return xProviders;
}
//etc with other getters and setters for each collection.
public List<Provider> getProviders() {
List<Provider> allProviders = new ArrayList<Provider>();
// TODO: add extra providers here...
allProviders.addAll(getXProviders());
allProviders.addAll(getYProviders());
return allProviders;
}
这是一个糟糕的解决方案,但风暴中的任何端口 ......
(也与此错误有关,使用接口作为集合类型http://code.google.com/p/datanucleus-appengine/issues/detail?id=207)
答案 2 :(得分:0)
App Engine的JDO层目前不支持多态。事实上,我不确定JDO是否支持它。