Почему этот запрос Hibernate Criteria завершается неудачно с «Нет явного выбора, а неявный выбор не может быть определен»? - PullRequest
3 голосов
/ 17 июля 2011

У меня есть объект с именем Bucket, и я пытаюсь создать запрос критерия, чтобы определить, есть ли Bucket, сохраненный со свойством «Name», равным «Bucket_1». Так что в основном это существующий запрос.

В классе 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();

Но я получаю точно такое же исключение.

Кто-нибудь знает, почему я получаю это и как исправить этот запрос?

Спасибо! Эдуардо

UPDATE:

Я смог построить запрос, используя следующий способ:

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)

Полагаю, самая сложная задача - получить выбор 1 ... идущий, где результатом внешнего запроса является логический, а не соответствующий объект.

Я знаю, что это у меня работает, сейчас я просто пытаюсь научиться делать это "правильно", я верю, что есть способ ...

1 Ответ

2 голосов
/ 17 июля 2011

Вы можете просто сделать это?

boolean result = (session.createCriteria(Bucket.class)
       .add(Restrictions.eq("Name","Bucket_1"))
       .setProjection(Projections.count("Name"))
       .uniqueResult() > 0);
...