2016-08-19 17 views
11

私は、次の永続クラスがあります。使用Hibernateの基準

public class Code { 

    @ElementCollection(targetClass = CodeValue.class) 
    @MapKeyClass(CodeProperty.class) 
    @JoinTable(name="code_properties") 
    @CreateIfNull(value = false) 
    private Map<CodeProperty,CodeValue> propertiesMap = 
     new HashMap<CodeProperty, CodeValue>(); 

    ... 
} 

public class CodeProperty { 
    private String name; 
    ... 
} 

public class CodeValue { 
    private String value; 
    ... 
} 

をそして私は、私はpropertiesMapを持っているいくつかのプロパティによってフィルタリングコードのリストを取得しようとしている(たとえば、私は、次の基本基準を使用している「色」という名前のプロパティの値が「緑」を持っているコード

:。

Criteria criteria = currentSession() 
    .createCriteria(Code.class, "code") 
    .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); 

私は(提案hereなど)の収集フィルタを実行しようとすると:

org.hibernate.QueryException: could not resolve property: foo of: com.example.CodeValue 

、私は本当に、なぜ理解して冬眠していないことを意味することを検討している:

criteria.createAlias("code.properties", "p"); 
criteria.add(Restrictions.eq("p.foo", "test1")); 
criteria.setFetchMode("code.properties", FetchMode.JOIN); 
criteria.list(); 

私は次のエラーを取得しますcode.propertiesの代わりにCodeValueです !!!

エイリアスを作成せずにこのフィールドにアクセスしようとしましたが、この方法では、正しいコードクラスにアクセスしているようです。私はproperties.indeceshereが示唆したように)使用:

criteria.add(Restrictions.eq("properties.indeces", "foo")); 
criteria.list(); 

をしかし、これで私は次のエラーを取得する:

could not resolve property: properties.indeces of: com.example.Code 

は、誰かがいただきました間違った理解私を助けることはできますか?色の緑でコードを検索するための正しいCriteriaクエリは何でしょうか?

the Github project that demonstrates this problemをチェックアウトすることができます。

おかげ

+0

@MapKeyClassでJPA 2.1の機能を使用していることがわかりました。 JPA Criteria APIではなく廃止予定のHibernate Criteria APIの使用に拘束されていますか? – Naros

+0

@Narosがmicdcarに代わって答える - はい、残念なことに、sessionfactory構成全体をentitymanagerに切り替えることを意味しますが、これは簡単な通知ではありません。私たちはhibernate基準を返すcreateCriteriaに縛られています。 – mmalmeida

答えて

1

私はあなたがレガシーHibernateのクライテリアAPIでこれを行うことができると信じていないとJPA基準のAPIを使用して、Hibernateの実装と小さな限界があります。これを解決する1つの方法は、次のようになります。

List<CodeProperty>を取得するには、そのエンティティに述語要件を直接照会します。

List<CodeProperty> propertyKeys = entityManager 
    .createQuery("FROM CodeProperty p WHERE p.name = :name") 
    .setParameter("name", "foo") 
    .getResultList(); 

クエリJPAの基準を使用して、あなたのCodeエンティティを。

// setup the query 
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
CriteriaQuery<Code> query = cb.createQuery(Code.class); 
Root<Code> root = query.from(Code.class); 
MapJoin<Code, CodeProperty, CodeValue> mapRoot = root.joinMap("propertiesMap"); 
query.select(root).where(mapRoot.key().in(propertyKeys)); 

// get results 
List<Code> results = entityManager.createQuery(query).getResultList(); 

私が使用して、これらを組み合わせることを試みた:

query 
    .select(root) 
    .where (cb.eq(mapRoot.key().get("name"), "foo")) 

問題は、これがNotYetImplemented例外:(その結果です。

1

を参照しないことがありますindecesを使用していたかどうかを確認してくださいまたは指数。次のように正しい使用方法は次のとおりです。また

criteria.createAlias("code.properties", "p"); 
criteria.add(Restrictions.eq("p.indices", "foo")); 
criteria.list(); 

、あなたが制限に

eq("p." + CollectionPropertyNames.COLLECTION_INDICES) 

を使用することができます。

まだ動作しない場合は、教えてください。

1

あなたのアプローチにはさまざまな問題があります: プロジェクトのgithubでMapTestフォルダを見て、常に変数名を列名として呼び出し、それらの同じ名前を基準に使用することをお勧めします。 基準はマップで、最初の引数は属性名で、2番目の引数は属性の値です。あなたが使用しようとすることができ、多くの関係に多くの場合 :

@JoinTable(
     name="docente_classe", 
     joinColumns= 
      @JoinColumn(name="id_dipendente", referencedColumnName="id_dipendente"), 
     inverseJoinColumns= 
      @JoinColumn(name="id_classe", referencedColumnName="id_classe") 
) 

これはJPAのアノテーションで、これはあなたのプロジェクトでコンパイルすると、私は知りません。クエリのために

https://github.com/tredue1/School_Manager/blob/master/code/SM/src/main/java/agc2/it/sm/gestioneDocente/DocenteJpa.java

多くの関係に多くの上でこの記事を見る:

jpa criteria for many to many relationship

+0

申し訳ありませんが、私はフォローしていません。あなたの例には地図がありません。 Setsを介して実装された多対多のクエリは、別のものです。 GitHubサンプル(またはプロジェクトフォーク)を使用して回答を明確にできますか? – mmalmeida

+0

リンクを確認しようとしましたか:http://stackoverflow.com/questions/8135612/jpa-criteria-for-many-to-many-relationship ????これは良い例です。 – pioardi

関連する問題