GAE + JDO:在谷歌应用引擎java中删除子对象导致问题

时间:2013-11-09 11:30:34

标签: java google-app-engine jdo

我在GAE中使用JDO。我有两个具有一对多关系的JDO类。父类是

@PersistenceCapable(detachable="true")
@FetchGroup(name="childerns", members={@Persistent(name="aliasName")})
public class IdentityProvider {

@PrimaryKey
@Persistent
private String url;
@Persistent
private String domainName;
@Persistent
@Element(dependent = "true")
private ArrayList<AliasDomain> aliasName = new ArrayList<AliasDomain>();

}

子课程是

@PersistenceCapable(detachable = "true")
public class AliasDomain {
@Persistent
private String url;
@Persistent
private String aliasName;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
}

我只是在两个实体上执行CURD操作。首先,我创建父实例,然后我创建子实例

 public void addAliasDomain(AliasDomain domain) {
    String url = domain.getUrl();
    PersistenceManager pm = PMFSingleton.get().getPersistenceManager();
    IdentityProvider idp = null;
    Transaction txn = null;
    try {
        txn = pm.currentTransaction();
        txn.begin();
        pm.getFetchPlan().addGroup("childerns");
        idp = pm.getObjectById(IdentityProvider.class, url);
        idp = pm.detachCopy(idp);
        idp.getAliasName().add(domain);
        pm.makePersistent(idp);
        txn.commit();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if ( txn.isActive() ) {
            txn.rollback();
        }
        pm.close();
    }
}

我删除任何子实例时创建了我的问题。正如您从上面的函数中看到的,我将子项链接到父项(意味着将子对象添加到arrayList中)。因此,当删除子项时,父项中的引用不会被删除,所以在父项对象的超时时间我得到了异常,如

Object of type "user.oauth.jdo.model.IdentityProvider" and identity "yahoo.com" was not     detached correctly. Please consult the log for any possible information.
org.datanucleus.exceptions.NucleusUserException: Object of type    "user.oauth.jdo.model.IdentityProvider" and identity "yahoo.com" was not detached    correctly. Please consult the log for any possible information.
at org.datanucleus.state.JDOStateManager.detachCopy(JDOStateManager.java:2942)
at org.datanucleus.ObjectManagerImpl.detachObjectCopy(ObjectManagerImpl.java:2591)
at   org.datanucleus.api.jdo.JDOPersistenceManager.jdoDetachCopy(JDOPersistenceManager.java:1145 )
    at   org.datanucleus.api.jdo.JDOPersistenceManager.detachCopy(JDOPersistenceManager.java:1174)
at user.oauth.data.broker.IDPJDOBroker.retrieveDomainList(IDPJDOBroker.java:49)

IDPJDOBroker中的函数retreiveDomainList的代码是

 public List retrieveDomainList() {
    PersistenceManager pm = PMFSingleton.get().getPersistenceManager();
    Query query = pm.newQuery(IdentityProvider.class);
    List<IdentityProvider> list = null;
    List<IdentityProvider> detachedList = null;
    IdentityProvider idp = null;
    try {
        pm.getFetchPlan().addGroup("childerns");
        list = (List<IdentityProvider>) query.execute();
        detachedList = new ArrayList<IdentityProvider>();
        for(IdentityProvider obj : list){
            idp = pm.detachCopy(obj);
            OAuthJDOBroker broker = new OAuthJDOBroker();
            int actUsers = 0;
            if ( idp.getHistory() != null && idp.getHistory().size() > 0) {
                actUsers = broker.calculateActiveUser(idp.getUserActiveDuration(),idp.getDomainName());
            }
            idp.setActiveUsers(actUsers);
            detachedList.add(idp);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        query.closeAll();
        pm.close();
    }
    return detachedList;
}

请告诉我该怎么办?在JDO中删除孩子是不可能的?如果有可能那么如何正确地做到这一点。

1 个答案:

答案 0 :(得分:0)

我刚看到这个,但是如果有人到达这里,要删除一对多关系中的子对象,你必须从父对象中删除引用,子对象将被“透明地”删除