hibernate criteria group Query is wrong - java

I am trying to generate the following query using Criteria:
select order_number, order_date, sum(order_amount)
from st_pur_orders
group by ORDER_NUMBER,ORDER_DATE;
Here is my Criteria:
Criteria cr = session.createCriteria(StPurOrders.class);
cr.setProjection(Projections.projectionList()
.add(Projections.property("orderNumber"), "orderDate")
.add(Projections.sum("orderAmount"))
.add(Projections.groupProperty("orderNumber"))
.add(Projections.groupProperty("orderDate")));
cr.setResultTransformer(Transformers.aliasToBean(PurOrderColl.class));
list = cr.list();
But the query getting generate in the background is this:
select this_.ORDER_NUMBER as y0_, sum(this_.ORDER_AMOUNT) as y1_,
this_.ORDER_NUMBER as y2_, this_.ORDER_DATE as y3_
from STOCK.ST_PUR_ORDERS this_
group by this_.ORDER_NUMBER, this_.ORDER_DATE;
My Question is why is the ORDER_NUMBER field being listed twice?

My Question is why is the ORDER_NUMBER field being listed twice?
Your Criteria already has Projections.groupProperty("orderNumber"). So the generated query will include orderNumber in its select clause.
I don't see a need for specifying Projections.property("orderNumber") explicitly. Can you please remove that and try.
Same applies for any other field that is specified using groupProperty(..).

Related

Hibernate GROUP BY invalid for Oracle

I created an Hibernate query like this:
select new ProjectForUser
(p.projectId, p.name, p.description, p.client, p.startDate, p.endDate,
p.liveDate, p.projectState, p.overallRagStatus, p.scopeRagStatus, p.flt,
up.projectManager)
from UserProjectAssociation up left join up.project p
where up.user.id = :userId and up.project.projectState != 'ARCHIVED'
group by p.projectId
to retrieve projects for user. Projects are stored in one table, users in the other and UserProjectAssociation is a joining table with additional attribute - projectManager.
The whole query works fine for H2 database, but on oracle I get this error:
ORA-00979: not a GROUP BY expression
What is a correct way to use GROUP BY for Oracle?
Thanks!
The Problem. ORA-00979 occurs when the GROUP BY clause does not contain all the expressions in the SELECT clause. Any SELECT expression that is not included in the GROUP function must be listed in the GROUP BY clause. These are AVG, COUNT, MAX, MIN, SUM, STDDEV, and VARIANCE.
see: https://www.tekstream.com/resources/ora-00979-not-a-group-by-expression/

Hibernate 2 with MSSQL for ORDER BY

I have been working with Oracle and Postgre and recently switched to MS SQL 2012.
I use hibernate in my application and wherever I have used the Order by Criteria:
(criteria.addOrder(Order.asc("applicationId")));
It causes an error saying:
aggregate functions dont work.
Once I comment that line out my program works and data can be retrieved.
I'm using Hibernate 3.
Is there any way to order it through hibernate without this error?
edit..
This is one error I get,
Column "SKY.tcrent.RENTNO" is invalid in the ORDER BY clause because
it is not contained in either an aggregate function or the GROUP BY
clause.
Edit 2..
MY query
Query tcSchaduleQ = getSession().createQuery("SELECT SUM(tcs.dueAmount) FROM TrialCalculationSchedule tcs WHERE tcs.facilityId=:facilityId AND tcs.rentalNumber>:rentalNumber AND tcs.dueDate>:dueDate AND dueTypeId IN(:dueTypeId) ORDER BY tcs.rentalNumber ").setInteger("rentalNumber", facility.getPeriod() - noOfprePayments).setInteger("facilityId",facility.getFacilityId()).setDate("dueDate", date).setParameterList("dueTypeId", plist);
Number tcsAmt = (Number) tcSchaduleQ.uniqueResult();
and this is what hibernate generates in HQL
SELECT
SUM(tcs.dueAmount)
FROM
TrialCalculationSchedule tcs
WHERE
tcs.facilityId=:facilityId
AND tcs.rentalNumber>:rentalNumber
AND tcs.dueDate>:dueDate
AND dueTypeId IN(
:dueTypeId
)
ORDER BY
tcs.rentalNumber
and this is the SQL
select
SUM(trialcalcu0_.DUEAMT) as col_0_0_
from
SKYBANKSLFHP.tcrent trialcalcu0_
where
trialcalcu0_.FACID=?
and trialcalcu0_.RENTNO>?
and trialcalcu0_.DUEDATE>?
and (
trialcalcu0_.DUETYPEID in (
? , ?
)
)
order by
trialcalcu0_.RENTNO
Look Like you mix aggregate and non-aggregate expressions .If you are using any aggregate function like AVG() in Select query with some other non-aggregate then you must use Group By ..
Try something like this
createQuery("SELECT SUM(tcs.dueAmount) As DueAmount ...
If you are using Criteria then it should be like this
Criteria crit = sess.createCriteria(Insurance.class);
ProjectionList proList = Projections.projectionList();
proList.add(Projections.sum("investementAmount"));
crit.setProjection(proList);
List sumResult = crit.list();

Parameter in SELECT clause for #Query?

While using a verbatim entered column name works fine in an SQL/JPA query, is it possible to use a variable?
#Query(value = "select distinct ?1 from Product", nativeQuery = true)
List<String> findOneColumn(String columnName);
This code appears to fail. It seems that it's not allowed to use parameters in SELECT clause (but works with WHERE clause). Is there any alternatives?
How can I set the column name dynamically?
Seems that Parameter in SELECT clause for #Query is not allowed pleasure :)

Select records which doesn't have specific records in joined table

Hi I'm trying to select records from one table which doesn't have records in connected many-to-many table with specific values.
I will explain on sample tables:
documentation:
id_documentation
irrelevant_data
user:
id_user
irrelevant_data
documentation_user:
id_documentation
id_user
role
What I want to achieve is to select every single documentation which doesn't have user in specific role. Any ideas?
The main problem is that I'm using java's CriteriaBuilder to create query so using subqueries is impossible (I think).
You can add restrictions on your left join using: createAlias(java.lang.String, java.lang.String, int, org.hibernate.criterion.Criterion) method, see API.
Check this answer for an example on how to use the left join with a criteria.
Main problem does not exist - Criteria API do have SubQuery. Query itself selects instances of User and uses not in construct to limit results based to subquery. Subquery selects all users that are connected to document with specific role via DocumentationUser.
Try something like this (code not tested):
CriteriaQuery<Documentation> cq = cb.createQuery(Documentation.class);
Root<Documentation> u = cq.from(Documentation.class);
Subquery<Integer> sq = cq.subquery(Integer.class);
Root<User> su = sq.from(User.class);
sq.select(su.get("id_user"));
Join<User, DocumentationUser> du = su.join("documentationUserCollection");
sq.where(cb.equals(du.get("role"), "mySpecificRole"));
cq.where(cb.not(cb.in(u.get("id_user")).value(sq)));
See also this useful answer on SO.

Projections.countDistinct with Hibernate produces unexpected result

I have the following code
Criteria criteria = this.getCriteriaForClass(DeviceListItem.class);
Projection rowCountProjection = Projections.countDistinct("color");
criteria.setProjection(rowCountProjection);
int rowCount = ((Long) criteria.uniqueResult()).intValue();
return rowCount;
, whose purpose is to find out the number of rows with different values for the field named "color". The problem is that
Projections.countDistinct("color");
returns the same number of results as
Projections.count("color");
even though there are multiple rows with same color in the database view. When converting the Criteria object to SQL, I see that the SQL produced by Hibernate is
select count(this_.COLOR) as y0_ from DEVICESLIST_VIEW this_ where 1=1
when I would expect it to be
select count(distinct this_.COLOR) as y0_ from DEVICESLIST_VIEW this_ where 1=1
Why doesn't it work like expected and is there some remedy? Unfortunately I have no option to use HQL in this case.
It's a bug, fixed in 3.5.2: HHH-4957.

Categories