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

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

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);

Alias Column In Resultset

I have a query in backend spring project, where I create a field alias named agent_id but I don´t have that column in Model. What is the best approach for showing this as a field in table view in front end???.
Here´s the query:
Query query = em.createNativeQuery("SELECT" +
" ips.*, " +
" s.mls_id AS imported," +
" p.INTEGRATOR_SALES_ASSOCIATED_ID AS agent_id " +
"FROM test1.ilist_property_summary ips " +
" LEFT JOIN test1.statistics s ON s.mls_id = ips.INTEGRATOR_PROPERTY_ID " +
" LEFT JOIN test1.person p ON p.INTEGRATOR_SALES_ASSOCIATED_ID = ips.INTEGRATOR_SALES_ASSOCIATED_ID " +
"WHERE ips.AGENCY_ID = :agencyId AND (s.statistics_type = 1 OR s.statistics_type IS NULL) AND ips.ORIG_LISTING_DATE BETWEEN :startDate AND :endDate");
query.setParameter("agencyId", agencyId)
.setParameter("startDate", DateUtil.asDate(startDate), TemporalType.DATE)
.setParameter("endDate", DateUtil.asDate(endDate), TemporalType.DATE);
return (List<PropertyVO>) query.getResultList().stream().map(o -> processProperty((Object[]) o)).collect(Collectors.<PropertyVO>toList());
I already have a field that shows agent_id, but not fetched with same field of table Person. I need to retrieve that field agent id alias fetched from left join.
I followed another approach:
Query query = em.createNativeQuery("SELECT" +
" ips.id, ips.agency_id, ips.integrator_property_id, ips.orig_listing_date, ips.contract_type," +
" ips.transaction_type, ips.current_listing_price, ips.current_listing_currency, ips.apartment_number, ips.commercial_residential," +
" ips.commission_percent, ips.commission_value, ips.property_type, ips.street_name, ips.street_number," +
" s.mls_id AS imported," +
" p.INTEGRATOR_SALES_ASSOCIATED_ID AS INTEGRATOR_SALES_ASSOCIATED_ID" +
" FROM test1.ilist_property_summary ips " +
" LEFT JOIN test1.statistics s ON s.mls_id = ips.INTEGRATOR_PROPERTY_ID " +
" LEFT JOIN test1.person p ON p.INTEGRATOR_SALES_ASSOCIATED_ID = ips.INTEGRATOR_SALES_ASSOCIATED_ID " +
"WHERE ips.AGENCY_ID = :agencyId AND (s.statistics_type = 1 OR s.statistics_type IS NULL) AND ips.ORIG_LISTING_DATE BETWEEN :startDate AND :endDate ");
Here field
INTEGRATOR_SALES_ASSOCIATED_ID
is taken from table p, and not from ips. I just selected specific fields so this one could be taken from the other table.

Sub query with lambda expression

I need lambda expression for the below query.
select tb_device.lat,tb_device.lng,tb_device.speed,tb_device.trackedOn, IL.DeviceIcon, IL.speedLimit, " +
"IL.deviceId, IL.deviceName, tb_device.Location, tb_device.IsExist " +
"from( select CONVERT (DATE, max( trackedOn)) as trackedDate , inventoryLogId as InventoryId from tb_devicelog " +
"group by inventoryLogId) as tb " +
"inner join tb_devicelog as tb_device on tb.InventoryId=tb_device.inventoryLogId and " +
"tb.trackedDate= CONVERT (DATE, tb_device.trackedOn) " +
"inner join tb_inventorylog IL on tb_device.inventorylogid=IL.id " +
"inner join tb_Logins ln on IL.assignedToCustId = ln.customers_id where ln.userName = 'cadmin' and IL.id in(1,3,2 )"
You could try Linqer which is a SQL to LINQ converter:
http://www.sqltolinq.com/

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.

Issue using Oracle date function with Spring's NamedParamenterJdbcTemplate

I'm having an issue trying to get my SQL query which works fine in SQL Developer (Oracles free database tool) to also work using Spring's NamedParameterJdbcTemplate class.
My query is:
String sql = " SELECT COUNT(*) FROM ( " +
" SELECT FE.USR_ID, MAX(FE.DATE_FIRST_SUB) AS SUB_DATE " +
" FROM FC, FE " +
" WHERE FC_STATUS = 'MEMBER' " +
" AND FC.FC_SPC_ID = :spcId " +
" AND FE.FE_USR_ID = FC.FC_USR_ID " +
" AND FE.DATE_FIRST_SUB IS NOT NULL " +
" GROUP BY FE_USR_ID " +
" ) " +
" WHERE SUB_DATE BETWEEN TO_DATE('01-JUN-2011', 'DD-MON-YYYY') AND TO_DATE('01-JUL-2011', 'DD-MON-YYYY') ";
It has something to do with my dates, formatting perhaps? When I don't use the WHERE clause in the outer select it works, when it's included 0 is returned from the count - as I mentioned running the SQL directly returns expected results.
Any advice?
Thanks.
Oh my, I was in fact looking at the wrong database!!

Resources