【发布时间】:2014-01-01 05:01:19
【问题描述】:
执行摘要:
当我从播放框架的“Finder”中取回一个对象时,该对象的 ManyToOne 字段已正确填充,但它指向自身的对象具有错误为 null 的 OneToMany 字段。
在我的应用程序(“场景存储库”)中,一个场景有一个游戏,而游戏有很多场景。
当我“找到”一个场景时
Scenario retrieved_scenario = Scenario.find.where().eq("name", "Test Scenario").findUnique();
游戏对象 (retrived_scenario.game) 缺少它的场景:
assertNotNull(retrieved_scenario); // passes
assertEquals("CM Test", retrieved_scenario.game.name); //passes
assertNotNull("retrived scenario's game's scenarios", retrieved_scenario.game.scenarios); // fails
但如果我使用游戏的 find 来检索游戏本身,并测试它的场景列表,那就没问题了。
我做错了什么?
详情:
我有一个名为 Game 的 ebean 持久对象,它可以有许多场景:
import play.db.ebean.*;
import com.avaje.ebean.*;
@Entity
public class Game extends Model {
@Id
public String name;
@OneToMany
public List<Scenario> scenarios;
Scenario 对象(也是 ebean 持久化的)在创建时将其自身添加到游戏的场景列表中:
@Entity
public class Scenario extends Model {
@Id
public String name;
@ManyToOne
public Game game;
@OneToOne
public User author;
public Scenario(String name, String game_name, String author_name) {
Logger.info(String.format("Constructing scenario '%s' of type '%s'", name, game_name));
this.name = name;
this.game = Game.find.where().eq("name", game_name).findUnique();
Logger.info(String.format("...found it's game: '%s', which has %d scenarios", this.game.name, this.game.scenarios.size()));
this.game.scenarios.add(this);
Logger.info(String.format("now ... it's game has %d scenarios", this.game.scenarios.size()));
this.author = User.find.where().eq("username", author_name).findUnique();
}
public static Scenario create(String name, String game_name, String author_name) {
Logger.info(String.format("Creating scenario '%s' of '%s' by '%s'", name, game_name, author_name));
Scenario it = new Scenario(name, game_name, author_name);
it.save();
it.game.save();
it.game.saveManyToManyAssociations("scenarios"); // doesn't help (or apparently hurt)
return it;
}
public static Scenario.Finder<String,Scenario> find =
new Scenario.Finder<String,Scenario>(String.class, Scenario.class);
}
但是,当我使用此查找器“找到”一个场景时,相关游戏的场景并未初始化:
@Test
public void createAndRetrieveScenario() {
Logger.info("testing createAndRetrieveScenario...");
Logger.info("setting up...");
Game created_game = Game.create("CM Test");
Logger.info("creating scenario...");
Scenario created_scenario = Scenario.create("Test Scenario", "CM Test", "GreenAsJade");
assertNotNull(created_scenario);
assertEquals("Test Scenario", created_scenario.name);
assertEquals("CM Test", created_scenario.game.name);
assertNotNull(created_scenario.game.scenarios);
Logger.info("checking that the scenario was added properly to the game...");
Game retrieved_game = Game.find.where().eq("name", "CM Test").findUnique();
assertNotNull("retrieved game", retrieved_game);
assertNotNull("retrieved game scenarios", retrieved_game.scenarios);
Logger.info("retrieving...");
Scenario retrieved_scenario = Scenario.find.where().eq("name", "Test Scenario").findUnique();
assertNotNull(retrieved_scenario);
assertEquals("Test Scenario", retrieved_scenario.name);
assertEquals("CM Test", retrieved_scenario.game.name);
Logger.info("checking scenario's game's scenarios...");
assertNotNull("retrived scenario's game's scenarios", retrieved_scenario.game.scenarios);
assertFalse(retrieved_scenario.game.scenarios.isEmpty());
}
IE 最后两个断言失败。但到目前为止,一切似乎都按我预期的方式工作。您可以在其中看到的所有日志消息都报告“您所期望的”...除了有趣的是没有与 find() 操作关联的 Scenario 构造函数调用,它确实返回了一个 Scenario!
我在这里做错了什么?
谢谢!
额外信息:
应用 SpartanElite 建议的更改并登录 SQL 后运行测试的输出如下:http://pastebin.com/BbMrCtZL
-
这些是产生结果的 ScenarioTest.java Scenario.java 和 Game.java 的确切来源。
-整件事的压缩包在这里:http://bit.ly/onetomanytest。您应该能够提取它、cd 到它、运行 play 并执行仅测试 models.ScenarioTest 以查看结果。除了这些东西和一个用户模型之外,什么都没有。
【问题讨论】:
-
注意:mappedBy 没有帮助:@OneToMany(mappedBy="game", cascade = CascadeType.ALL) public List
场景; -
而且 - 奇怪的是,即使 Game 中的场景列表有启动器,assertNotNull 也会失败: public List
scenario = new ArrayList ();
标签: java jpa playframework-2.0 one-to-many ebean