我正在研究基于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 {
// ....
此外,还有一个类,应该引用其中一个子类 . 根据"Polymorphic Relationships" section of "Entity Relationships in JDO" article,实现此类关系的最佳方法是存储对象的键,因此该类以下列方式查找:
@PersistenceCapable (identityType = IdentityType.APPLICATION)
public class OtherClass {
@Persistent
private String reference;
// ....
我从OtherClass的实例中检索引用对象的字符串键 . 然后我想获得引用对象本身:它是一个Parent子类的实例 . 但:
- 如果我使用pm.getObjectById(oid)方法执行此操作:
Object object = pm.getObjectById(reference);
抛出JDOObjectNotFoundException异常(javax.jdo.JDOObjectNotFoundException:没有这样的对象FailedObject:...) .
- 如果我使用getObjectById(class, key)方法:
父对象= pm.getObjectById(Parent.class,reference);
抛出FatalNucleusUserException异常(org.datanucleus.store.appengine.FatalNucleusUserException:收到查找类型Parent对象的请求,但提供的标识符是kind类的Key的String表示形式)
检索另一个实体中引用的子类之一的实例的正确方法是什么?
UPDATE :我在GAE google小组中找到了this帖子,但坦率地说,这对我没什么帮助 .
3 回答
App Engine的JDO层目前不支持多态 . 事实上,我不确定JDO是否支持它 .
我发现JDO和App Engine存在同样的问题,所以我启动了一个实现此解决方案的项目 . https://code.google.com/p/datanucleus-appengine-patch/我用我现在的代码进行的第一次测试看起来没问题,请随意尝试一下给我一些反馈 .
实际上我的解决方法可以通过两种方式解决您的问题 .
我实现了一个getObjectById(class,id),它也查找作为提供的类的实例的种类 .
我实现了一个getObjectById(oid),如果oid的类型为com.google.appengine.api.datastore.Key,它会对查找进行一些特殊处理,然后它会找出要返回的正确类 .
我添加了一个新的注释@PolymorphicRelationship,通过存储密钥,可以轻松处理App Engine描述的变通方法 . 样本如下所示:
@NotPersistent
@PolymorphicRelationship(keyField =“myChildKeys”)
public Collection <TestChild> myChildren;
我正在使用这种相当癌症和恶臭的反模式来克服JDO / App Engine的这种限制 .
然后获取集合:
这是一个糟糕的解决方案,但风暴中的任何端口......
(还涉及到这个bug,使用接口作为集合类型http://code.google.com/p/datanucleus-appengine/issues/detail?id=207)