java - 在创建新的 JDO 实体之前,如何确保 Google AppEngine 中不存在该实体?

标签 java google-app-engine jdo

我有一个 JDO 卡实体,具有外部生成的 key (从物理卡读取)。它链接到一个用户实体,该实体与卡实体同时创建。当我读取卡片并调用方法时,我希望 AppEngine 返回之前创建的卡片和用户,或者创建一个新的卡片和用户。但是,如果我快速连续调用该方法两次,最终会覆盖卡实体并创建两个用户身份。

这是我的代码(我已删除 getter 和 setter):

CardEntity.java

@PersistenceCapable public class CardEntity {

    @PrimaryKey
    private Key Id;
    @Persistent
    @Unowned
    private UserEntity user;
}

UserEntity.java

@PersistenceCapable
public class CustomerEntity {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key; 
    @Persistent 
    private String name;
}

Controller.java 中的方法

    public UserEntity getOrCreateUser(String id) {
        CardEntity cardEntity;
        UserEntity userEntity;
        Query query;

        PersistenceManager mgr = getPersistenceManager();
        Transaction tx = mgr.currentTransaction();
        boolean complete = false;
        while (!complete) {
            try {
                tx.begin();

                query = mgr.newQuery(CardEntity.class);
                query.setUnique(true);
// rootkey is a key for a CardEntity that I am using as the parent for
// all CardEntities, so they are in the same enitity group, as a hack
// to try to solve this problem.
                Key key = KeyFactory.createKey(rootKey, "CardEntity", id);
                query.setFilter("id == :id");
                cardEntity = (CardEntity) query.execute(key);
                if (CardEntity == null) {
                    cardEntity = new CardEntity();
                    cardEntity.setId(key);
                    userEntity = new UserEntity();
                    mgr.makePersistent(userEntity);
                    nfcCardEntity.setUser(UserEntity);
                    mgr.makePersistent(cardEntity);
                    CardEntity rootCardEntity = 
                                        (CardEntity) mgr.getObjectById(CardEntity.class, rootKey);
                    rootCardEntity.setUser(userEntity);
// this is another hack to ensure that something changes in this transaction
// so that if there's a conflict, it will be rolled back
                    mgr.makePersistent(rootCardEntity);
                } else {
                    userEntity = cardEntity.getUser();
                }
                tx.commit();
            } finally {
                if (tx.isActive()) {
                    tx.rollback();
                } else {
                    complete = true;
                }
            }
        }
        mgr.close();
        return userEntity;
    }

我尝试了很多方法,但最终经常会创建多个 UserEntities。上面的代码将所有 CardEntities 放在一个实体组中(由 rootkey 定义),我什至还对根实体进行了修改。这似乎没有帮助。

有什么提示、指示吗?

最佳答案

查找:getObjectById并捕获异常。

getObjectById 具有很强的一致性,这意味着,如果对象在创建后就存在,它应该立即返回该对象。 查询仅具有最终一致性,这意味着它可能在创建后找到,但也可能没有。

如果找不到getObjectById,则会抛出一个 Entity not found 异常,该异常可以单独捕获和处理。

关于java - 在创建新的 JDO 实体之前,如何确保 Google AppEngine 中不存在该实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14505902/

相关文章:

java - Jdo错误重复键

java - <ProjectName.ProjectUI 作为我的 Netbeans java OS X 应用程序的名称很糟糕

java - 是否有任何工具或库可以将 YAML 或 XML 文件转换为 Java 代码?

java - GWT Node 或 Element 监听 onAttach 事件

multithreading - 是否有适用于 Python 2.7 的 ereporter 版本

node.js - 如何使 App Engine 标准上的 Node JS 日志像 Python 一样好

java - 存在一致性问题

java - 将不同的 GWT 实现返回到 GAE 上的移动和桌面客户端

java - JDO数据核: Annotator @Column(jdbcType ="") not working

java - 使用 JDO 在 Google 数据存储区中创建实体时出错