首页 文章

Google App Engine中的JDO:如何实现多态关系?

提问于
浏览
1

我正在研究基于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子类的实例 . 但:

Object object = pm.getObjectById(reference);

抛出JDOObjectNotFoundException异常(javax.jdo.JDOObjectNotFoundException:没有这样的对象FailedObject:...) .

父对象= pm.getObjectById(Parent.class,reference);

抛出FatalNucleusUserException异常(org.datanucleus.store.appengine.FatalNucleusUserException:收到查找类型Parent对象的请求,但提供的标识符是kind类的Key的String表示形式)

检索另一个实体中引用的子类之一的实例的正确方法是什么?

UPDATE :我在GAE google小组中找到了this帖子,但坦率地说,这对我没什么帮助 .

3 回答

  • 0

    App Engine的JDO层目前不支持多态 . 事实上,我不确定JDO是否支持它 .

  • 1

    我发现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描述的变通方法 . 样本如下所示:

    @Persist
    public Collection <Key> myChildKeys;

    @NotPersistent
    @PolymorphicRelationship(keyField =“myChildKeys”)
    public Collection <TestChild> myChildren;

  • 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;
    }
    

    这是一个糟糕的解决方案,但风暴中的任何端口......

    (还涉及到这个bug,使用接口作为集合类型http://code.google.com/p/datanucleus-appengine/issues/detail?id=207

相关问题