HQL like operator for case insensitive search - spring

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

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.

Criteria Query to retrieve data from DB using specification and predicate

I have two tables (user, vehicles) and i want to write criteria query to retrieve data from db using criteria query specification and predicate to both Join Tables.
select ur.id, count (ur.vehicle_FK) from user so
inner join VEHICLE vhe on vhe.user_id_FK = ur."ID"
group by ur.id, vhe.user_id_FK;
How to implement it using criteria query ??
Try something like this :
Criteria criteria = session.createCriteria(User.class, "user");
criteria.createAlias("user.vehicle_FK", "vehicle", Criteria.INNER_JOIN);
criteria.setProjection(
Projections.projectionList().add(Projections.groupProperty("user.id"))
.add(Projections.countDistinct("user.id")));
Parameters in Criteria Queries
The following query string represents a JPQL query with a parameter:
SELECT c FROM Country c WHERE c.population > :p
An equivalent query can be built using the JPA criteria API as follows:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Country> q = cb.createQuery(Country.class);
Root<Country> c = q.from(Country.class);
ParameterExpression<Integer> p = cb.parameter(Integer.class);
q.select(c).where(cb.gt(c.get("population"), p));
The ParameterExpression instance, p, is created to represent the query parameter. The where method sets the WHERE clause. As shown above, The CriteriaQuery interface supports method chaining. See the links in the next sections of this page for detailed explanations on how to set criteria query clauses and build criteria expressions.
You can find more examples here
https://www.objectdb.com/java/jpa/query/criteria
Remember to post an answer when you find one! :)

How to get total count in hibernate full text search?

I am trying using hibernate full text by following this link:
hibernate/search/4.1/reference/en-US/html/getting-started
Basically, it works, but I want to know how to get total count while I execute a full text query,then I can tell user how many results and how many pages would be in such a query.
Here is the code(Using JPA to create and execute a search):
EntityManager em = entityManagerFactory.createEntityManager();
FullTextEntityManager fullTextEntityManager =
org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
em.getTransaction().begin();
// create native Lucene query unsing the query DSL
// alternatively you can write the Lucene query using the Lucene query parser
// or the Lucene programmatic API. The Hibernate Search DSL is recommended though
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder().forEntity( Book.class ).get();
org.apache.lucene.search.Query query = qb
.keyword()
.onFields("title", "subtitle", "authors.name", "publicationDate")
.matching("Java rocks!")
.createQuery();
// wrap Lucene query in a javax.persistence.Query
javax.persistence.Query persistenceQuery =
fullTextEntityManager.createFullTextQuery(query, Book.class);
persistenceQuery.setFirstResult((page - 1) * PAGECOUNT);
persistenceQuery.setMaxResults(PAGECOUNT);
// execute search
List result = persistenceQuery.getResultList();
em.getTransaction().commit();
em.close();
In SQL, I can use select count(*) from something, but here I don't know how to do that. I want to just fetch one page of data every time and use another API to get total count.
query.getResultSize(); //return the total number of matching ... regardless of pagination
I'm not sure if there is such a way when using the Hibernate full text search.
If you want to know the total number of results then you have to perform the full query. After you have the full count you can set your page limiter and perform it again.
javax.persistence.Query persistenceQuery =
fullTextEntityManager.createFullTextQuery(query, Book.class);
int count = persistenceQuery.getResultList().size();
persistenceQuery =
fullTextEntityManager.createFullTextQuery(query, Book.class);
persistenceQuery.setFirstResult((page - 1) * PAGECOUNT);
persistenceQuery.setMaxResults(PAGECOUNT);
List result = persistenceQuery.getResultList();
For Hibernate(maybe for JPA)
public interface FullTextQuery extends Query
in other words, you need use
org.hibernate.search.FullTextQuery query = fullTextEntityManager.createFullTextQuery(query, Book.class);
instead of
org.hibernate.Query query = fullTextEntityManager.createFullTextQuery(query, Book.class);
and method getResultSize() will be available
When using directly Lucene/Solr, I usually use a hack* by searching for *:*, setting it to return the least possible results BUT that does return the total result count for "everything", and I proceed to extract it. Basically it's the same as the SELECT count(*) FROM whatever :P
*I say hack because I'm not sure if it's supposed to be that way or not, but it works for me...

Create a linq subquery returns error "Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator"

I have created a linq query that returns my required data, I now have a new requirement and need to add an extra field into the returned results. My entity contains an ID field that I am trying to map against another table without to much luck.
This is what I have so far.
Dictionary<int, string> itemDescriptions = new Dictionary<int, string>();
foreach (var item in ItemDetails)
{
itemDescriptions.Add(item.ItemID, item.ItemDescription);
}
DB.TestDatabase db = new DB.TestDatabase(Common.GetOSConnectionString());
List<Transaction> transactionDetails = (from t db.Transactions
where t.CardID == CardID.ToString()
select new Transaction
{
ItemTypeID= t.ItemTypeID,
TransactionAmount = t.TransactionAmount,
ItemDescription = itemDescriptions.Select(r=>r.Key==itemTypeID).ToString()
}).ToList();
What I am trying to do is key the value from the dictonary where the key = itemTypeID
I am getting this error.
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
What do I need to modify?
This is a duplicate of this question. The problem you're having is because you're trying to match an in-memory collection (itemDescriptions) with a DB table. Because of the way LINQ2SQL works it's trying to do this in the DB which is not possible.
There are essentially three options (unless I'm missing something)
1) refactor your query so you pass a simple primitive object to the query that can be passed accross to the DB (only good if itemDescriptions is a small set)
2) In your query use:
from t db.Transactions.ToList()
...
3) Get back the objects you need as you're doing, then populate ItemDescription in a second step.
Bear in mind that the second option will force LINQ to evaluate the query and return all transactions to your code that will then be operated on in memory. If the transaction table is large this will not be quick!

Resources