Spring jdbcTemplate executing query - oracle

I have a strange problem ,
My Query looks like below.
String tokenQuery = "select id from table
where current_timestamp between
creation_time and (creation_time + interval '10' minute)
and token = '"+Token+"'";
But when I run, jdbcTemplate.queryForLong(tokenQuery) , no matter what , it always throws EmptyDataAccessException.
I am executing this in Oracle
Can we not append dynamic values to string and then pass it as a query and execute ?
What could be the issue ?

I assume that what you get is in fact an EmptyResultDataAccessException. The javadoc of this exception says:
Data access exception thrown when a result was expected to have at least one row (or element) but zero rows (or elements) were actually returned.
That simply means that the query is executed fine, and is supposed to return one row, but doesn't return any. So no row satisfies the criteria of your query.
If that is expected, then catch the exception, or use a method that returns a list rather then returning a single value. That way, you can test if the returned list is empty.
That said, you should use a parameterized query instead of concatenating the token like you're doing. This would prevent SQL injection attacks. It would also work even if the token contains a quote, for example.

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.

Converting Object to Class object

in my Spring MVC project i m using Hibernate, by using Criteria API i am applying Group BY and Order BY clause. Query get executed on DB successfully and it brings result also but its an array of Object--
Here is code of Criteria API
Criteria criteria = session.createCriteria(DashboardSubindicatorSubmission.class, "DashboardSubindicatorSubmission")
.setProjection(Projections.projectionList()
.add(Projections.sum("InputValue").as("InputValue"))
.add(Projections.groupProperty("fkAccademicYearId"))
.add(Projections.groupProperty("fkAssessmentPlanID"))
.add(Projections.groupProperty("fkSubindicatorID"))
.add(Projections.groupProperty("InputTitle")))
.addOrder(Order.asc("fkAccademicYearId"))
.addOrder(Order.asc("fkAssessmentPlanID"))
.addOrder(Order.asc("InputTitle"));
List<DashboardSubindicatorSubmission> dashboardSubindicatorSubmissionList = (List<DashboardSubindicatorSubmission>)criteria.list();
session.flush();
transaction.commit();
return dashboardSubindicatorSubmissionList;
I am casting criteria.list() to List<DashboardSubindicatorSubmission> but when i try to do dashboardSubindicatorSubmissionList.get(i) on controller it gives me exception java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to mkcl.accreditation.model.DashboardSubindicatorSubmission.
i come to know that, though i m casting it to List<DashboardSubindicatorSubmission> still its an list of object[] thats why i cant do dashboardSubindicatorSubmissionList.get(i) because it returns me object of DashboardSubindicatorSubmission. (Correct me if i am wrong)
So how can i convert my result into list of DashboardSubindicatorSubmission class?
Does setResultTransformer() helps me in this case?
You have two options. When you use projections, Hibernate doesn't know how to respect each field because it uses the name of each field to build objects and he doesn't know the names yet.
Thus, your first option is to name the fields grouped so that they match the names of object properties. This is necessary even if the string you use in projection is already the name of the object field. Something like:
.add(Projections.groupProperty("fkAccademicYearId"), "fkAccademicYearId") // same value
.add(Projections.groupProperty("fkAssessmentPlanID"), "other") // other value
The second option is to do what you yourself suggested, create your own implementation of ResultTransformer. I reckon this a interesting option if you want to extract other object of this query, as when you make a report.

How to handle missing rows in a dependent table

I have two Sql Server tables accessed through Entity Framework 4. They are joined by a single key with 0 to 1 rows on the dependent side of the join. Here is my linq query.
var typeDtoList = from type in typeList
select (new DxStudioTypeDto(parent,
isChildrenLoadOnDemand,
businessFacade,
server,
database,
type.typeGuid,
type.typeName,
type.writerName,
type.managerName,
type.Reporting_Type.MRef_Status,
type.Reporting_Type.Exists_In_Drop));
Obviously, if the Reporting_Type returns zero rows, the linq expression throws a null reference exception on the last two parameters of the DxStudioTypeDto constructor:
type.Reporting_Type.MRef_Status,
type.Reporting_Type.Exists_In_Drop));
Is there a way to detect the absence of a Reporting_Type row and substitute a default string? DxStudioTypeDto is an immutable type, so I need all the parameters available when I instanciate a new object. Any other strategies for this situation?
Did you try this?
((type.Reporting_Type == null) ? "some default value" : type.Reporting_Type.MRef_Status)
I know sometimes the EF engine returns a "the provider does not support this operation" for this kind of thing, but it's worth a try.

no supported translation to SQL Help Linq -> SQL

I have a query that has a where clause that checks if the data element is contained within a list.
This query executes fine:
results = awardedStats.Where(r => guidReq.Contains(r.RequirementId) || orgAcr.Contains(r.Division))
.Select(r => r);
however this does not:
results = awardedStats.Where(r => guidReq.Contains(r.RequirementId) || orgAcrId.Contains(r.guidDivisionId))
.Select(r => r);
r.division is a string and orgAcr is a List
r.guidDivisionId is a Guid and orgAcrId is a List
I know that each list get the correct values, I can check the list in the debugger, but if I run the first query, everything runs through fine, if I run the second query I get an error stating that the member "guidDivisionId" has no supported translation to SQL
If orgAcrId is a List<Guid> and r.guidDivisionId is a uniqueidentifier column in SQL Server, this should be fine. Are you sure the column name isn't r.DivisionId?
Get all data from sql and call AsEnumarable() method on it and then apply the where. That way comparison would be done in memory and it won't complain about sql translation.
Another thing is that when you use contains, it's converted to Sql IN clause. All elements in the list are included in the IN clause. If your list has more than 2100 elements, then you would get sql exception saying that sql cannot accept more than 2100 parameters. Doing this kind of comparison in memory is safer.

In Linq, what's the difference between .FirstOrDefault and .SingleOrDefault

I don't know the difference between FirstOrDefault and SingleOrDefault. When should I use the first and when should I use the second?
FirstOrDefault() is for when zero or more results are expected to be present in the input collection and the call returns the first item if there are multiple results, Default if none.
SingleOrDefault() is for when zero or one result is expected in the input collection and the call returns the one result if exactly one result is present, Default if no results and exception if more than one result.
SingleOrDefault will throw a "Sequence contains more than one element" exception if more than one item exists.
firstordefault it will take number of rows but will just return first one of it if it is
null it can handle the exception
First it will take number of rows but will just return first one of it if it is
null it will throw the exception
singleordefault it will take only one row but will return it can handle exceptions if it is null
single it will take only one row but will return it & cannot handle exceptions
If your result set returns 0 records:
SingleOrDefault returns the default value for the type (e.g. default for int is 0)
FirstOrDefault returns the default value for the type
If you result set returns 1 record:
SingleOrDefault returns that record
FirstOrDefault returns that record
If your result set returns many records:
SingleOrDefault throws an exception
FirstOrDefault returns the first record
Conclusion:
If you want an exception to be thrown if the result set contains many records, use SingleOrDefault.
If you always want 1 record no matter what the result set contains, use FirstOrDefault

Resources