2011-07-16 4 views
3

저는 Bucket이라는 엔티티가 있습니다. "Bucket_1"과 동일한 "Name"속성과 함께 저장된 Bucket이 있는지를 결정하는 기준 쿼리를 작성하려고합니다. 기본적으로 존재하는 쿼리입니다. 간단 불가능 버킷 클래스에 대한 특별한 것이 없다이 Hibernate Criteria Query가 "명시 적 선택이없고 암시적인 하나의 냉기가 결정되지 않음"으로 인해 실패하는 이유는 무엇입니까?

:

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(); 

내가 I에 대해 쿼리를 실행할 때 : 쿼리

@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; 

     ... 
} 

, 이것은 내가 지금까지 갈 것입니다 마지막 줄에 다음과 같은 예외가 발생합니다.

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 :

내가 사용하는 쿼리를 구성 할 수 있었다 존재하는 다음과 같은 방법 :

select generatedAlias0 from com.test.Bucket as generatedAlias0 where exists (select generatedAlias1 from com.test.Bucket as generatedAlias1 where generatedAlias1.Name=:param0) 
: 이상한 SQL 결과

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; 

는 다음과 같이 생성

나는 어려운 부분이 그 select 1 ...을 얻는 것 같아요 ... 어디서, 외부 쿼리의 결과는 부울 및 일치하는 엔터티가 아닙니다. 내가 작품을 가지고이 일을 알고

, 지금 바로

답변

2

방금이 작업을 수행 할 수 ... "제대로", 나는 방법이 생각을하는 방법을 배우려고?

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

이 솔루션은 효과가 있지만 성능 문제를 해결하기 위해 기존 구성을 사용하고 싶습니다. 나는 확인하기 위해 수없이 많은 기록을 남길 것이다. 제한과 일치하는 첫 번째 레코드가 발견되면 DBMS가 레코드 찾기를 중지함에 따라 기존 구조가 더 잘 수행되어야합니다. 카운트를 사용하여 모든 항목을 확인한 다음 다른 항목을 구분하고 쿼리를 완료해야합니다. –

+0

SQL 쿼리는 어떻게 표시됩니까? 뭔가 (오라클의 경우)'select from dual from where where (select * from buckets from name = 'BUCKET_1')'? 내가 아이디어를 얻고 대답을 업데이트하는지 알게 될 것입니다. detached 쿼리가 작동해야한다고 생각합니다. –

+0

그런데이 성능 로직을 따르면, 당신은 항상'setMaxResults (1)'로 질의를 할 수 있습니다. –

관련 문제