1

GAE で JDO を使用しています。1 対多の関係を持つ 2 つの 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で子を削除することはできませんか? 可能であれば、適切に行う方法。

4

1 に答える 1

1

私はこれを見たばかりですが、誰かがここに到着した場合、1対多の関係で子オブジェクトを削除するには、親からの参照を削除する必要があります。子オブジェクトは「透過的に」削除されます

于 2015-01-06T20:16:27.253 に答える