2011-06-18 8 views
4

CriteriaBuilderを介してネストされたオブジェクトプロパティを保持する方法はありますか?OpenJPA criteriaBuilderネストされたオブジェクトプロパティの取得

ここには小さなケースがあります。だから、

@Entity 
public class X { 
     private Object Y; 

     // getters, setters... 
} 

@Entity 
public class Y { 
     private String Z; 

     // getters, setters... 
} 

CriteriaBuilderを使用した場合、我々はすなわち、ルートとしてXを使用します。

@PersistenceContext 
private EntityManager entityManager; 

//..... 

Root<X> rootObj = criteriaBuilder.from(X.class); 
CriteriaQuery<X> select; 

String param1 = X.getY().getZ(); 

// initializing predicate, default value is TRUE 
Predicate predicate1 = criteriaBuilder.isNull(null); 

// construct search predicate which fails miserably due to IllegalArgumentExecption 
if (X != null) { 
predicate1 = criteriaBuilder.and(predicate1, criteriaBuilder.equal(rootObj.<String> get("Y.Z"), param1));} 

、私の悲しみはこれです - >get("Y.Z")

CriteriaBuilderは反射的Zを取得するために知っていません(しかし、それはYを解決することができます)。 get()からZを直接取得する方法はありますか?

JPQLを使用する以外にも、私は非常に嫌いな方法が考えられます。つまり、OpenJPAがXとして@TransientプロパティをZとして公開しているとします。本当に悪い考えのように聞こえる:私は本質的にオブジェクトグラフを手作業で平坦化して、複雑なグラフやエラーの公表に必要な時間を数えずに、エンティティBean内に不要なゴミを導入することになる。たくさんの方法)。

これを行う方法はありますか?任意のアイデアが評価されます。

答えて

7

解決法は驚くほど簡単です。本当に醜いですが、うまくいきます。

predicate1 = criteriaBuilder.and(predicate1, criteriaBuilder.equal(rootObj.get("Y").<String> get("Z"), param1));} 

もっと洗練された解決法があるかどうかは本当にわかりません。

+2

メタモデルを使用すると、次のようになります。 'predicate1 = criteriaBuilder.and(predicate1、criteriaBuilder.equal(root.hj.get(X_.Y).get(Y_.Z)、param1));}' – gertas

+0

メタモデルクラスを使用しないでください。私はこの予期せぬ連鎖の構文、特にチェーン内の最後のゲッターの型宣言を個人的に見つけました。おそらく、フードの下での反射を使用して、よりきれいに定義することができます(そして、簡単に使用することができます)。 – quantum

関連する問題