2010-12-09 4 views
6

이 게시물을 읽은 후 JPA map relation entity parentID이 코드를 적용하려고 시도했지만이 기능이 작동하지 않았습니다. JPA와 동일한 객체에 부모/자식 관계를 매핑하는 방법

내가 항상 실패

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

} 

시험이 줄을 실행

@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 updated parent category 
    assertEquals(1, sportCat.subCategories.size()); 

내 관계에 대한 설정에 따라 최대 절전 모드에서는 하위 범주를 검색 할 수 없으며 이유를 알 수 없습니다. 지금 나는 정말로 내 자신을 쏘지 않을 것이기 때문에 이것이 내 멍청한 것이 아니기를 바란다. (비록 늦어도 피곤할지라도). 그런데 코드에서 공용 변수를 신경 쓸 필요는 없지만 play! (playframework)를 사용하면 캡슐화가 처리됩니다. 사전에 도움을 주셔서 감사합니다

답변

5

그것은 같은 클래스에 매핑 부모와 자식의 문제가 아니다. - 문제는 양방향 관계의 양쪽 끝을 손으로 유지해야한다는 것입니다.

child.setParent(parent) 
parent.addChild(child) 

BTW : 한쪽에만 (데이터베이스에서 관계를 저장하는 책임이있는 것), 저장에 설정하고, 기업도 경우에 따라 작동합니다 다시로드합니다. (그리고 많은 오래된 자습서에서이 더러운 트릭을 발견하게 될 것입니다.) 그러나 제 의견으로는 나쁜 습관입니다. (테스트 케이스에서는, 아이를 저장 한 후에 부모를 다시로드하기 전에 캐시를 정리해야합니다.)

+0

이것은 정확히 내가 한 일입니다. 상위 카테고리에 하위 카테고리를 추가하는 메소드를 추가했습니다. 나는 적절하게 시험을 수정했고 그것은 지금 내가 원하는만큼 정확하게 작동한다. 랄프 대단히 고마워. 그리고 그곳의 모든 사람들에게 감사합니다. – Alain

2

질문에 표시된 코드는 subCategories에 아무 것도 추가하지 않습니다. 빈 목록으로 만 초기화합니다. 내가 제대로 코드를 이해 (읽기)로, Hibernate는하지 않습니다 당신은, 그래서

if (parentCategory != null) { 
    parentCategory.subCategories.add(this); 
} 

같은 것을 필요가 있다고 생각이 있기 때문에 하위 범주를 검색 (할 수 없음) 당신은 아마했다 new Category(sportCat, "Hockey", false).save();

0

를 호출 한 후 빈칸 부모 엔티티를 자식에게 추가하기에 충분할 것으로 기대하지만, 내가 본 것에서 볼 때, Hibernate는 일대 다 관계의 양 끝을 유지해야한다.

즉, 상위 카테고리 목록에 하위 카테고리를 추가해야합니다.

는 여기에 설명 된 것 : 또한 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-parentchild.html#example-parentchild-bidir

그리고 여기 (별도의 캐싱 문제로) : Hibernate @OneToMany with mappedBy (parent-child) relationship and cache problem

관련 문제