2016-08-19 5 views
3

クエリ実行にSpringDataを使用して、QueryDSLに基づいた動的フィルタコンポーネントを作成しています。したがって、Predicateインスタンスを受信データ広告から作成してQueryDslPredicateExecutorに渡します。エンティティ属性に動的にアクセスするには、エンティティクラスに型名PathBuilderと入力します。要素の複数の属性によるフィルタコレクション - QueryDSL

class Offer { 
    List<LanguageToName> names; 
} 
class LanguageToName { 
    String name; 
    String language; 
} 

私は属性を持つ彼らのコレクションname要素を持っているOffer entites、「ABC」を照会しようとすると、以下のように、私は単に述語を作成します:

は、以下の(簡体字)のコードを考えてみましょう

pathBuilder.getCollection("names", LanguageToName.class).any().getString("name") 
    .like("%" + fieldData.getFieldValue() + "%"); 

しかし、私は、PathBuilderを使用して、含まれているオブジェクトの複数の属性によってコレクションをフィルタリングするソリューションを考え出すことができませんでした。上記のコードを.and()に追加し、pathBuilder変数を使用して再度コレクションにアクセスすると、結果として望ましくない結果をもたらすAND EXISTS...というSQLクエリを追加することと同等の結果が得られます。私もgetCollection().contains()を使用しようとしましたが、そのような場合を記述するExpression<LanguageToName>を作成できませんでした。

Predicateを作成して、コレクションの要素の複数の属性、つまり照会されたエンティティの項目によってエンティティをフィルタリングする方法はありますか?

答えて

0

私のプロジェクトで同じ問題が発生しました。 私の回避策は、手動でサブクエリをビルドすることです。

@Entity 
@Table(name = "Offer") 
public class Offer { 

    @Id 
    String id; 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "offer") 
    List<LanguageToName> names; 
} 

@Entity 
@Table(schema = "dcsdba", name = "Language_To_Name") 
public class LanguageToName { 

    @Id 
    String id; 

    @ManyToOne(fetch= FetchType.LAZY) 
    @JoinColumn(name="Offer_id") 
    private Offer offer; 

    String name; 
    String language; 
} 

いずれかに単純なクエリ():

select 
    offer0_.id as id1_7_ 
from 
    offer offer0_ 
where 
    exists (
     select 
      1 
     from 
      dcsdba.language_to_name names1_ 
     where 
      offer0_.id=names1_.offer_id 
      and names1_.name=? 
    ) 

サブクエリへ

BooleanExpression namesFilter = QOffer.offer.names.any().name.eq("Esperanto"); 

マップ:

をあなたの両方のクラスをエンティティとしてマッピングされていると仮定すると

BooleanExpression namesFilter = JPAExpressions.selectOne() 
      .from(languageToName) 
      .where(languageToName.offer.eq(QOffer.offer) 
        .and(languageToName.name.eq("Esperanto"))) 
      .exists(); 

マップへ:

select 
    offer0_.id as id1_7_ 
from 
    offer offer0_ 
where 
    exists (
     select 
      1 
     from 
      dcsdba.language_to_name languageto1_ 
     where 
      languageto1_.offer_id=offer0_.id 
      and languageto1_.name=? 
    ) 

完全に以前のSQLと一致します。 次のような条件を追加できます。

BooleanExpression namesFilter = JPAExpressions.selectOne() 
      .from(languageToName) 
      .where(languageToName.offer.eq(QOffer.offer) 
        .and(languageToName.name.eq("Esperanto")) 
        .and(languageToName.language.like("E%"))) 
      .exists(); 
関連する問題