execute preparedStatement in getSqlMapClientTemplate - spring

I want to execute prepardStatement in getsqlMapClientTemplate() method.One of preparedStatement parameter value is received by another query result.Is it possible to execute like this?
like
String query="select Id_no from employee";
String resultQuery="select empSalary from employeePay where Id=?";
prepareStatement ps=con.preprepareStatement(query); // Instead of connection reference i want to use getSqlMapClientTemplate
ResultSet rs=ps.executeQuery();
while(rs.next()){
//pst.setInt(1,rs.getInt(1)); // here if i want to pass dynamic value to execute resultQuery
pst.setInt(1,userGivenValue);
PrepareStatement pst=con.prepareStatement(resultQuery); //
pst.executeQuery();
forpreparedStatement instead of connection object i want to use getSqlMapClientTemplate() method.

You don't want a SqlMapClientTemplate you want a JdbcTemplate instead.
Next your solution is flawed as it falls into the 1+N select problem, ie. you execute a single query to get a list of ids then for each id issue another query. Creating a single query which does everything in one shot is more effecient.
final String query = "select empSalary from employeePay where Id in (select Id_no from employee)"
JdbcTemplate template = getJdbcTemplate();
List<Long> salaries = template.queryForList(query, Long.class);
Something like that.
Or if you want to use the SqlMapClientTemplate simply add the query to the ibatis configuration and let iBatis (instead of the JdbcTemplate) handle the hard lifting for you.

Related

Getting Second Order SQL Injection in Spring Hibernate

I am facing Second Order SQL Injection in the Spring-Hibernate application after scanning through the Checkmarx tool, I have gone through multiple questions in StackOverflow and in other platforms as well but did not get the right finding.
could you please look into the below code snip,
public String getOrderId(order_name){
String returnId= null;
Query query = entityManager.createNativeQuery("select order_id from order where order_name=?");
List<String> dataset = query.setParameter(1,order_name).getResultList();
if(dataset!=null){
returnId = dataset. Get(0);
}
return returnId;
}
In this above method, while calling getResultList(), getting a high vulnerability issue that, this method returns data flows through the code without being properly sanitized or validated, and eventually used in further database query in the method.
Earlier code was like this,
public String getOrderId(order_name){
String returnId= null;
String q = "select order_id from order where order_name="+order_name;
Query query = entityManager.createNativeQuery(q);
and directly it was used as a string append in query, which I have modified with set parameter,
Query query = entityManager.createNativeQuery("select order_id from order where order_name=?");
List<String> dataset = query.setParameter(1,order_name).getResultList();
but still after getting data from query.getResultSet(), it is asking for sanitizing and validating the data before use in further database query method.
and this return data is being used in further query like select * from return_Data where clause. (properly used in where clause to set parameter to avoid SQL injection).
and in the above query is used in another method where we pass return_Data as input to it.
could you please help here to know what checks and validation can be added to overcome this type of issue. Thanks in advance for prompt response.

Spring Data JPA - How do i get a list of specific rows by ids?

I'm trying to get specific rows from the table by ids, but what I have below is not working.
#Query(value = "SELECT * FROM row r where r.row_id = :row_ids", nativeQuery = true)
List<Object> temp(#Param("albumsIds") String row_ids);
row_ids is all the ids separated by an "or" - id:1 or id:2 or id:3
I'm just trying to do select * from row r where r.row_id = id:1, or r.row_id = id:2, or r.row_id = id:3
Does anyone have an idea what the problem is, or is there a better way to do it?
Simply use:
List<Object> findByIdIn(Collection<Integer> ids);
That will automatically setup the derived query from the query method name itself.
Alternatively, if you want to provide the query programmatically, then the query should be:
#Query(value = "SELECT * FROM row R WHERE R.row_id IN :ids", nativeQuery = true)
List<Object> temp(#Param("ids") Collection<Integer> ids);
MySQL lets use use the IN keyword in queries, which let's us provide a CSV for the IDs to parse and returns any records which ID is in the CSV. This obviously can be used on any data, just for this purpose we'll use the IDs as an example.
Using the method above should minimize the risk of SQL injection significantly, as the Java Collection type casting shouldn't allow a user to provide any values that can cause issues.

Spring data jpa projection could not extract ResultSet

I'm trying to map my entity to projection using the below query but i'm getting error as
Exception : could not extract ResultSet SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
here is the query
#Query("select rf.rfqID as rfqID,rf.creationDate as creationDate," +
"rf.deadLineDate as deadLineDate,rf.details as details," +
"rf.message as message, rf.rfqDoc as rfqDoc," +
"CASE WHEN (rf.creationDate > CURRENT_DATE) THEN 'open' ELSE 'closed' END as status," +
"rf.rfqMembers as rfqMembers " +
"from RFQ rf where rf.createdBy = ?1")
Page<RfqDto> loadAllRfq(String creator, Pageable pageable);
In my Dto I have an extra status column which I don't want to persist in db and would like to get the status via query
here is my projection interface
public interface RfqDto {
String rfqID();
Date creationDate();
Date deadLineDate();
String details();
String message();
String rfqDoc();
String status();
List<RfqMember> rfqMembers();
}
The root cause of your problem is here:
In my Dto I have an extra status column which I don't want to persist in db and would like to get the status via query
As it's explained in the documentation:
The important bit here is that the properties defined here exactly match properties in the aggregate root.
...
The query execution engine creates proxy instances of that interface at runtime for each element returned and forwards calls to the exposed methods to the target object.
So, you can not use spring data jpa projection for your case. You can not use hibernate/jpa projection as well, because it dose not support collections in row results.
You can try to use Blaze-Persistence Entity Views. See for example this answer.

Cassandra select query with Bind Variables in java8

I am trying to execute a Cassandra query in Java8.
My query is
SELECT * FROM customer where aor='north'
and I execute it with
session.execute(query)
and got correct answer.
But then I changed my query to SELECT * FROM customer where aor=?
PreparedStatement statement = session.prepare(query);
BoundStatement boundStatement = statement.bind("'north'");
ResultSet results = session.execute(boundStatement);
for (Row row : results) {
System.out.println(row.toString());
}
This is not working. No errors showing but I am not getting any result.
Can someone please help
When you are using statement.bind("'north'"); it means that you want literally find 'north'.
Just change your string to north and it will work as you wanted

HQL like operator for case insensitive search

I am implementing an autocomplete functionality using Jquery, when I type the name, it fetches the record from the db, The records stored in db are mixture of capital & small letters. I have written a HQL Query which fetches me the records with case-sensitive, but I need to records irrespective of case. Here is the query,
List<OrganizationTB> resultList = null;
Query query = session.createQuery("from DataOrganization dataOrg where dataOrg.poolName
like '%"+ poolName +"%'");
resultList = query.list();
Ex : If I have pool names, HRMS Data set, Hrms Data, Hr data etc... if I type HR or hr I need to get all the 3 records, which I'm not able to.
Please help...
change your query to
"from DataOrganization dataOrg where lower(dataOrg.poolName)
like lower('%"+ poolName +"%')"
for more information have a look 14.3 doc
A good solution is:
List<OrganizationTB> resultList = null;
Query query = session.createQuery("from DataOrganization dataOrg where lower(dataOrg.poolName) like lower(:poolName)");
query.setParameter("poolName", '%'+poolName+'%', StringType.INSTANCE);
resultList = query.list();
So you protect your code from SQL injection

Resources