Java 为什么这个Hibernate条件查询失败,并且“没有显式选择,也没有确定隐式选择”?
我有一个名为Bucket的实体,我正在尝试构建一个条件查询,以确定是否存在一个存储了Name属性等于Bucket_1的Bucket。所以基本上它是一个exists查询 Bucket类没有什么特别之处,更简单的是:Java 为什么这个Hibernate条件查询失败,并且“没有显式选择,也没有确定隐式选择”?,java,hibernate,hibernate-criteria,criteriaquery,Java,Hibernate,Hibernate Criteria,Criteriaquery,我有一个名为Bucket的实体,我正在尝试构建一个条件查询,以确定是否存在一个存储了Name属性等于Bucket_1的Bucket。所以基本上它是一个exists查询 Bucket类没有什么特别之处,更简单的是: @Entity(name="Bucket") @Table(name = "BUCKETS") public class Bucket implements Serializable { private static final long serialVersionUID =
@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();
我做了很多研究,但找不到任何人有相同的错误解释和/或修复
我也试过这样做:
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();
我想最难的部分是得到选择1。。。这样,外部查询的结果是布尔值,而不是匹配的实体
我知道这本书很管用,我现在正努力学习如何正确使用它,我相信有一种方法…你能做到这一点吗
boolean result = (session.createCriteria(Bucket.class)
.add(Restrictions.eq("Name","Bucket_1"))
.setProjection(Projections.count("Name"))
.uniqueResult() > 0);
这个解决方案确实有效,但我想使用exists构造来解决性能问题。我会做无数的记录来检查。exists结构的性能应该更好,因为一旦找到第一个与限制匹配的记录,DBMS就会停止查找记录。使用计数,它必须检查所有数据,然后分离不同的数据,然后才完成查询?类似于Oracle,从存在的双存储中选择1,从name='BUCKET_1'的存储桶中选择*?我会看看我是否有想法并更新答案。我认为分离查询应该可以工作。顺便说一句,按照这个性能逻辑,您可以始终使用setMaxResults1进行查询。您在setMaxResult1上有一个很好的观点,我可能最终会将建议的解决方案与您的建议结合起来。这个查询看起来就像你写的,是的!实际上,它可能会更简单,因为您不需要计数投影。而不是uniqueResult do list,并将其大小与0进行比较。可能需要设置id投影,这样就不必传输所有列。
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 generatedAlias0 from com.test.Bucket as generatedAlias0 where exists (select generatedAlias1 from com.test.Bucket as generatedAlias1 where generatedAlias1.Name=:param0)
boolean result = (session.createCriteria(Bucket.class)
.add(Restrictions.eq("Name","Bucket_1"))
.setProjection(Projections.count("Name"))
.uniqueResult() > 0);