[英]Need help creating JPA criteria query
I'm building my first Java EE web application using Glassfish and JSF. 我正在使用Glassfish和JSF构建我的第一个Java EE Web应用程序。 I'm fairly new to the criteria query and I have a query I need to perform but the javaee6 tutorial seems a little thin on examples.
我对条件查询相当新,我有一个我需要执行的查询,但javaee6教程在示例上似乎有点薄。 Anyway, I'm having a hard time creating the query.
无论如何,我很难创建查询。
Goal: I want to pull the company with the most documents stored. 目标:我希望用最多的文档来存储公司。 Companies have a OneToMany relationship with Documents.
公司与文档具有OneToMany关系。 Documents has a ManyToOne relationship with several tables, the "usertype" column distinguishes them.
Documents与多个表具有ManyToOne关系,“usertype”列区分它们。
MySQL query: MySQL查询:
SELECT USERID, COUNT(USERID) AS CNT
FROM DOCUMENTS
WHERE USERTYPE="COMPANY"
GROUP BY USERID
ORDER BY CNT DESC
Thanks 谢谢
--update-- Based on user feedback, here is what I have so far: --update--根据用户反馈,这是我到目前为止:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Documents> cqry = cb.createQuery(Documents.class);
//Intersting Stuff
Root<Documents> root = cqry.from(Documents.class);
Expression userid = root.get("userID");
Expression usertype = root.get("userType");
Expression count = cb.count(userid);
cqry.multiselect(userid, count);
Predicate userType = cb.equal(usertype, "COMPANY");
cqry.where(userType);
cqry.groupBy(userid);
cqry.orderBy(cb.desc(count));
//more boilerplate
Query qry = em.createQuery(cqry);
List<Documents> results = qry.getResultList();
The error I get is: 我得到的错误是:
Exception Description: Partial object queries are not allowed to maintain the cache or be edited. You must use dontMaintainCache().
Typical error, means nothing to me! 典型的错误,对我来说没什么意义!
Your query doesn't return a complete entity object as you're only selecting two fields of the given table (this is why you're getting an error that says yadayadapartialyadayada ). 您的查询不会返回完整的实体对象,因为您只选择给定表的两个字段(这就是您收到yadayadapartialyadayada错误的原因 )。
Your solution is almost right, here's what you need to change to make it work—making it partial . 您的解决方案几乎是正确的,这是您需要更改以使其工作的部分 。
Instead of a plain CriteriaQuery<...>
you have to create a tuple CriteriaQuery<..>
by calling CriteriaBuilder.createTupleQuery()
. 而不是简单的
CriteriaQuery<...>
你必须通过调用CriteriaBuilder.createTupleQuery()
来创建一个元组 CriteriaQuery<..>
。 (Basically, you can call CriteriaBuilder.createQuery(...)
and pass Tuple.class
to it as an argument. Tuple
is a sort of wildcard entity class.) (基本上,你可以调用
CriteriaBuilder.createQuery(...)
并通过Tuple.class
把它作为一个参数。 Tuple
是一种通配符实体类的。)
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq= cb.createTupleQuery();
Root<Documents> root = cq.from(Documents.class);
Expression<Integer> userId = root.get("USERID");
Expression<String> userType = root.get("USERTYPE");
Expression<Long> count = cb.count(userId);
cq.multiselect(userId.alias("USERID"), count.alias("CNT"));
cq.where(cb.equal(userType, "COMPANY");
cq.groupBy(userId);
cq.orderBy(cb.desc(count));
TypedQuery<Tuple> tq = em.createQuery(cq);
for (Tuple t : tq.getResultsList()) {
System.out.println(t.get("USERID"));
System.out.println(t.get("CNT"));
}
(Accessing fields of a Tuple
gave me an error if I didn't use aliases for them (in multiselect(...)
). This is why I've used aliases, but this can be tackled more cleanly by using JPA 2's Metamodel API , which is described in the specification quite thoroughly. ) (如果我没有为它们使用别名,访问
Tuple
字段会给我一个错误(在multiselect(...)
)。这就是我使用别名的原因,但是使用JPA 2的Metamodel可以更清晰地解决这个问题。 API ,在规范中非常详尽地描述。 )
The documentation for CriteriaQuery.multiselect(...)
describes the behaviour of queries using Tuple
objects more deeply. CriteriaQuery.multiselect(...)
的文档描述了更深入地使用Tuple
对象的查询行为。
If you are using Hibernate, this should work: 如果你正在使用Hibernate,这应该工作:
ProjectionList pl = Projections.projectionList()
.add(Projections.groupProperty("userid"))
.add(Projections.property("userid"))
.add(Projections.count("userid"));
Criteria criteria = session.createCriteria(Document.class)
.add(Restrictions.eq("usertype",usertype))
.setProjection(pl)
.addOrder(Order.desc("cnt"));
Hope it helps! 希望能帮助到你!
Take a look into this easy tutorial. 看看这个简单的教程。 It uses JPA2 and Criteria
它使用JPA2和Criteria
http://www.jumpingbean.co.za/blogs/jpa2-criteria-api http://www.jumpingbean.co.za/blogs/jpa2-criteria-api
Regards! 问候!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.