如何使用JPA将父/子关系映射到同一对象上

Ala*_*ain 8 recursion hibernate jpa playframework

阅读此帖后JPA地图关系实体parentID我尝试将此应用于我的代码,但这对我不起作用.

这是我在Object中的代码

@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;

}
Run Code Online (Sandbox Code Playgroud)

现在这是我跑的测试

@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);

}
Run Code Online (Sandbox Code Playgroud)

这条测试线总是失败.

// Test updated parent category
    assertEquals(1, sportCat.subCategories.size());
Run Code Online (Sandbox Code Playgroud)

基于我对我的关系的设置,Hibernate无法检索子类别,我不知道为什么.现在我真的希望这对我来说不是一件愚蠢的事情,因为我会自己拍摄(即使已经很晚了,我已经累了).顺便说一下,不要介意代码中的公共变量,我正在使用play!(playframework),它负责封装.在此先感谢您的帮助

Ral*_*lph 6

将父级和子级映射到同一个类不是问题. - 问题是你需要手工维护双向关系的两端.

child.setParent(parent)
parent.addChild(child)
Run Code Online (Sandbox Code Playgroud)

BTW:只在一侧设置它(负责在数据库中存储关系的那个),存储和重新加载实体也会在某些情况下起作用.(你会在许多旧教程中找到这个肮脏的技巧).但在我看来,这是不好的做法.(在您的测试用例中,在保存子项后重新加载父项之前,需要清理缓存.)