У меня есть объект с именем 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 ... идущий, где результатом внешнего запроса является логический, а не соответствующий объект.
Я знаю, что это у меня работает, сейчас я просто пытаюсь научиться делать это "правильно", я верю, что есть способ ...