阅读此帖JPA map relation entity parentID后,我尝试将此应用于我的代码,但这对我不起作用。
这是我在对象中的代码
@Entity
public class Category extends Model {
public static final int EASY = 1;
public static final int MEDIUM = 2;
public static final int HARD = 3;
public static final int VERRY_HARD = 4;
public String name;
public String fullName;
public boolean active;
public Date createdOn;
public int difficulty;
@ManyToOne
@JoinColumn(name = "FK_PARENT_CATEGORY")
public Category parentCategory;
@OneToMany(mappedBy="parentCategory", cascade = CascadeType.ALL)
public List<Category> subCategories;
public Category(Category parentCategory, String name, boolean active) {
this.name = name;
this.active = active;
this.parentCategory = parentCategory;
this.subCategories = new ArrayList<Category>();
this.createdOn = new Date();
this.difficulty = Category.EASY;
this.fullName = name;
if (parentCategory != null)
this.fullName = parentCategory.fullName + "/" + this.fullName;
}
现在这是我运行的测试
@Test
public void testParentAndSubCategories() {
//Create the parent category
new Category(null, "Sport", true).save();
Category sportCat = Category.find("byName", "Sport").first();
//Test the newly created parent category state
assertNotNull(sportCat);
assertEquals("Sport", sportCat.name);
assertEquals(true, sportCat.active);
assertEquals("Sport", sportCat.fullName);
assertNull(sportCat.parentCategory);
assertEquals(0, sportCat.subCategories.size());
//Create the subCategory
new Category(sportCat, "Hockey", false).save();
Category hockeyCat = Category.find("byName", "Hockey").first();
// Test the newly created sub category
assertNotNull(hockeyCat);
assertEquals("Hockey", hockeyCat.name);
assertEquals(false, hockeyCat.active);
assertEquals("Sport/Hockey", hockeyCat.fullName);
assertNotNull(hockeyCat.parentCategory);
assertEquals("Sport", hockeyCat.parentCategory.name);
assertEquals(0, sportCat.subCategories.size());
//Fetch new values for parent category
sportCat = Category.find("byName", "Sport").first();
// Test updated parent category
assertEquals(1, sportCat.subCategories.size());
assertEquals("Hockey", sportCat.subCategories.get(0).name);
}
此测试线始终失败。
// Test updated parent category
assertEquals(1, sportCat.subCategories.size());
根据我对我的关系的设置,Hibernate无法检索子类别,我不知道为什么。现在我真的希望这对我来说不是一件愚蠢的事情,因为我会自己拍摄(即使已经很晚了,我已经累了)。顺便说一下,不要介意代码中的公共变量,我正在使用play!(playframework),它负责封装。在此先感谢您的任何帮助
答案 0 :(得分:6)
将父级和子级映射到同一个类不是问题。 - 问题是你需要手工维护双向关系的两端。
child.setParent(parent)
parent.addChild(child)
顺便说一句:只在一侧设置它(负责在数据库中存储关系的那个),存储和重新加载实体在某些情况下也会起作用。 (你会在许多旧教程中找到这个肮脏的技巧)。但在我看来,这是不好的做法。 (在您的测试用例中,在保存子项后重新加载父项之前,需要清理缓存。)
答案 1 :(得分:3)
问题中显示的代码不会向subCategories
添加任何内容。它只用空列表初始化它。我认为你需要像
if (parentCategory != null) {
parentCategory.subCategories.add(this);
}
所以,正如我理解(并阅读)你的代码一样,Hibernate没有(不能)检索子类别,因为它在调用new Category(sportCat, "Hockey", false).save();
之后保持空白
答案 2 :(得分:0)
你可能期望足够将父实体添加到孩子身上,但从我所看到的,Hibernate要求你保持一对多关系的两端。
换句话说,您必须将子类别添加到父类别列表中。
此处(还有额外的缓存问题): Hibernate @OneToMany with mappedBy (parent-child) relationship and cache problem