1

データベースにツリーを構築するこのオブジェクトがあります。各ノードはその親を指すか、null です。この関係を双方向にする必要があるため、各ノードはその子ノードも認識します。ノードが削除されると、IS_ACTIVE が false に設定されます。IS_ACTIVE が true に設定された子のみが読み込まれるように、これらの注釈を変更するにはどうすればよいですか?

@Entity
@Table(name = "node")
public class Node {
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "PARENT_NODE_ID")
  private Node parentNode;

  @OneToMany(mappedBy = "parentNode", fetch = FetchType.LAZY)
  private Set<Node> childrenNodes;

  @Column(name = "IS_ACTIVE", nullable = false)
  private boolean isActive;

   //other fields that shouldn't matter left out.
}

現在、単体テストは同じトランザクションで実行されているため、session.refresh(node) を使用して子ノードをまったくロードする必要がありますが、すべての子ノードをロードするたびに、フィルタと where 句を無視します。

このクラスに注釈を付けて、子がアクティブな子のみをロードする正しい方法は何ですか?

子供たちが怠け者であるかどうかは問題ですか?

*これに対する回答を検索していることに注意してください。

例として、この質問は関連しているように見えますが、解決策は機能しません。私の結合は自己参照であるため、それは異なると思います...しかし、それは私が見逃している何かが原因である可能性があります。@OneToMany 関連付けの結果をフィルタリングするための注釈

4

1 に答える 1

1

「IS_ACTIVE が true に設定された子のみがロードされる」と言うときは、ビジネス ルールを定義しているため、何らかの方法で Hibernate にそれに従うように指示する必要があります。

「session.get(object)」と「session.refresh(object)」を使用して、Hibernate にエンティティを取得するように要求していますが、Hibernate にビジネス ルールに従うように指示していません。

簡単に言えば、問題を解決するには 2 つの方法があります。

(1): Hibernate にすべての「childrenNode」をフェッチさせます。その後、別のメソッドを記述して、IS_ACTIVE = true の子のみを返すことができます。何かのようなもの:

public Set<Node> getActiveChildrenNodes(Node n){
   Set<Node> result = new HashSet(); 
   for(Node cn : n.getChildrenNodes()){
        if(cn.isActive)
        result.add(cn);
    }
   return result;
}

ご覧のとおり、データベースに複数のレコードがある場合、このアプローチはパフォーマンスが低下する可能性があります。

(2): より良いオプションは、IS_ACTIVE = true の子のみをロードすることです。したがって、次のように書くことができます。

public List getActiveChildrenNodes(Node n, Session s){
    return = session
        .createQuery("FROM Node WHERE Node.id = :pId AND Node.childrenNodes.isActive : pIsActive")
        .setParameter("pId", n.getId())
        .setParameter("pIsActive", true)
        .list();
}

いくつかの方法がありますが、この説明が役に立てば幸いです。

乾杯、

于 2013-03-29T23:03:30.887 に答える