I want to create a search filter in Spring Boot controller, that takes 6 paramas and param value may be null then how to write a Data JPA Query? - spring

Like I have a page where data are showing like first name, middle name, last name, address, city, state, country, age, salary.
There are a filter implemented that have 4 fields like city, age, salary, state. now I have to made a controller in Spring boot that takes all 4 fields as input params and find data from database using Spring Data JPA.
But my problem is that I want to filter Data sometime by salary only, sometime by city, state, sometime with all 4 params.
So what will be controller code and JPA Repository query to do this filter process.
Please Help me
Thanks in Advance

test if your parameters are null :
"where (:name is null or name = :name) and (:city is null or city = :city)"

I would suggest to use JPA Specification instead,
to know more on specification code here is my thread on stackoverflow
If you want to stick with JPA then here's the query which can help you
where (:field1 is null or table.field1 = :field1)
and (:field2 is null or table.field2 = :field2)
...
...
...
Explanation: The above code will check if the parameter is null, then return true otherwise compare with the column.

You can modify Query with below clause Where you can write query in Repository and in
where clause you can add conditions. So this will work as expected.
#Query(value = "SELECT user from User user WHERE ((:name IS NULL) OR (user.name = :name)) AND ((:city IS NULL) OR (user.city = :city)))

Related

Null and Empty Check for a IN Clause parameter for Spring data jpa #query?

My Spring data JPA code to get the data from db based on some search criteria is not working. My DB is SQL Server 2012, same query seem to work with MYSQL DB.
Code Example :
#Query(value = "select * from entity e where e.emp_id=:#{#mySearchCriteria.empId} and ((:#{#mySearchCriteria.deptIds} is null or :#{#mySearchCriteria.deptIds} ='') or e.dept_id in (:#{#mySearchCriteria.deptIds})) ", nativeQuery = true)
public List<Entity> search(#Param("mySearchCriteria") MySearchCriteria mySearchCriteria);
if list mySearchCriteria.deptIds has more than one value- it's not working(it's actually translating it to wrong query. Any lead? Thanks in advance.
Note: data type for deptIds is List of Integer
Its complaining because values of {#mySearchCriteria.deptIds} is comma separated list e.g. 'Value1', 'Value2' so the query gets translated as ('Value1', 'Value2' is null) which causes this error.
Need to verify if list is empty or not and then change the query with IN clause and one without IN clause.
Surround the list by parentheses. This works for me.
(:#{#mySearchCriteria.deptIds}) is null

How to query upon the given parameters in Mongo repository

I have a mongo repostiory query as below, If we provide both name and price it gives the response. I want to get response if we only give name or price or both. how to make those parameters optional. if we provide both name and price i want to retrieve aggregated result unless i want to search just from the given field. Much appreciate you help.
List<Response> findByNameAndPrice(String name, int price)
Either you may need to implement custom JPA query or need to use QueryDSL in such scenarios.
1) Custom JPA Query like, you may need to change the query if you want to ad new optional parameters.
#Query(value = "{$or:[{name: ?0}, {?0: null}], $or:[{price: ?1}, {?1: null}]}")
List<Response> findByNameAndPrice(String name, Integer price)
2) QueryDSL Approach where you can add as many optional parameters, no need to modify your code. It will generate query automatically.
Refer this link for more : Spring Data MongoDB Repository - JPA Specifications like
I don't believe you'll be able to do that with the method name approach to query definition. From the documentation (reference):
There is a JIRA ticket regarding this which is still under investigation by the Spring team.
You can try this way
In repository
List<Response> findByName(String name)
List<Response> findByPrice(int price)
List<Response> findByNameAndPrice(String name, int price)
In your service file
public List<Response> findByNameAndPrice(String name, int price){
if(name == null ){
return repository.findByName(name);
}
if( price == 0){
return repository.findByPrice(price);
}
return repository.findByNameAndPrice(name, price);
}
Here I found a simple solution using mongodb regex,we can write a query like this,
#Query("{name : {$regex : ?0}, type : {$regex : ?1})List<String> findbyNameAndType(String name, String type)
The trick is if we want to query upon the given parameter, we should set other parameters some default values. As an example here thinks we only provide name. Then we set the type to select its all possible matches by setting its default param as ".*".
This regex pattern gives any string match.

Spring DATA JPA Between and IsBetween keywords

How to get Spring DATA JPA method (like findBy....) for the query below:
Select * from USER where '2016-02-15' between VALID_FROM and VALID_TO;
You should do it in this way
SELECT * FROM users u WHERE e.REFERENCE_FIELD BETWEEN startDate AND endDate
Your code is not very clear, and I dont know what is 2016-02-15, if is the name of your field or is a value, if is a value and you are using between, you must specify a range, and a field to be compared.
EDIT
If you want to use spring data jpa then do it like this
findReferenceFieldBetween(value1,value2);
check the ref. here
In Spring boot: 2.1.6, you can use like below:
List<OrderSummaryEntity> findByCreateTimestampBetween(String fromDate, String toDate);
Just to confirm how it is working internally, If you put spring.jpa.properties.hibernate.show_sql=true property in applocation.properties file, you may see the query like below. Internally nothing but BETWEEN query only.
Hibernate: select order0_.order_id as order_id1_8_,
order0_.create_timestamp as create_t2_8_,
order0_.inventory_at_order as inventor3_8_,
order0_.last_updated_by as last_upd4_8_,
order0_.location_id as location5_8_,
...
...
...
from order_summary order0_
where order0_.create_timestamp between ? and ?
If you want to include both boundary dates in result you can use below in Spring data jpa
#Query(value = "{'field' : {$gte : ?0, $lte : ?1}}", fields="{ 'field' : 1}")
List<DTO> findByFieldBetweenQuery(String first, String second);
Remove fields section if all fields are expected. Hope it helps someone.
SELECT * FROM users WHERE timeStamp BETWEEN 'fromDate' AND 'toDate';
You also can use the below JPA method to get data as the above query.
findByTimeStampGreaterThanEqualAndTimeStampLessThanEqual(fromDate,toDate);

SimpleJpaRepository Count Query

I've modified an existing RESTful/JDBC application i have to work with new features in Spring 4... specifically the JpaRepository. It will:
1) Retrieve a list of transactions for a specified date. This works fine
2) Retrieve a count of transactions by type for a specified date. This is not working as expected.
The queries are setup similarly, but the actual return types are very different.
I have POJOs for each query
My transactions JPA respository looks like:
public interface MyTransactionsRepository extends JpaRepository<MyTransactions, Long>
//My query works like a charm.
#Query( value = "SELECT * from ACTIVITI_TMP.BATCH_TABLE WHERE TO_CHAR(last_action, 'YYYY-MM-DD') = ?1", nativeQuery = true )
List< MyTransactions > findAllBy_ToChar_LastAction( String lastActionDateString );
This returns a list of MyTransactions objects as expected. Debugging, i see the returned object as ArrayList. Looking inside the elementData, I see that each object is, as expected, a MyTransactions object.
My second repository/query is where i'm having troubles.
public interface MyCountsRepository extends JpaRepository<MyCounts, Long>
#Query( value = "SELECT send_method, COUNT(*) AS counter FROM ACTIVITI_TMP.BATCH_TABLE WHERE TO_CHAR(last_action, 'YYYY-MM-DD') = ?1 GROUP BY send_method ORDER BY send_method", nativeQuery = true )
List<MyCounts> countBy_ToChar_LastAction( String lastActionDateString );
This DOES NOT return List as expected.
The object that holds the returned data was originally defined as List, but when I inspect this object in Eclipse, I see instead that it is holding an ArrayList. Drilling down to the elementData, each object is actually an Object[2]... NOT a MyCounts object.
I've modified the MyCountsRepository query as follows
ArrayList<Object[]> countBy_ToChar_LastAction( String lastActionDateString );
Then, inside my controller class, I create a MyCounts object for each element in List and then return List
This works, but... I don't understand why i have to go thru all this?
I can query a view as easily as a table.
Why doesn't JPA/Hibernate treat this as a simple 2 column table? send_method varchar(x) and count (int or long)
I know there are issues or nuances for how JPA treats queries with counts in them, but i've not seen anything like this referenced.
Many thanks for any help you can provide in clarifying this issue.
Anthony
That is the expected behaviour when you're doing a "group by". It will not map to a specific entity. Only way this might work is if you had a view in your database that summarized the data by send_method and you could map an entity to it.

way to fetch column from mysql in Hibernate, Spring mvc web application

//this query can be used to get list of PaymentAttribute for whicch payment details is NOT NULL
#Query("select p.paymentDetailName from paymentattribute p where p.entityId=?1 AND p.entityType=?2 and p.paymentDetailName is not null")
List<String> getNonNullPaymenyDetaisName(String entityId,String entityType);
My paymentattribute table contains some column like entityId, entityType,paymentDetailsName etc. I want to fetch just paymentdetail column as per query stated above . I am getting error. Is there is way in Spring-mvc web applications , via which i can fetch just the column rather than complete tuples. Above code is part of repository.

Resources