How to run between and like clause while using Pagination and Sorting With Spring Data JPA - spring

I have to execute a query which is
SELECT * FROM transaction WHERE account LIKE '%deepak%' and date_created BETWEEN 'Thu Jan 01 00:00:00 IST 2015' AND 'Wed Dec 16 00:00:00 IST 2015' ORDER BY date_created ASC OFFSET 5 LIMIT 10;
currently I am able to perform 4 functions using JPA which are:-
Set Offset
Set Page Size
Set Direction
Set Sort by column name
using the following code:-
PageRequest request = new PageRequest(1, 10, Sort.Direction.ASC, date_created );
return transactionRepository.findAll(request);
But how to perform remaining functions i.e. 'between' clause and 'like' clause using Pagination and Sorting With Spring Data JPA
Other suggested methods are also welcome.

Take a look at Spring jpa data reference documentation ,
Add this to your repository that extends PagingAndSortingRepository<..,..>
findByAccountLikeAndDateCreatedBetween(String account,Date start,Date end,Pageable pageable)

If you're familiar with JPQL you can always annotate a query with #Query inside your repository. ie:
#Query("select t from transaction t where t.name like ?1")
List<Transaction> getTransactions(String name, Pageable pageable)
where ?1 is the first parameter you passed, in this case name. Note that Pageable must always be the last parameter. This way you can name your query whatever you want.
See more info here.

Related

How to use the query dynamically in spring boot repository using #Query?

How to use the below query dynamically in spring boot repository using
#Query(value="SELECT * FROM do_not_track WHERE (user_id=7 ) AND ('2022-06-25' BETWEEN from_date AND to_date) OR ('2022-06-30' BETWEEN from_date AND to_date)",nativeQuery = true)
SELECT * FROM do_not_track WHERE (user_id=7 ) AND ('2022-06-25' BETWEEN from_date AND to_date) OR ('2022-06-30' BETWEEN from_date AND to_date);
How to write the above query using jpa method?
I have used as given below but it's not working.
findByUser_userIdAndFromDateBetweenOrToDateBetween(Long userId, Date fromDate, Date toDate,
Date fromDate2, Date toDate2)
The #Query annotation allows you to 'bind' a SQL statement to a method and also allows you to include placeholders in your query.
To create such placeholder values, at first you want to annotate the arguments you pass to the repository method with #Param("someName"), where 'someName' is the name of the placeholder that will later be used in the query.
Inside the query you can reference to a specific parameter using :someName.
In the end your repository method and query could look something like this:
#Query("SELECT * FROM do_not_track WHERE (user_id = :userId) AND (date
BETWEEN :fromDate AND :toDate) AND (date BETWEEN :fromDate2 AND :toDate2)")
findByUser(#Param("userId") Long userId,
#Param("fromDate") Date fromDate,
#Param("toDate") Date toDate,
#Param("fromDate2") Date fromDate2,
#Param("toDate2") Date toDate2)

How to create a subquery that uses listagg in JPA repository?

Using JPA specification classes or predicate builder. How can I convert this WHERE clause?
I am using an oracle db.
WHERE (SELECT listagg(reject_cd,':') within group (order by order_no) as rejectList
FROM REJECT_TABLE WHERE ID = transactio0_ id group by id) like '%06%'
The LISTAGG function is highly specific to Oracle, and is not supported by JPQL. However, you can still use a native query here, e.g.
#Query(
value = "SELECT ... WHERE (SELECT LISTAGG(reject_cd,':') WITHIN GROUP (ORDER BY order_no) AS rejectList FROM REJECT_TABLE WHERE ID = transactio0_ id GROUP BY id) LIKE '%06%'"
nativeQuery = true)
Collection<SomeEntity> findAllEntitiesNative();
Another option here might be to find a way to avoid needing to use LISTAGG. But, we would need to see the full query along with sample data to better understand your requirement.

Creating Query using Date parameters with Spring Jpa Repository

I want to execute a query via JpaRepository that uses Date objects as parameters (java.util.Date). However, each time the method from the repository is called, it returns a null value. When I pass Integer values and work with id instead of Date I don't get any errors and the query is successfully executed.
This is my query:
#Query(value="SELECT sum(o.price) FROM Order o WHERE o.dateCreatedAt BETWEEN ?1 AND ?2")
Double getTotalMoneyEarned(Date beginDate, Date endDate)
I don't know if I'm missing something. In my Order model object, dateCreatedAt is a column of type Date.
Add this line at imports block
import org.springframework.data.repository.query.Param;
This should work :
#Query(value="SELECT sum(o.price) FROM Order o WHERE o.dateCreatedAt BETWEEN :beginDate AND :endDate")
Double getTotalMoneyEarned(#Param("beginDate") Date beginDate, #Param("endDate") Date endDate)

Order By Date Desc Limit in Spring Data JPA

I am trying to limit the query results by using Limit query. With out limit the query is working as expected.
#Query("SELECT a FROM DrmAdpodTimeSlot a where a.startTime > :startTime order by a.startTime desc")
public List<DrmAdpodTimeSlot> findByStartTime(#Param("startTime") Timestamp startTime);
But When I try to limit the records by using limit (no.of records), as follows,
#Query("SELECT a FROM DrmAdpodTimeSlot a where a.startTime > :startTime order by a.startTime desc limit 2")
public List<DrmAdpodTimeSlot> findByStartTime(#Param("startTime") Timestamp startTime);
From the above query I am getting the following error,
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: limit near line 1, column 110 [SELECT a FROM com.dooreme.domain.DrmAd
podTimeSlot a where a.startTime > :startTime order by a.startTime desc limit 2]
How can I use the order by limit query in spring data jpa query?
You can not add pagination support to the Query annotation. There is no need for adding sorting and pagination functionality into HQL/JPQL when you're using Spring Data JPA. Use Pageable as the second argument instead, like following:
#Query("SELECT a FROM DrmAdpodTimeSlot a where a.startTime > :startTime")
public List<DrmAdpodTimeSlot> findByStartTime(#Param("startTime") Timestamp startTime, Pageable pageable);
Pageable encasulates the sort and paging functionality, as spring data jpa doc says:
Add Pageable instance to the query method to dynamically add paging to
your statically defined query. A Page knows about the total number of
elements and pages available. It does so by the infrastructure
triggering a count query to calculate the overall number. As this
might be expensive depending on the store used, Slice can be used as
return instead. A Slice only knows about whether there’s a next Slice
available which might be just sufficient when walking thought a larger
result set.
So, you can use either:
#Query("SELECT a FROM DrmAdpodTimeSlot a where a.startTime > :startTime")
public Page<DrmAdpodTimeSlot> findByStartTime(#Param("startTime") Timestamp startTime, Pageable pageable);
Or:
#Query("SELECT a FROM DrmAdpodTimeSlot a where a.startTime > :startTime")
public Slice<DrmAdpodTimeSlot> findByStartTime(#Param("startTime") Timestamp startTime, Pageable pageable);
Also:
Sorting options are handled through the Pageable instance too.
None of the other answers really answered your question of how to limit to the top 2 start times descending order. I'm not sure how to do it using jpql, but using jpa query, you can do findTop2ByOrderByStartTimeDesc
Also, see this post
How would I write SELECT TOP 25 sql query in Spring data repository
You can use in Repository your query:
#Query("SELECT a FROM DrmAdpodTimeSlot a WHERE a.startTime>'?1' ORDER BY a.startTime DESC")
List<DrmAdpodTimeSlot> findByStartTime(String startTime, Pageable pageable);
}
And in the Service, use a PageRequest, returning a Page object:
Page<DrmAdpodTimeSlot> top2 = arcustRepository.findByStartTime(arcustno, PageRequest.of(0, 2));
List<DrmAdpodTimeSlot> top2StartTimes = top2.getContent();

getting Hibernate error when using DBMS_RANDOM.value

I would like to achieve same result as the below query using Hibernate SQL, i.e., I would like to get two random records from the table whose ID is not equal to 300. I am using Hibernate 4.1 and Oracle 11g. I ran the below query on Toad and it gives 2 random records. But, when I try to run the HQL, there is error to do with the usage of "DBMS_RANDOM.value".
SELECT * FROM
( SELECT *
FROM table
where ID != '300'
AND q_ID=125
ORDER BY DBMS_RANDOM.value
)WHERE rownum < 3
;
I tried creating criteria and query, but both give Hibernate errors:
Hibernate Message: Invalid path: 'DBMS_RANDOM.RANDOM' [from com.model.table tab where tab.ID != '33092' ORDER BY DBMS_RANDOM.RANDOM]
and my actual hibernate query is:
Query query = session.createQuery("from table tab where tab.ID != '" +agrmId+"' ORDER BY DBMS_RANDOM.RANDOM").setMaxResults(2);
I also tried ORDER BY rand() and that gives an Oracle error.
Thank you for any help.
I solved the problem by adding a property tag in the hibernate mapping file:
<property name="constVal" formula="DBMS_RANDOM.RANDOM" type="long"/>
and then, in the POJO class, I added a variable with getter and setter methods:
private long constVal;
then, in the DAO class, I added the following query:
Criteria crit1 = session.createCriteria(table.class);
crit1.add(Restrictions.ne("id",300));
crit1.add(Restrictions.eq("quesId",125));
crit1.addOrder(Order.asc("constVal"));
crit1.setMaxResults(2);
and that solved it.

Resources