2

親としてのカテゴリと子としてのカテゴリのリストを持つカテゴリ エンティティがあります。宣言は次のとおりです。

@Entity
@Table(name="CATEGORYENTITY")
public class CategoryEntity extends BaseEntity<Long> {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    @Column(name="ID")
    private Long id;

    @Column(name="NAME")
    private String name;

    @Column(name="VIEWSCOUNT")
    private Integer viewsCount;

    @OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    @JoinColumn(name="CATEGORY_ID")
    private List<CategoryEntity> childCategories;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="CATEGORY_ID")
    private CategoryEntity parent;

setters and getters...

保存および更新時には正常に機能しますが、すべてのカテゴリを取得しようとすると...各子に対して親も返されます!!! たとえば、mainCat があり、この mainCat に 4 つの子がある場合、db からすべてのカテゴリを取得すると、4 つの子すべてと驚くべきことに 4 つの mainCat が返されます...奇妙な部分は、返されたオブジェクトが正しく、それらのプロパティが正しい設定と4つのmainCatは同じです!!! 私は何をすべきか?

次のコードを使用して結果を取得します。

public List<E> find(E example, final PagingObject paging, Map<?, ?> filter) throws Exception {
    // create the criteria
    final DetachedCriteria detachedCriteria = createCriteria(filter);
    // add restrictions to the criteria based on example entity
    pruneCriteria(detachedCriteria, example);
    List<E> result = getHibernateTemplate().execute(new HibernateCallback<List<E>>() {
        @SuppressWarnings("unchecked")
        @Override
        public List<E> doInHibernate(Session session) throws HibernateException, SQLException {
            // attach criteria to the session
            Criteria criteria = detachedCriteria.getExecutableCriteria(session);
            // add paging and sort to the criteria
            paginate(criteria, paging);
            List<E> list = criteria.list();
            return list;
        }
    });
    return result;
}
4

1 に答える 1

2

双方向の関連付けには、常に所有者側と逆側があります。所有者側は、関連付けのマッピング方法を定義する側です (@JoinColumn を使用)。逆に、関連付けのマッピング方法を定義してはなりません (冗長になります)。ただし、mappedBy 属性を使用して逆側であることを定義する必要があります。

親子の双方向の関連付けを定義する代わりに、2 つの異なる関連付けを定義しました。

コレクションのマッピングは次のようになります。

@OneToMany(mappedBy = "parent",
           fetch=FetchType.EAGER, 
           cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
private List<CategoryEntity> childCategories;

このような関連付けの両側を EAGER に設定すると、ツリーの 1 つのノードをロードするたびに、Hibernate が強制的にツリー全体をロードすることに注意してください。非常に多数のクエリが実行され、ひどいパフォーマンスになることを覚悟してください。

于 2012-05-15T15:08:18.450 に答える