我想同时运行count和distinct的标准。
我的代码如下:
final EntityManager entityManager = getEntityManagerFactory().createEntityManager();
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> criteriaQuery = criteriaBuilder.createQuery(Long.class);
final Root<Manufacturer> root = criteriaQuery.from(Manufacturer.class);
criteriaQuery.select(criteriaBuilder.count(root));
final Join productJoin = root.join("products");
productJoin.join("nickNames");
criteriaQuery.distinct(true);
final TypedQuery<Long> countQuery = entityManager.createQuery(criteriaQuery);
System.out.println(countQuery.getSingleResult());
我的标准有问题吗?或者是一个OpenJPA错误?如果我删除了不同的查询执行没有问题。
根据上述标准,我收到以下异常消息:
Exception in thread "main" <openjpa-2.3.0-r422266:1540826 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: Failed to execute query "null". Check the query syntax for correctness. See nested exception for details.
at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:872)
at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:794)
at org.apache.openjpa.kernel.DelegatingQuery.execute(DelegatingQuery.java:542)
at org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:275)
at org.apache.openjpa.persistence.QueryImpl.getResultList(QueryImpl.java:291)
at org.apache.openjpa.persistence.QueryImpl.getSingleResult(QueryImpl.java:319)
at com.uaihebert.test.Main.main(Main.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: unexpected token: FROM {SELECT DISTINCT FROM (SELECT DISTINCT t0.id AS t0_id FROM Manufacturer t0 INNER JOIN Manufacturer_Product t1 ON t0.id = t1.MANUFACTURER_ID INNER JOIN Product t2 ON t1.PRODUCTS_ID = t2.id INNER JOIN Product_NickName t3 ON t2.id = t3.PRODUCT_ID INNER JOIN NickName t4 ON t3.NICKNAMES_ID = t4.id)} [code=-5581, state=42581]
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:219)
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:199)
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$000(LoggingConnectionDecorator.java:59)
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection.prepareStatement(LoggingConnectionDecorator.java:251)
at org.apache.openjpa.lib.jdbc.DelegatingConnection.prepareStatement(DelegatingConnection.java:133)
at org.apache.openjpa.lib.jdbc.ConfiguringConnectionDecorator$ConfiguringConnection.prepareStatement(ConfiguringConnectionDecorator.java:140)
at org.apache.openjpa.lib.jdbc.DelegatingConnection.prepareStatement(DelegatingConnection.java:133)
at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$RefCountConnection.prepareStatement(JDBCStoreManager.java:1643)
at org.apache.openjpa.lib.jdbc.DelegatingConnection.prepareStatement(DelegatingConnection.java:122)
at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:508)
at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:488)
at org.apache.openjpa.jdbc.sql.SelectImpl.prepareStatement(SelectImpl.java:481)
at org.apache.openjpa.jdbc.sql.SelectImpl.execute(SelectImpl.java:422)
at org.apache.openjpa.jdbc.sql.SelectImpl.execute(SelectImpl.java:384)
at org.apache.openjpa.jdbc.kernel.SelectResultObjectProvider.open(SelectResultObjectProvider.java:94)
at org.apache.openjpa.kernel.QueryImpl$PackingResultObjectProvider.open(QueryImpl.java:2070)
at org.apache.openjpa.kernel.QueryImpl.singleResult(QueryImpl.java:1320)
at org.apache.openjpa.kernel.QueryImpl.toResult(QueryImpl.java:1242)
at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:1007)
at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:863)
... 11 more
答案 0 :(得分:0)
尝试在代码中使用CriteriaBuilder#countDistinct()
。
// ...
criteriaQuery.select(criteriaBuilder.countDistinct(root));
final Join productJoin = root.join("products");
productJoin.join("nickNames");
//criteriaQuery.distinct(true); -- commented u=out
// ...
在Hibernate 4.3.5
下,您的查询效果很好,但可能是供应商特定的行为(不一定是OpenJPA's
错误)。
我无法告诉count(..)
然后distinct(true)
与countDistinct(..)
的区别,但从逻辑上讲,它与写DISTINCT(COUNT(..))
和COUNT(DISTINCT(..))
的区别相同。
<强>更新强>
检查生成的SQL后,我可以确认单独的count()
和distinct()
生成的查询为SELECT DISTINCT COUNT(..) ..
,而countDistinct()
的查询为SELECT COUNT(DISTINCT(..) ..
。< / p>