CRUDRepository native query with parameter - spring-boot

I am using a native query in spring data JpaRepository like below :
#Query(value = "SELECT SUBSTRING_INDEX(u.email, '#', -1) as domain, COUNT(*) as domainCount r.invite_organization_id"
+ " FROM users u,_registrations r where u.user_id=r.user_id and r.invite_organization_id=?1"
+ " GROUP BY "
+ "SUBSTRING_INDEX(u.email, '#', -1) ORDER BY domainCount DESC", nativeQuery = true)
List<Object[]> countTopDomain(String orgId);
The above gives me the following exception :
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 'r.invite_organization_id FROM users u,registrations r where u.user' at line 1
How will I pass the value for invite_organization_id(in the query ) from the method countTopDomain() argument.

'r.invite_organization_id FROM srs_users u,srs_user_registrations r', have syntax error. ',' is missing after count (*) as domainCount

Try this one
#Query(value = "SELECT SUBSTRING_INDEX(u.email, '#', -1) as domain, COUNT(*) as domainCount, r.invite_organization_id"
+ " FROM srs_users u,srs_user_registrations r where u.user_id=r.user_id and r.invite_organization_id=?1"
+ " GROUP BY "
+ "SUBSTRING_INDEX(u.email, '#', -1) ORDER BY domainCount DESC", nativeQuery = true)
List<Object[]> countTopDomain(String orgId);

Related

repeated data in json response spring boot

I have this SQL query
#Query( value = "select tc_users.id as userid,tc_devices.id as deviceid, tc_devices.name, tc_devices.lastupdate as hora_fecha,\n" +
"tc_positions.speed as velocidad, tc_positions.latitude, tc_positions.longitude, tc_positions.devicetime\n" +
"from tc_devices\n" +
"join tc_users on tc_users.id = tc_devices.userid \n" +
"join tc_positions on tc_devices.id= tc_positions.deviceid and \n" +
"tc_positions.devicetime=(select max(devicetime) from tc_positions where tc_positions.deviceid= tc_devices.id) and tc_users.id= ?1 ;", nativeQuery = true)
List<resumen_entity> resu(Integer userid);
This SQL query return this data
result of query in SQL workbench
but when using it with my spring project it returns this json
result of query by springboot
a really need help with this problem
I try with another type of SQL query but spring returns the same result
#Query( value = "select distinct tc_users.id as userid,tc_devices.id as deviceid, " +
"tc_devices.name, tc_devices.lastupdate as hora_fecha, " +
"tc_positions.speed as velocidad, tc_positions.latitude, " +
"tc_positions.longitude, tc_positions.devicetime " +
"from tc_users, tc_devices,tc_positions where tc_users.id =tc_devices.userid " +
"and tc_devices.id= tc_positions.deviceid " +
"and tc_positions.devicetime=(select max(devicetime) " +
"from tc_positions where tc_positions.deviceid = tc_devices.id) and tc_users.id= ?1 ",
nativeQuery = true)
List<resumen_entity> resu(Integer userid);

Adding a parameter to a native query in Spring Boot causes "org.hibernate.exception.SQLGrammarException",

I've created a native query in a Spring Boot project which works fine when there is no parameter, as follows:
#Query(nativeQuery = true, value="SELECT system_name as systemName, norcaType as norcaType, "
+ "device_number as deviceNumber, feature_vector as featureVector, code as norcaCode, count(*) as sum "
+ "FROM (SELECT a.id, a.object_id, a.system_name, b.norca_type AS norcaType, device_number, "
+ "b.feature_vector, a.seqnb, a.object_index, c.code "
+ "FROM system_objectdata a "
+ "JOIN sick_il_dacq.system_barcode_norca b "
+ "ON a.id = b.system_objectdata_id "
+ "AND a.partition_key = b.partition_key "
+ "JOIN system_feature_vector c "
+ "ON b.feature_vector = c.id "
+ "JOIN sick_il_services.system_device d "
+ "ON b.device_number = d.id) detail "
+ "GROUP BY system_name, device_number, feature_vector")
public List<INorcaSummarySystemDeviceDTO> getNorcaSummaryBySystemAndDeviceAllSystems();
However, when I add a where clause with a single parameter to it, it gives a mysql grammar exception.
Here's the new query with the WHERE clause and the parameter:
#Query(nativeQuery = true, value="SELECT system_name as systemName, norcaType as norcaType, "
+ "device_number as deviceNumber, feature_vector as featureVector, code as norcaCode, count(*) as sum "
+ "FROM (SELECT a.id, a.object_id, a.system_name, b.norca_type AS norcaType, device_number, "
+ "b.feature_vector, a.seqnb, a.object_index, c.code "
+ "FROM system_objectdata a "
+ "JOIN sick_il_dacq.system_barcode_norca b "
+ "ON a.id = b.system_objectdata_id "
+ "AND a.partition_key = b.partition_key "
+ "JOIN system_feature_vector c "
+ "ON b.feature_vector = c.id "
+ "JOIN sick_il_services.system_device d "
+ "ON b.device_number = d.id"
+ "and a.system_name = ?1 ) detail "
+ "GROUP BY system_name, device_number, feature_vector")
public List<INorcaSummarySystemDeviceDTO> getNorcaSummaryBySystemAndDeviceOneSystem(String systemName);
I know the raw SQL works with the where clause because I can run it in MySql Workbench.
I also know that the parameter is correctly getting through because I see it in the debugger and it's showing up on the log as well.
I've tried both the named and index variable and get the same result each time.
Any idea what the problem is?
This is the error being printed in the log:
2021/12/21 17:25:47.799 | ERROR | http-nio-8181-exec-6 | o.a.c.c.C.[.[.[.[dispatcherServlet]] | Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
java.sql.SQLSyntaxErrorException: 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 'a.system_name = '02') detail GROUP BY system_name, device_number, feature_vector' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:536)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:513)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:115)
at com.mysql.cj.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:1983)
at com.mysql.cj.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1826)
seems you missed a space after d.id in this line "ON b.device_number = d.id", change it to "ON b.device_number = d.id " and test

I use #Query annotation in Jpql, I modified my query with additional "distinct", How to Fix it?

In my Repositories, I modified my query with additional "distinct" and it can't work
#Query(value = "select distinct i from Item i "
+"where i.store = ?1 and i.itemVariant IN ?2 "
+"and i.status = ?3 " )
Page<Item> findByStoreAndItemVariantInAndStatus
(Store store, List<ItemVariant> itemVariant ,byte status, Pageable pageable);
if I remove the additional modifying #Query, this works but the result is duplicated
I have fixed it. I change it using native query and changed distinct to group by, and it's works
#Query(value = "SELECT i.* "
+" FROM public.mst_item as i "
+" join public.mst_store as ist "
+" on i.store_id = ist.id "
+" join public.mst_item_classifiers as iv "
+" on iv.item_id = i.id "
+" where ist.id = :store and iv.name IN "
+" (select ic.name from public.mst_item_classifiers as ic "
+" where ic.name like concat('%',:itemVariant,'%') and ic.status = :status ) "
+" and i.status = :status "
+" group by ?#{#pageable}, i.id",
nativeQuery = true)
Page<Item> findByStoreAndItemVariantInAndStatus(#Param("store")Store store,#Param("itemVariant") String itemVariant , #Param("status") byte status, Pageable pageable);

#Query not recognizing parameters if they are inside single quote in Spring Framework

I have a big problem with Spring Data in #Query.
I have the following query :
SELECT created_at::DATE "date",
count(*)
FROM
absence
WHERE
created_at::DATE between '2018-05-27' AND '2018-05-31'
GROUP BY created_at::DATE;
this query works in postgres without any problem now in spring to use it :
#Query("SELECT created_at\\:\\:DATE \"date\",count(*) FROM absence " +
"WHERE created_at\\:\\:DATE between '?1' AND '?2' " +
"GROUP created_at\\:\\:DATE", nativeQuery = true)
fun getAbsenceCount(beginDate: String,endDate: String): List<AbsenceCount>
This query doesn't work at all, the problem is that spring can't recognize the parather beginDate (?1) & endDate (?2).
I tried a lot of solution from stackoverflow like solution and solution 2 but I can't get rid of this problem.
I don't know if it's intented or it's a bug in spring.
Try to simply use the classic SQL cast function:
#Query(value = "" +
"select " +
" cast(a.created_at as date) as createdAt, " +
" count(*) as quantity " +
"from " +
" absence a " +
"where " +
" cast(a.created_at as date) between ?1 and ?2 " +
"group " +
" cast(a.created_at as date)" +
"", nativeQuery = true)
fun getAbsenceCount(beginDate: String, endDate: String): List<AbsenceCount>
where AbsenceCount is a projection like this (java):
public interface AbsenceCount {
LocalDate getCreatedAt();
Long getQuantity();
}

Unable to get out of ORA-00907 error

I am getting the missing right paranthesis error. If I remove the comments around iterator.next() statement, its working fine. Unable to figure out whats wrong. There is NO "(" in the data I pass.
String ORACLE_SUM_QUERY = "select item_number, sum(system_quantity) from ITEMS " +
"where sndate = ? and item_id in" +
" (select item_id from ap.system_items where org_id = 4 " +
" and segment1 in ";
......
while (iterator.hasNext()) {
//iterator.next();
String oracleQuery = String.format(ORACLE_SUM_QUERY + "(%s)) GROUP BY item_number", iterator.next());
preparedStat = connection.prepareStatement(oracleQuery);
preparedStat.setDate(1, getSnDate());
The error seems to indicate that the SQL statement you are building up in oracleQuery has an incorrect number of parenthesis. It would probably be helpful to print that SQL statement out before passing it to the prepareStatement call to make debugging easier.
My guess is that the string that is returned by iterator.next() is not what you expect.
Try rewriting your code as
String ORACLE_SUM_QUERY = "select item_number, sum(system_quantity) from ITEMS " +
"where sndate = ? and item_id in" +
" (select item_id from ap.system_items where org_id = 4 " +
" and segment1 in (";
......
while (iterator.hasNext())
{
ORACLE_SUM_QUERY = ORACLE_SUM_QUERY + String.format("%s", iterator.next());
if(iterator.hasNext())
ORACLE_SUM_QUERY = ORACLE_SUM_QUERY + ",";
}
ORACLE_SUM_QUERY = ORACLE_SUM_QUERY + ")) GROUP BY item_number";
preparedStat = connection.prepareStatement(ORACLE_SUM_QUERY);
preparedStat.setDate(1, getSnDate());
This may not get it exactly as I can't test it, but it might get you closer.
Share and enjoy.

Resources