2011-01-19 108 views
1

我正在研究基於GAE的應用程序,它使用JDO訪問數據存儲。我需要實現持久對象之間的多態關係。Google App Engine中的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子類之一的一個實例。但是:

JDOObjectNotFoundException異常被拋出(javax.jdo.JDOObjectNotFoundException:沒有這樣的對象FailedObject:...)。

FatalNucleusUserException則拋出異常(org.datanucleus.store.appengine.FatalNucleusUserException:收到的請求以找到一種父但在提供的標識符的一個目標是一個關鍵的對兒童種類的字符串表示)

什麼是正確的方式來檢索其他實體中引用的子類之一的實例?

UPDATE:我發現this線程在GAE谷歌組,但坦率地說,它並沒有幫助我很多。

+0

由於目前沒有多態支持,我提出了一種解決方法 - 存儲有關引用對象的類型。 – Kel 2011-01-21 06:45:42

回答

0

App Engine的JDO層目前不支持多態。事實上,我不確定JDO是否支持它。

1

我發現JDO和App Engine的同樣的問題,所以我就開始實現了一個解決方法爲這個項目。 https://code.google.com/p/datanucleus-appengine-patch/ 我對我現在的代碼的第一次測試看起來不錯,請隨時嘗試一下,給我一些反饋。

其實我的解決辦法可能解決您的問題2種方式。

  1. 我實現了一個getObjectById(class,id),它也查找提供的類的實例的種類。
  2. 如果oid的類型爲com.google.appengine.api.datastore.Key,那麼我實現了一個getObjectById(oid),它執行一些特殊的查找處理,然後它會找出返回的正確類。
  3. 我添加了一個新的註解@PolymorphicRelationship,它可以很容易地處理App Engine描述的解決方法,並存儲密鑰。如下圖所示樣品:
@Persist 
public Collection<Key> myChildKeys; 

@NotPersistent 
@PolymorphicRelationship(keyField ="myChildKeys") 
public Collection<TestChild> myChildren; 
+0

謝謝,目前我正在調查datanucleus-appengine-patch。 – Kel 2011-01-23 18:31:10

1

我使用這個,而癌變又臭反模式繞過這個限制JDO /應用程序引擎。

@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

相關問題