Objectify BATCH删除无效

时间:2012-02-29 08:20:29

标签: java google-app-engine google-cloud-datastore objectify

我下面有一个DAO,每个实体的交易删除 批量。 一次删除一个实体就可以了。

批量删除无论如何都没有效果: 下面的代码是简单明了的IMO,但调用 deleteMyObjects(Long [] ids) - 调用删除(Iterable keysOrEntities) Objectify - 没有效果!

public class MyObjectDao {

    private ObjectifyOpts transactional = new ObjectifyOpts().setBeginTransaction(true);

    private ObjectifyOpts nonTransactional = new ObjectifyOpts().setBeginTransaction(false);

    private String namespace = null;

    public MyObjectDao(String namespace) {
        Preconditions.checkNotNull(namespace, "Namespace cannot be NULL");
        this.namespace = namespace;
    }

    /**
     * set namespace and get a non-transactional instance of Objectify
     * 
     * @return
     */
    protected Objectify nontxn() {
        NamespaceManager.set(namespace);
        return ObjectifyService.factory().begin(nonTransactional);
    }

    /**
     * set namespace and get a transactional instance of Objectify
     * 
     * @return
     */
    protected Objectify txn() {
        NamespaceManager.set(namespace);
        Objectify txn =  ObjectifyService.factory().begin(transactional);
        log.log(Level.FINE, "transaction <" + txn.getTxn().getId() + "> started");
        return txn;
    }

    protected void commit(Objectify txn) {
        if (txn != null && txn.getTxn().isActive()) {
            txn.getTxn().commit();
            log.log(Level.FINE, "transaction <" + txn.getTxn().getId() + "> committed");
        } else {
            log.log(Level.WARNING, "commit NULL transaction");
        }
    }

    protected void rollbackIfNeeded(Objectify txn) {
        if (txn != null && txn.getTxn() != null && txn.getTxn().isActive()) {
            log.log(Level.WARNING, "transaction <" + txn.getTxn().getId() + "> rolling back");
            txn.getTxn().rollback();
        } else if (txn == null || txn.getTxn() == null) {
            log.log(Level.WARNING, "finalizing NULL transaction, not rolling back");
        } else if (!txn.getTxn().isActive()) {
            log.log(Level.FINEST, "transaction <" + txn.getTxn().getId() + "> NOT rolling back");
        }
    }


    public void deleteMyObject(Long id) {
        Objectify txn = null;
        try {
            txn = txn();
            txn.delete(new Key<MyObject>(MyObject.class, id));
            commit(txn);
        } finally {
            rollbackIfNeeded(txn);
        }
    }

    public void deleteMyObjects(Long[] ids) {
        Objectify txn = null;
        List<Key<? extends MyObject>> keys = new ArrayList<Key<? extends MyObject>>();
        for (long id : ids) {
            keys.add(new Key<MyObject>(MyObject.class, id));
        }
        try {
            txn = txn();
            txn.delete(keys);
            commit(txn);
        } finally {
            rollbackIfNeeded(txn);
        }
    }
}

当我调用deleteMyObjects(Long [])时,我在下面的日志中看不到任何可疑内容。事务提交正常没有错误。但数据不受影响。循环通过相同的ID列表并一次删除一个对象,效果很好。

Feb 29, 2012 8:37:42 AM com.test.MyObjectDao txn
FINE: transaction <6> started
Feb 29, 2012 8:37:42 AM com.test.MyObjectDao commit
FINE: transaction <6> committed
Feb 29, 2012 8:37:42 AM com.test.MyObjectDao rollbackIfNeeded
FINEST: transaction <6> NOT rolling back

但数据未更改并存在于数据存储区中!?!?!

欢迎任何帮助。

更新

进入Objectify代码,我想知道这与命名空间有什么关系?客观化的代码就在这里:

@Override
public Result<Void> delete(Iterable<?> keysOrEntities)
{
    // We have to be careful here, objs could contain raw Keys or Keys or entity objects or both!
    List<com.google.appengine.api.datastore.Key> keys = new ArrayList<com.google.appengine.api.datastore.Key>();

    for (Object obj: keysOrEntities)
        keys.add(this.factory.getRawKey(obj));

    return new ResultAdapter<Void>(this.ads.delete(this.txn, keys));
}

当我在debug中检查 this.factory.getRawKey(obj)时,我注意到该键的命名空间为空。然而, NamespaceManager.get()会返回正确的命名空间!?

enter image description here

1 个答案:

答案 0 :(得分:3)

创建密钥时未设置命名空间。

必须在创建密钥之前设置名称空间!

所以重写这样,解决了我的问题:

public void deleteMyObjects(Long[] ids) {
    Objectify txn = null;
    try {
        txn = txn();
        List<Key<MyObject>> keys = new ArrayList<Key<MyObject>>();
        for (long id : ids) {
            keys.add(new Key<MyObject>(MyObject.class, id));
        }
        txn.delete(keys);
        commit(txn);
    } finally {
        rollbackIfNeeded(txn);
    }
}

然后我称之为:

new MyObjectDAO("somenamespace").delete({ 1L, 34L, 116L });
相关问题