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?
Related
I want to implement JPA Projection with count. I tried this:
#Query(value = "SELECT new org.service.PaymentTransactionsDeclineReasonsDTO( id, count(id) as count, status, error_class, error_message) " +
" FROM payment_transactions " +
" WHERE terminal_id = :id AND (created_at > :created_at) " +
" AND (status != 'approved') " +
" GROUP BY error_message " +
" ORDER BY count DESC", nativeQuery = true)
List<PaymentTransactionsDeclineReasonsDTO> transaction_decline_reasons(#Param("id") Integer transaction_unique_id, #Param("created_at") LocalDateTime created_at);
But I get error: Caused by: java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.plugin.service.PaymentTransactionsDeclineReasonsDTO( id, count(id) as c' at line 1
How I can implement proper count when I have class based Projection?
Try Interface-based Projection instead of DTO:
public interface TransactionDeclineReason {
Integer getId();
Long getCount();
Status getStatus();
ErrorClass getErrorClass(); // I suppose it's enum...
String getErrorMessage();
}
#Query(value = "select " +
"id as id, " +
"count(id) as count, " +
"status as status, " +
"error_class as errorClass, " +
"error_message as errorMessage " +
"from " +
"payment_transactions " +
"where " +
"terminal_id = ?1 " +
"and created_at > ?2 " +
"and status != 'approved' " +
"group " +
"by error_message " +
"order by " +
"2 desc", nativeQuery = true)
List<TransactionDeclineReason> getTransactionDeclineReasons(Integer transactionId, LocalDateTime createdAt);
Pay attention on aliases (i.e. id as id) - they are mandatory.
You are mixing JPQL and SQL syntax.
The constructor expression (new ...) is JPQL, but in the annotation you mark it as a nativeQuery i.e. as SQL so you have to make up your mind.
If it is to be SQL I don't think you can use aliases in the ORDER BY clause, so you might have to either repeat the expression or wrap it in a subselect as described here: Using an Alias in a WHERE clause.
If it is to be JPQL it doesn't support aliases in a constructor expression, so I guess you have to repeat the expression in the order by clause.
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();
This question already has answers here:
Jpa namedquery with left join fetch
(2 answers)
Closed 5 years ago.
I'm using spring data JPA and I want to write a SQL query in my repository.
I have a following SQL query (notice the LEFT JOIN):
SELECT * FROM institution LEFT JOIN
(select * from building_institutions where building_institutions.building_id = 1) as reserved_institutions
ON reserved_institutions.institutions_user_id = institution.user_id
WHERE reserved_institutions.institutions_user_id is null;
and i want to execute it in my InstitutionRepository which is as follows:
#Repository
public interface InstitutionRepository extends JpaRepository<Institution, Long>, PagingAndSortingRepository<Institution,Long> {
// doesn't work
//#Query("SELECT b.institutions as bi FROM Building b left join Institution i WHERE bi.building_id not in :id")
Page<Institution> findPotentialInstitutionsByBuildingId(#Param("id") Collection<Long> id, Pageable pageable);
// doesn't work
#Query(
value = "SELECT * FROM kits_nwt.institution LEFT JOIN\n" +
"(SELECT * FROM kits_nwt.building_institutions WHERE kits_nwt.building_institutions.building_id = ?1) AS reserved_institutions\n" +
"ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id\n" +
"WHERE reserved_institutions.institutions_user_id IS null ORDER BY ?#{#pageable}",
nativeQuery = true)
Page<Institution> findPotentialInstitutionsByBuildingId(Long userId, Pageable pageable);
}
So, I want to get all institutions which are not in building with certain ID (which I will send as a parameter).
Here is my current DB data:
Institutions:
Building institutions:
What I want: (in this query, the id is set on 1, for presentation purposes)
I have looked at many SO questions and answers (such as this one) but I haven't been able to figure out the solution.
So, how do I write this query so that I get what I want?
Edit 1:
#KevinAnderson Currently, I'm trying with:
#Query(
value = "SELECT username, password, description, location, title, user_id FROM (institution INNER JOIN user ON institution.user_id = user.id) LEFT JOIN\n" +
"(SELECT * FROM building_institutions WHERE building_institutions.building_id = 1) AS reserved_institutions\n" +
"ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id\n" +
"WHERE reserved_institutions.institutions_user_id IS null ORDER BY ?#{#pageable}",
nativeQuery = true)
Page<Institution> findPotentialInstitutionsByBuildingId(Long userId, Pageable pageable);
And I'm getting this exception:
MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE) FROM building_institutions WHERE building_institutions.building_id = 1) A' at line 2
Edit 2:
#StanislavL here it is:
The problem is that your query gets me the institution with ID 25 because it is in both building with ID 1 and building with ID 2. When you do a JOIN, you have 2 rows ON institution ID being 25 in both institution table and building_institutions table. Then, your WHERE condition removes one from those two rows and I get one row where instituiton ID is 25, and I don't want what.
Here is an image for the above:
Edit 3 - this question is not a duplicate because of the following:
My query is with pagination (I added "with pagination" to the question title)
I'm not using #NamedQuery but #Query
My mistake was that I didn't write countQuery parameter to the #Query annotation
I solved it...
The query needs to look like this:
#Query(
value = "SELECT * FROM \n" +
"(institution INNER JOIN user ON institution.user_id = user.id) \n" +
"LEFT JOIN \n" +
"(SELECT * FROM \n" +
"building_institutions \n" +
"WHERE building_id = :userId)\n" +
" AS reserved_institutions \n" +
"ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id \n" +
" where reserved_institutions.institutions_user_id IS null \n"
+ "ORDER BY ?#{#pageable}"
,
countQuery = "SELECT count(*) FROM \n" +
"(institution INNER JOIN user ON institution.user_id = user.id) \n" +
"LEFT JOIN \n" +
"(SELECT * FROM \n" +
"building_institutions \n" +
"WHERE building_id =:userId)\n" +
" AS reserved_institutions \n" +
"ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id \n" +
"where reserved_institutions.institutions_user_id IS null \n" +
"ORDER BY ?#{#pageable}",
nativeQuery = true)
Page<Institution> findPotentialInstitutionsByBuildingId(#Param("userId") Long userId, Pageable pageable);
I was getting the error at line 4 near WHERE, when my query looked like this:
#Query(
value = "SELECT username, password, description, location, title, user_id FROM (institution INNER JOIN user ON institution.user_id = user.id) LEFT JOIN\n" +
"(SELECT * FROM building_institutions WHERE building_institutions.building_id = 1) AS reserved_institutions\n" +
"ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id\n" +
"WHERE reserved_institutions.institutions_user_id IS null ORDER BY ?#{#pageable}",
nativeQuery = true)
Page<Institution> findPotentialInstitutionsByBuildingId(Long userId, Pageable pageable);
and that was because I didn't add the countQuery parameter to the #Query annotation.
Big thanks to all of you who tried to help.
I hope that I save someone else many hours of misery.
Cheers! :)
I'm trying to use hibernate to make a simple SQL UPDATE query and map the result row into Hibernate entity (Using the createSQLQuery).
String updateQuery =
String.format("UPDATE \"user\" "
+ "SET chips_balance=chips_balance + %d, diamonds_balance=diamonds_balance + %d "
+ "WHERE id=%d", chips_delta, diamonds_delta, userId);
User user = (User)session.createSQLQuery(updateQuery).uniqueResult();
This throws an Exception:
org.hibernate.exception.GenericJDBCException: could not extract ResultSet
Cause:
org.postgresql.util.PSQLException: No results were returned by the query.
How can I make this work? (Using the RETURNING keyword)
This is how to achieve it:
String updateQuery =
String.format( "UPDATE \"user\" "
+ "SET chips_balance=chips_balance + %d, diamonds_balance=diamonds_balance + %d "
+ "WHERE id=%d "
+ "RETURNING *", 100, 5, 64);
User user = (User) session.createSQLQuery(updateQuery)
.addEntity(User.class)
.uniqueResult();
The key point here is to use "RETURNING *" and map it to the entity using .addEntity(User.class)
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()