【问题标题】:Objectify : Use an entity key juste createdObjectify : 使用刚刚创建的实体键
【发布时间】:2014-02-21 17:27:14
【问题描述】:

我有一个问题,但我没有找到我想做的事情。我正在使用带有 appengine 和 Objectify 的 google Endpoints。我有一个实体 Round 需要刚刚创建的实体 Game 的密钥。因此,当我必须创建新游戏时,我会创建新游戏,然后使用新密钥创建回合。我使用函数 .now() 来保存游戏,但有时游戏没有创建,我创建了一个没有任何游戏的回合。因为它有问题,所以我决定循环获取游戏,直到它被创建,但我知道这是一种非常糟糕的方式,我想知道我可以用什么代替。

之前:

//Create a new game
Game game = new Game(pending_game.getPlayer(),pending_game.getApplicant());
ofy().save().entity(game).now();

//Get the player just created
game = ofy().load().type(Game.class).filter("player1 =", pending_game.getPlayer()).filter("player2 =", pending_game.getApplicant()).first().now();
Key<Game> key_game = Key.create(Game.class, game.getId());          
//We add the new round
Round round = new Round(key_game,generateWord());
ofy().save().entity(round).now();

现在:

//Create a new game
Game game = new Game(pending_game.getPlayer(),pending_game.getApplicant());
ofy().save().entity(game).now();

Key<Game> key_game = null;
//Get the player just created 
for(int i=0; i<5 && key_game == null;i++)
{
    //Get the key of the new game created
    game = ofy().load().type(Game.class).filter("player1 =", pending_game.getPlayer()).filter("player2 =", pending_game.getApplicant()).first().now();
    key_game = Key.create(Game.class, game.getId());
}                   
//We add the new round
Round round = new Round(key_game,generateWord());
ofy().save().entity(round).now();

感谢您的帮助。

【问题讨论】:

  • 除了下面的答案之外,您看到行为的原因是因为查询最终是一致的。每个循环实际上都是在重新保存实体;循环一直持续到查询索引赶上。不用说,这是一种不好的方法。

标签: java google-app-engine entity google-cloud-endpoints objectify


【解决方案1】:

为什么要加载保存的game

Game game = new Game(pending_game.getPlayer(),pending_game.getApplicant());
ofy().save().entity(game).now();    
Key<Game> key_game = Key.create(Game.class, game.getId());          
//We add the new round
Round round = new Round(key_game,generateWord());
ofy().save().entity(round).now();

如果您的目的是确保在继续之前成功保存游戏,use a transaction

要么应用事务中的所有操作,要么不应用它们。

Objectify transaction docs 示例。

【讨论】:

  • 我想使用事务,但问题是如果没有final,我不能使用函数中的参数。我能做些什么 ?声明每个参数的最终副本?
  • 无需创建副本。只需在声明方法时将final 关键字添加到参数中即可。例如,public Article setArticleTags(@Named("url") final String url)
  • 感谢您的帮助,它工作正常。还有一件事。我必须用伪注册一个 Player 并且我希望伪是唯一的。因此,当我想添加一个播放器时,我会检查是否尚未使用伪。但是,如果 2 个人几乎同时服用同一个伪药,它就会起作用。你知道我该如何避免吗?
  • 我能想到的唯一方法是将伪实体的@idHerearesome相关链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-04
相关资源
最近更新 更多