4

Bucket というエンティティがあり、"Bucket_1" に等しい "Name" プロパティで格納された Bucket があるかどうかを判断する条件クエリを作成しようとしています。したがって、基本的には存在するクエリです。

Bucket クラスについて特別なことは何もありません。単純に不可能です:

@Entity(name="Bucket")
@Table(name = "BUCKETS")
public class Bucket implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name = "BUCKET_NAME", length=200)
    private String Name;

        ...
}

クエリについては、これまでのところ次のとおりです。

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Boolean> superQuery = criteriaBuilder.createQuery(Boolean.class);

Class<? extends T> scopeClass = Bucket.class;
Root<? extends T> root = superQuery.from(scopeClass);

Path<?> attributePath = root.get("Name");
Predicate pred = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("Bucket_1"));

Subquery<? extends T> subQuery = superQuery.subquery(scopeClass);
subQuery.where(pred);
Predicate where = criteriaBuilder.exists(subQuery);

superQuery = superQuery.select(where);

/* This line fails!! */
TypedQuery<Boolean> typedQuery = em.createQuery(superQuery);

boolean result = typedQuery.getSingleResult();

クエリを実行すると、最後の行で次の例外が発生します。

Caused by: java.lang.IllegalStateException: No explicit selection and an implicit one cold not be determined
    at org.hibernate.ejb.criteria.QueryStructure.locateImplicitSelection(QueryStructure.java:296)
    at org.hibernate.ejb.criteria.QueryStructure.render(QueryStructure.java:249)
    at org.hibernate.ejb.criteria.CriteriaSubqueryImpl.render(CriteriaSubqueryImpl.java:281)
    at org.hibernate.ejb.criteria.predicate.ExistsPredicate.render(ExistsPredicate.java:57)
    at org.hibernate.ejb.criteria.predicate.ExistsPredicate.renderProjection(ExistsPredicate.java:62)
    at org.hibernate.ejb.criteria.QueryStructure.render(QueryStructure.java:252)
    at org.hibernate.ejb.criteria.CriteriaQueryImpl.render(CriteriaQueryImpl.java:340)
    at org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:223)
    at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:441)
    at com.specktro.orchid.io.connection.database.dao.internal.DefaultDAO.has(DefaultDAO.java:426)
    ... 28 more

私は多くのことを調査しましたが、説明および/または修正された同じエラーを持つ人を見つけることができませんでした.

私もこの方法を試しました:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Boolean> superQuery = criteriaBuilder.createQuery(Boolean.class);

Class<? extends T> scopeClass = Bucket.class;
superQuery.from(scopeClass);
Subquery<? extends T> subQuery = superQuery.subquery(scopeClass);
Root<? extends T> root = subQuery.from(scopeClass);

Path<?> attributePath = root.get("Name");
Predicate pred = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("Bucket_1"));

Subquery<? extends T> subQuery = superQuery.subquery(scopeClass);
subQuery.where(pred);
Predicate where = criteriaBuilder.exists(subQuery);

superQuery = superQuery.select(where);

/* This line fails!! */
TypedQuery<Boolean> typedQuery = em.createQuery(superQuery);
boolean result = typedQuery.getSingleResult();

しかし、まったく同じ例外が発生します。

なぜ私がこれを取得したのか、このクエリを修正する方法を知っている人はいますか?

ありがとうございました!!エドゥアルド

アップデート:

次の方法で存在するクエリを作成できました。

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

CriteriaQuery<Bucket> query = criteriaBuilder.createQuery(Bucket.class);
Root<Bucket> root = query.from(Bucket.class);
query.select(root);

Subquery<Bucket> subquery = query.subquery(Bucket.class);
Root<Bucket> subRootEntity = subquery.from(Bucket.class);
subquery.select(subRootEntity);

Path<?> attributePath = subRootEntity.get("Name");
Predicate pred = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("Bucket_1"));
subquery.where(pred);
query.where(criteriaBuilder.exists(subquery));

TypedQuery<Bucket> typedQuery = em.createQuery(query);

boolean entityExists = typedQuery.getResultList().size() == 1;

その結果、次のような奇妙な SQL が生成されました。

select generatedAlias0 from com.test.Bucket as generatedAlias0 where exists (select generatedAlias1 from com.test.Bucket as generatedAlias1 where generatedAlias1.Name=:param0)

外部クエリの結果はブール値であり、一致するエンティティではありません。

私はこれが機能することを知っています。私は今、それを「適切に」行う方法を学ぼうとしています。方法があると信じています...

4

1 に答える 1

2

Can you just do this?

boolean result = (session.createCriteria(Bucket.class)
       .add(Restrictions.eq("Name","Bucket_1"))
       .setProjection(Projections.count("Name"))
       .uniqueResult() > 0);
于 2011-07-17T01:55:02.727 に答える