エンティティオブジェクトをフォローする必要があります
@Entity
public class Foobar {
...
private List<String> uuids;
...
}
ここで、uuid リストに文字列 "abc123" が含まれるすべての Foobar pojo を取得する基準クエリを作成したいと思いますが、適切な基準を作成する方法がわかりません。
エンティティオブジェクトをフォローする必要があります
@Entity
public class Foobar {
...
private List<String> uuids;
...
}
ここで、uuid リストに文字列 "abc123" が含まれるすべての Foobar pojo を取得する基準クエリを作成したいと思いますが、適切な基準を作成する方法がわかりません。
JPA 2.0 を実装するバージョンの Hibernate を使用していると思います。これは、準拠した実装で動作する JPA 2.0 ソリューションです。
uuids
JPAのアノテーションをつけてください@ElementCollection
。@CollectionOfElements
他の回答コメントのいくつかに記載されているように、Hibernate を使用しないでください。後者には同等の機能がありますが、推奨されていません。
Foobar.java
おおよそ次のようになります。
@Entity
public class Foobar implements Serializable {
// You might have some other id
@Id
private Long id;
@ElementCollection
private List<String> uuids;
// Getters/Setters, serialVersionUID, ...
}
「abc123」 を含むすべてのCriteriaQuery
を選択するを構築する方法は次のとおりです。Foobar
uuids
public void getFoobars() {
{
EntityManager em = ... // EM by injection, EntityManagerFactory, whatever
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<Foobar> cq = b.createQuery(Foobar.class);
Root<Foobar> foobar = cq.from(Foobar.class);
TypedQuery<Foobar> q = em.createQuery(
cq.select(foobar)
.where(b.isMember("abc123", foobar.<List<String>>get("uuids"))));
for (Foobar f : q.getResultList()) {
// Do stuff with f, which will have "abc123" in uuids
}
}
これで遊んでいる間に、自己完結型の概念実証プログラムを作成しました。今は押し出せません。POC を github にプッシュしたい場合は、コメントしてください。
これは古い質問であることは知っていますが、この問題に遭遇して解決策を見つけました。
Hibernate Criteria を使用する場合は、uuids
コレクションに参加し、そのプロパティを使用してelements
要素を一致させることができます。そのように:
session.createCriteria(Foobar.class)
.createAlias("uuids", "uuids")
.add(Restrictions.eq("uuids.elements", "MyUUID"))
.list()
以下の例のようにクエリを使用するか、これをNamedQueryに変換することができます。残念ながら、Criteriaでこれを行う方法はないようです。
List<Foobar> result = session
.createQuery("from Foobar f join f.uuids u where u =: mytest")
.setString("mytest", "acb123")
.list();
1 年前のこの投稿を見つけて、数時間前と同じ問題を抱えている人を助けることができるなら、この方法を作成しました。
Public List<EntityObject> getHasString(String string) {
return getSession().createCriteria(EntityObject.class)
.add(Restriction.like("property-name", string, MatchMode.ANYWHERE).ignoreCase();
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.list();
弦のグループでも同じようにしました。
public List<EntityObject> getByStringList(String[] tab) {
Criterion c = Restrictions.like("property-name", tab[tab.length-1], MatchMode.ANYWHERE).ignoreCase();
if(tab.length > 1) {
for(int i=tab.length-2; i >= 0 ; i--) {
c = Restrictions.or(Restrictions.like("property-name",tab[i], MatchMode.ANYWHERE).ignoreCase(), c);
}
}
return getSession().createCriteria(EntityObject.class)
.add(c)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.list();
}
「or」ステートメントで機能しますが、「and」ステートメントに簡単に置き換えることができます。
あなたが求めていることは、Hibernateによって箱から出してサポートされていません。http://opensource.atlassian.com/projects/hibernate/browse/HHH-869を参照してください
jiraチケットで利用可能な回避策は次のとおりです。
entityCriteria.add(Restrictions.sqlRestriction(
"fooAlias.id in (select e.id from foobar_table e, values_table v" +
" where e.id = v.entity_id and v.field = ?)", "abc123"), Hibernate.String)) ;
jira http://opensource.atlassian.com/projects/hibernate/browse/HHH-869の sqlRestriction を使用したソリューションは、 基準 API を多用しているため、私にとって最善の方法のように思えました。Thierryのコードを編集する必要があったので、私の場合はうまくいきました
モデル:
@Entity
public class PlatformData
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long iID;
private List<String> iPlatformAbilities = new ArrayList<String>();
}
基準呼び出し:
tCriteria.add(Restrictions.sqlRestriction(
"{alias}.id in (select e.id from platformData e, platformdata_platformabilities v"
+ " where e.id = v.platformdata_id and v.element = ? )", aPlatformAbility.toString(),
Hibernate.STRING));
まず、Hibernate がList<String>
. ただし、他のエンティティのリストをマップすることはできます。
したがって、コードが次のようなものである場合:
@Entity
public class Foobar {
private List<EntityObject> uuids;
...
}
にEntityObject
は というString
プロパティがstr
あり、基準は次のようになります。
List<Foobar> returns = (List<Foobar>) session
.createCriteria.(Foobar.class, "foobars")
.createAlias("foobars.uuids", "uuids")
.add(Restrictions.like("uuids.str", "%abc123%"))
.list();