I have this code in my dao method:
TypedQuery<Application> query = em.createQuery(
"FROM Application a "
+ "WHERE LOWER(a.candidate.firstName LIKE :firstName) "
+ "OR LOWER(a.candidate.lastName LIKE :lastName) "
+ "OR (a.candidate.phoneNumber LIKE :phoneNumber) "
+ "OR LOWER(a.candidate.email LIKE :email) "
+ "OR LOWER(a.candidate.postcode LIKE :postcode)"
, Application.class);
query = query.setParameter("firstName", candidate.getFirstName());
query = query.setParameter("lastName", candidate.getLastName());
query = query.setParameter("phoneNumber", candidate.getPhoneNumber());
query = query.setParameter("email", candidate.getEmail());
query = query.setParameter("postcode", candidate.getPostcode());
and it throws this Exception:
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: ( near line 1, column 57 [FROM com.xxx.xxx.entity.Application a WHERE LOWER(a.candidate.firstName LIKE :firstName) OR LOWER(a.candidate.lastName LIKE :lastName) OR (a.candidate.phoneNumber LIKE :phoneNumber) OR LOWER(a.candidate.email LIKE :email) OR LOWER(a.candidate.postcode LIKE :postcode)]
Something is probably wrong with my query, but I cannot see what... Any help appreciated.
It's your parenthesis.
LOWER(a.candidate.firstName LIKE :firstName)
should be:
LOWER(a.candidate.firstName) LIKE :firstName
etc.
Related
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?
I encountered a very interesting issue. I want to create an UPDATE statement NamedQuery for my class (I know this is a bit hacky).
The weird thing is if I use positioned parameters in the query like ?1, ?2 etc. it works perfectly. However, if I want to use named parameters like :id, it fails with the following error:
failed because of: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting EOF, found 'consumingTxId' near line 1.
I'm using Kotlin btw.
My entity:
class StateDetailEntity(
#Id
#Column(name = "issue_tx_id")
val issueTxId: String,
#Column(name = "consuming_tx_id")
val consumingTxId: String?
)
My named query:
NamedQuery(
name = "StateDetailEntity.consume",
query = "UPDATE StateDetailEntity SET " +
"consumingTxId = :consumingTxId " +
"WHERE issueTxId = :issueTxId " +
"AND consumingTxId IS NULL"
)
If I add an alias to the table and re-write the name query to like UPDATE StateDetailEntity s SET... I get the following error:
org.hibernate.hql.internal.ast.QuerySyntaxException: expecting EOF, found 's'.
The funny thing is if I change the query like this:
NamedQuery(
name = "StateDetailEntity.consume",
query = "UPDATE StateDetailEntity SET " +
"consumingTxId = ?1 " +
"WHERE issueTxId = ?2 " +
"AND consumingTxId IS NULL"
)
There are no issues at all. Any ideas? Using Hibernate 5.4.32.Final.
So my problem is the following:
I have a table I want a filter to apply to. This filter should call a query which finds based on the given information the reports.
This is how my query looks:
#Query("SELECT r FROM Report r WHERE r.importanceLevel = COALESCE(importance,'%')" +
"AND r.source = COALESCE(source,'%')" +
"AND r.resolvedStatus = COALESCE(resolvedStatus,'%')" +
"AND r.header LIKE + '%' COALESCE(query,'%') + '%'")
List<Report> getReportsByAppliedFilter(#Param("importance") int importance, #Param("source") String source,
#Param("resolvedStatus") int resolvedStatus, #Param("query") String query);
Problem is: IntelliJ does not like the following:
LIKE + '%' COALESCE(query,'%') + '%'
Error: expected, got +
Do you have any idea how to solve this otherwise?
Yeah, time to go to bed. You dont use + for concat , you use concat():
#Query(value = "SELECT r FROM Report r WHERE r.importanceLevel = COALESCE(importance,'%')" +
"AND r.source = COALESCE(source,'%')" +
"AND r.resolvedStatus = COALESCE(resolvedStatus,'%')" +
"AND r.header LIKE CONCAT('%', COALESCE(query,'%'), '%')")
If your column name is request_status and table name is connections then use COALESCE like
#Query(value = "SELECT connections.id, COALESCE(connections.request_status,'') as request_status.... ", nativeQuery = true)
List<ZXYType> xysfunction();
Here if request_status is null then it will be replaced by an empty string.
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()
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);