I want to count the number of group by rows with hibernate Criteria API, but i can only count number of rows aggregated in each group:
ProjectionList projectionList = Projections.projectionList()
.add(Projections.groupProperty("color"))
.add(Projections.rowCount());
Criteria criteria = session.createCriteria("ProductEntity");
criteria.setProjection(projectionList);
// adding some criteria
List results = criteria.list();
Above code will results in this query:
select p.color, count(*) from product p group by p.color
But i want this query:
select count(*) from (select p.color from product p group by p.color)
I know it's possible with HQL, but i don't want to use it. So how can i do this with Criteria API?
If you want to know how many different colors are present you should use
Projections.countDistinct("color")
This will result a query which will return the same result as this:
select count(*) from (select p.color from product p group by p.color)
Related
I'm relatively new to Spring JPA CriteriaQuery. Im trying to convert my old native query in my program to criteria query and haven't been successful on join query for multiple table with conditions. I need help converting native SQL query into Criteria Query for these query below :
select * from student s inner join (
select distinct on (student_id) * from class where status = 'Active' order by
student_id,date_register desc) c on s.id = c.user_id
inner join teacher t on t.subject_id = c.subject_id
where t.status = 'Active' and s.status='Active' order by s.name desc
Update :
Below code is as far as I can go cause I dont really know much. Am i in the right direction? I'm opting for Expression because i dont know how to use Join.
CriteriaQuery<Student> query = cb.createQuery(Student.class);
Root<Student> sRoot= query.from(Student.class);
query.select(sRoot);
Subquery<Integer> subquery = query.subquery(Integer.class);
Root<Class> cRoot= subquery.from(CLass.class);
Expression<Integer> max = cb.max(cRoot.get("dateRegister"));
subquery.select(max);
subquery.groupBy(cRoot.get("student"));
query.where(
cb.and(
cb.in(cRoot.get("dateRegister")).value(subquery)
)
);
Thanks in advance!
i have Three tables [users,projects,scenarios] i need to get latest update projects details based on modified Date column with out duplicate values
the tables are:
users Table :
project table
scenario Table
and i try below query but its return duplicates values if am using group by then old values came but i need latest values
With out Group by query
SELECT
p.`PROJECT_NAME`,
p.`CREATED_DATE`,
s.`MODIFIED_DATE`
FROM
`projects` p
JOIN `scenarios` s ON
s.`PROJECT_ID` = p.`PROJECT_ID`
WHERE
P.`USER_ID` =(
SELECT
USER_ID
FROM
users
WHERE
EMAIL = 'test#gmail.com'
)
ORDER BY
s.`MODIFIED_DATE`
DESC
out put:
with Group by Query :
SELECT
p.`PROJECT_NAME`,
p.`CREATED_DATE`,
s.`MODIFIED_DATE`
FROM
`projects` p
JOIN `scenarios` s ON
s.`PROJECT_ID` = p.`PROJECT_ID`
WHERE
P.`USER_ID` =(
SELECT
USER_ID
FROM
users
WHERE
EMAIL = 'test#gmail.com'
)
group by p.PROJECT_NAME
ORDER BY
s.`MODIFIED_DATE`
DESC
output:
You can separately get the latest scenario per project using a subquery then the resulting rows will then be join again to get the other columns, if needed.
SELECT p.PROJECT_NAME,
p.CREATED_DATE,
s.MODIFIED_DATE
-- all columns in s.* will have the latest row
FROM projects p
INNER JOIN scenarios s
ON p.PROJECT_ID = s.PROJECT_ID
INNER JOIN
(
SELECT project_ID, MAX(modified_date) MAX_modified_date
FROM scenarios
GROUP BY project_ID
) t ON s.project_ID = t.project_ID
AND s.modified_date = t.MAX_modified_date
INNER JOIN users u
ON P.USER_ID = u.USER_ID
WHERE u.EMAIL = 'test#gmail.com'
ORDER BY s.MODIFIED_DATE DESC
However, if you don't need to get the other columns, you can directly use MAX() and GROUP BY.
SELECT p.PROJECT_NAME,
p.CREATED_DATE,
MAX(s.MODIFIED_DATE) AS MAX_MODIFIED_DATE
FROM projects p
INNER JOIN scenarios s
ON p.PROJECT_ID = s.PROJECT_ID
INNER JOIN users u
ON P.USER_ID = u.USER_ID
WHERE u.EMAIL = 'test#gmail.com'
GROUP BY p.PROJECT_NAME,
p.CREATED_DATE
ORDER BY MAX_MODIFIED_DATE DESC
I have a situation where I need to convert a query like :-
select hostname, avg(cpu_utilization_percentage) from cpu_utilization where timestamp In (select distinct(timestamp) from report.cpu_utilization order by timestamp desc limit 6) group by hostname
Now, this data I want to fetch using hibernate so I have used Subqueries:-
// For inner Query
DetachedCriteria subquery = DetachedCriteria.forClass(CpuUtilizationDTO.class);
subquery.setProjection(Projections.distinct(Projections.property("timeStamp"))).addOrder(Order.desc("timeStamp"));
subquery.getExecutableCriteria(session).setMaxResults(6);
// For Outer Query
Criteria query = session.createCriteria(CpuUtilizationDTO.class);
ProjectionList list = Projections.projectionList();
list.add(Projections.groupProperty("hostName"));
list.add(Projections.avg("cpuUtilizationpercentage"));
query.setProjection(list);
List<Object[]> obj= (List<Object[]>)hibernateTemplate.findByCriteria(query);ction(list);
//Now to add subquery into main query I am using
query.add(Subqueries.propertyIn("timeStamp", subquery));
But everytime I am getting the average of entire data. Can anyone please help that where did I miss?
I create a query using criteria (java) on PostgreSQL DB ,
This is a snippet from my code:
protected Criteria createEntityCriteria() {
return createEntityCriteria(getSession());
}
protected Criteria createEntityCriteria(Session session) {
return session.createCriteria(getEntityClass(), "main").setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
}
Criteria crit = createEntityCriteria();
crit.setFirstResult((pagingInfo.getPageNumber() - 1) * pagingInfo.getPageSize());
crit.setMaxResults(pagingInfo.getPageSize());
now when i view the log from hibernate(criteria query) i see 2 queries
the first one:
the first query which i have NOT asked at all is:
/* criteria query */ select
count(*) as y0_
from some_Table this
left outer join moreTable
on ......
the second one is which i did asked for:
Hibernate:
/* criteria query */ select col1 y0_,
col2 y1_,
......
from .....
left join ....
on ....
order by
y41_ desc limit ? offset ?
the problem is that the count query fail due to a query time out .
and second one works perfect .
is there a way to prevent from hibernate to "made-up" this count query ?
I run following code intend to update the least record in the table on Hibernate 3.6.7 final (JPA 2.0?) :
Query query = em.createQuery("UPDATE MyTable a SET a.isEnable=1 WHERE a.isEnable=0 ORDER BY a.id DESC").setMaxResults(1);
query.executeUpdate();
but hibernate ignores ORDER BY when generating sql.
Is ORDER BY for SELECT use only in JPQL? How to execute UPDATE query with ORDER BY in JPA?
thanks for any help.
To update the record with the last ID in a table you do the following:
TypedQuery<MyEntity> query = em.createQuery("SELECT a FROM MyEntity a WHERE a.isEnable=0 ORDER BY a.id DESC", MyEntity.class);
query.setMaxResults(1);
List<MyEntity> resultList = query.getResultList();
if (resultList.size()>0) {
resultList.get(0).setEnabled(true);
//eventually you can to em.flush();
}