2012-09-16 21 views
2

我使用GAE 1.7.0 w/JDO(DataNucleus)。 當我使用集合屬性持久保存類時,不會從數據存儲中刪除已刪除的集合成員。我從分離的副本中刪除集合成員。新成員正確添加,現有的成員沒有刪除,導致我的收藏只增長。JDO(DataNucleus)收集成員不會被刪除

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true") 
public class Parent{ 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Long id; 

    @Persistent(defaultFetchGroup="true", dependentElement="true") 
    private List<Child> children = new ArrayList<Child>(0); 

} 

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true") 
public class Child implements Serializable { 

    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") 
    private String id; 

    @Persistent 
    @Extension(vendorName="datanucleus", key="gae.parent-pk", value="true") 
    private String parentId; 
    .... 
} 

... 
parent = pm.detachCopy(resultFromQuery); 
// parent looks correct in dubugger: all children are fetched (and detached) 
.... 
parent.getChildren().clear(); 
parent.getChildren().addAll(newChildren); 
for (Child child: parent.getChildren()) 
    child.setParentId(KeyFactory.createKeyString("Parent", parent.getId())); 
// parent looks good in the debugger: old children were removed and new ones added 
... 
PersistenceManager pm = PMF.get().getPersistenceManager(); 
try { 
    pm.currentTransaction().begin(); 
    pm.makePersistent(parent); 
    pm.currentTransaction().commit(); 
} catch (Exception e) { 
} finally { 
    if (pm.currentTransaction().isActive()) 
     pm.currentTransaction().rollback(); 
    if (!pm.isClosed()) 
     pm.close(); 
} 
// problem in datastore: new children were created, old ones not removed 

我注意到,如果我做的查詢,刪除,堅持一個交易(不拆卸的對象),那麼問題就解決了。這是一個好的臨時解決方法,但我仍然想對分離的對象進行更新。

+0

同樣的問題DataNucleus artifactId datanucleus-core 3.1.3和Google App Engine 1.9.21。 – CoolDude

回答

1

我不是JDO的專家,但在這裏不用....

每個Parent及其相關Child實體相同的實體小組。因此,您需要在事務中執行數據存儲更新,因爲給定的實體組可能不會以每秒大約一次的頻率更新。另外,在一個交易中,增強魔術將起作用:隱藏,添加Java字節碼,它將處理諸如添加和移除子項以及設置字段值等內容。

如果你不想這樣做,那麼一種方法是不要在Parent中存儲一個Child實體列表;改爲存儲Child ID和/或主鍵列表。這將導致每個Child都在其自己的實體組中。但即使如此,您仍然可以每秒更新每個Parent(列表)。

+0

不確定,但是...如果您應用JDO分離模式,則實際上您將在事務中執行數據存儲更新。在事務開始之前,您只需在分離的對象上「準備」更新:http://db.apache.org/jdo/attach_detach.html – peternees