Hibernate Group By Query - java

Please help me understand whats wrong with this query.
String sql = "select d.arc_alrt_cde, d.alrt_desc, count(d.arc_alrt_cde) " +
"from arc_alrt a, arc_alrt_def d " +
"where d.arc_alrt_cde = a.alrt_cde " +
"and (a.stat_cde = 'OPEN' or a.stat_cde = 'RE-OPENED') " +
"group by d.arc_alrt_cde, d.alrt_desc "+
"order by count(d.arc_alrt_cde) desc"
println sql
Query query = session.createQuery(sql);
Printing SQL
sql = select d.arc_alrt_cde, d.alrt_desc, count(d.arc_alrt_cde) from arc_alrt a, arc_alrt_def d where d.arc_alrt_cde = a.alrt_cde and (a.stat_cde = 'OPEN' or a.stat_cde = 'RE-OPENED') group by d.arc_alrt_cde, d.alrt_desc order by count(d.arc_alrt_cde) desc
Getting the following error. Tried IN clause also.. Not working..
Error:
java.lang.IllegalArgumentException: node to traverse cannot be null!
at org.hibernate.hql.internal.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:64)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:300)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:203)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:126)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:88)

That's an SQL query not a HQL one, so you should use:
SQLQuery query = session.createSQLQuery(sql);
That exception you got is thrown because Hibernate expects an HQL query but receives an SQL query instead.

You are to name the count field such as count(d.arc_alrt_cde) as countOfXXX
and also your entity should be aligned with that query or you should remove that count field at all.

Changed it to use object properties and it worked. Thanks for your inputs.
String sql = "select alert.alertCode, def.alertDesc, count(alert.alertCode) " +
"from ArcAlert as alert, ArcAlertDef as def " +
"where alert.alertCode = def.alertCode " +
"and alert.status in ('OPEN', 'RE-OPENED') " +
"and alert.assignedTo = '"+assignedTo+"' " +
"group by alert.alertCode, def.alertDesc " +
"order by count(alert.alertCode) desc"
Query query = session.createQuery(sql);
lst = query.list()

Related

Java Hibernate Error org.hibernate.hql.ast.QuerySyntaxException: unexpected token

Hello I have a problem with the execution of a Query inside Java using Hibernate.
When I use this Query:
Query query = dbSession.createQuery("SELECT activitydate, userid, sum(time) as homeofficeTime FROM Hours AS hours " +
"WHERE (hours.comment ILIKE ANY(ARRAY['%homeoffice%', '%home office%']) OR " +
"remark ILIKE ANY(ARRAY['%homeoffice%', '%home office%'])) AND " +
"hours.activitydate BETWEEN :from AND :to " +
"AND userid = :user " +
"GROUP BY activitydate, userid ORDER BY activitydate ");
query.setLong("user", employee.getUserid());
query.setCalendar("from", from);
query.setCalendar("to", to);
I get this Error:
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ILIKE near line 1, column 129 [SELECT activitydate, userid, sum(time) as homeofficeTime FROM com.thiesen.timesheet.sql.dbo.Hours AS hours WHERE (hours.comment ILIKE ANY(ARRAY['%homeoffice%', '%home office%']) OR remark ILIKE ANY(ARRAY['%homeoffice%', '%home office%'])) AND hours.activitydate BETWEEN :from AND :to AND userid = :user GROUP BY activitydate, userid ORDER BY activitydate ]
However when I use this Query:
Query query = dbSession.createQuery("SELECT activitydate, userid, sum(time) as homeofficeTime FROM Hours AS hours " +
"WHERE hours.comment = 'test Homeoffice tst' AND " +
"hours.activitydate BETWEEN :from AND :to " +
"AND userid = :user " +
"GROUP BY activitydate, userid ORDER BY activitydate ");
query.setLong("user", employee.getUserid());
query.setCalendar("from", from);
query.setCalendar("to", to);
It works and I get a Result back: [[Ljava.lang.Object;#7221ae50]
Both of the Query work if I test them inside Adminer and run the Querys there but for some Reason the first one wont work in my Project. Does Hibernate not know what to do with "ILIKE" or "LIKE" or the "Array[]" Part?

column not found in result set

I have a query that uses JpaRepository
#Query(
value = "SELECT count(user_name) AS user_count " +
"FROM users " +
"where status = 'B' ",
nativeQuery = true
)
List<Users> usersStatCount();
It gives me an error,
Could not execute query...
The column name user_name was not found in result set
But when I tried the query on pgadmin it is working fine.
And when I tried a simple
#Query(
value = "SELECT * " +
"FROM users " +
"where status = 'B' ",
nativeQuery = true
)
List<Users> usersStatCount();
It is working fine as well.
It's because the query returns a single value, not a row, that has to mapped to entity. Try the following:
#Query(
value = "SELECT count(user_name) " +
"FROM users " +
"where status = 'B' ",
nativeQuery = true
)
Long usersStatCount();

native query SELECT multiple table hibernate and oracle

I have a SQL query for get two table of SELECT.
I want to get two table as entity in result.
these tables are some column's name is equal(id,version).
I have following code :
String sql = "select sepTemp.*,pspTerm.* " +
"from SEPTRANSACTIONTEMP sepTemp " +
"LEFT JOIN PSP_Terminal pspTerm ON (pspTerm.idInPSP=sepTemp.termid AND pspTerm.pspID=:pspID) " +
"where NOT EXISTS " +
"(select * from PSPTRANSACTION pspTrans where pspTrans.PSPID=:pspID AND pspTrans.termNo=sepTemp.rrn) ";
List<Object[]> sepTransactionTemps = em.createNativeQuery(sql)
.setParameter("pspID", PSPTypes.SEP.getType())
.getResultList();
sepTransactionTemps.forEach(row -> {
SEPTransactionTemp sepTransactionTemp = ((SEPTransactionTemp) row[0]);
PSPTerminal sepTransactionTemp = ((PSPTerminal) row[1]);
...
but throw exception following :
org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [ID] during auto-discovery of a native-sql query
column id exists in your tables (SEPTRANSACTIONTEMP, LEFT JOIN PSP_Terminal)
create an alias for id column in your select query
String sql = "select " +
"sepTemp.id as sepTemp_id, " +
"sepTemp.version as sepTemp_version, " +
"pspTerm.id as pspTerm_id, " +
"pspTerm.version as pspTerm_version " // try here add all your column names
+ " from SEPTRANSACTIONTEMP sepTemp LEFT JOIN PSP_Terminal pspTerm "
+ "ON (pspTerm.idInPSP=sepTemp.termid AND pspTerm.pspID=:pspID) " + "where NOT EXISTS "
+ "(select * from PSPTRANSACTION pspTrans where pspTrans.PSPID=:pspID AND pspTrans.termNo=sepTemp.rrn) ";
List<Object[]> sepTransactionTemps = em.createNativeQuery(sql).setParameter("pspID", PSPTypes.SEP.getType())
.getResultList();

Order By in #Query select not working

I have this Query in my JPA repository - and it works EXCEPT the " order by " part. Am i doing this wrong ? is it different in hql ?
#Query(value = "select wm.WagerIdentification, wm.BoardNumber, wm.MarkSequenceNumber, wm.MarkNumber," +
" pt.CouponTypeIdentification, pt.WagerBoardQuickPickMarksBoard " +
"from WagerBoard wb " +
"inner join wb.listOfWagerMarks wm " +
"inner join wb.poolgameTransaction pt " +
"where wb.WagerIdentification = wm.WagerIdentification and wb.BoardNumber = wm.BoardNumber and wb.GameIdentification = wm.GameIdentification and wm.meta_IsCurrent = 1 " +
"and wb.TransactionIdentification = pt.TransactionIdentification and pt.meta_IsCurrent = 1 " +
"and wb.meta_IsCurrent = 1 order by wm.WagerIdentification asc, wm.BoardNumber asc, wm.MarkNumber asc")
Instead of ordering result within the #Query, you can add a method parameter of type Sort, like in Spring Data JPA reference

HQL: variable column

I'm able to set variable values for "where" restrictives:
Query criteria = session.createQuery(
"select test.col1, test.col2, test.col3
"from Test test " +
"where test.col = :variableValue ");
criteria.setInteger("variableValue", 10);
But is it possible to set variable column like this?
String variableColumn = "test.col1";
Query criteria = session.createQuery(
"select test.col1, test.col2, test.col3
"from Test test " +
"where :variableColumn = :variableValue ");
criteria.setInteger("variableValue", 10);
criteria.setString("variableColumn", variableColumn);
This is the result:
Exception in thread "main" Hibernate: select .... where ?=? ...
org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
...
at _test.TestCriteria.main(TestCriteria.java:44)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting the nvarchar value 'test.col1' to data type int.
...
UPDATE (working solution):
Query criteria = session.createQuery(
"select test.col1, test.col2, test.col3
"from Test test " +
"where (:value1 is null OR test.col1 = :value1) AND
(:value2 is null OR test.col2 = :value2) "
Does this make sense in your application:
String query = "select test.col1, test.col2, test.col3" +
"from Test test " +
"where {columnName} = :variableValue ";
Object variableValue = // retrieve from somewhere
String columnName = // another retrieve from somewhere
query = query.replace("{columnName}", columName);
// Now continue as always
This is generally a naive query constructor. You may need to refactor this idea to a separate utility/entity-based class to refine (e.g. SQL injection) the queries before execution.
You can set the column name as part of the string. For security you may do the SQL escaping manually, but at the end you can achieve this.
To avoid SQL injection you can use commons class:
String escapedVariableColumn = org.apache.commons.lang.StringEscapeUtils.escapeSql(variableColumn);
Query criteria = session.createQuery(
"select test.col1, test.col2, test.col3
"from Test test " +
"where " + escapedVariableColumn + " = :variableValue ");
criteria.setInteger("variableValue", 10);

Categories

Resources