8

この投稿を読んだ後、JPAマップリレーションエンティティ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)を使用しており、カプセル化を処理します。助けてくれてありがとう

4

3 に答える 3

6

親と子を同じクラスにマッピングすることは問題ではありません。- 問題は、手動で双方向関係の両端を維持する必要があることです。

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

ところで:一方の側(データベースに関係を保存する責任がある側)にのみ設定すると、エンティティの保存とリロードが機能する場合もあります。(そして、多くの古いチュートリアルでこの汚いトリックを見つけることができます)。しかし、私の意見では、それは悪い習慣です。(テストケースでは、子が保存された後に親をリロードする前に、キャッシュを消去する必要があります。)

于 2010-12-09T11:23:36.800 に答える
3

あなたの質問に示されているコードは、に何も追加しませんsubCategories。空のリストで初期化するだけです。次のようなものが必要だと思います

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

したがって、コードを正しく理解している (そして読んでいる) ように、Hibernate はサブカテゴリを取得しません (できません)。new Category(sportCat, "Hockey", false).save();

于 2010-12-09T05:27:19.367 に答える
0

おそらく、親エンティティを子エンティティに追加するだけで十分だと思っていたでしょうが、私が見た限りでは、Hibernate では 1 対多の関係の両端を維持する必要があります。

つまり、子カテゴリを親のカテゴリ リストに追加する必要があります。

ここで説明されています: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-parentchild.html#example-parentchild-bidir

また、ここでも(追加のキャッシュの問題があります): mappedBy(親子)関係とキャッシュの問題を伴うHibernate @OneToMany

于 2010-12-09T08:31:46.377 に答える