Select only the ids using Specification and Pageable - spring-boot

I am looking to select only the ids using this approach. Not sure how to get only the ids of matching employees.
Page<Employee> findAll(Specification<Employee> specification, Pageable pageable);

Related

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.

Get distinct column values with a Spring Data JpaRepository

I have this entity (annotations omitted for brevity):
#Entity
class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Lob
private String category;
#Lob
private String name;
#Lob
private String customer_number;
// more attributes omitted
}
I have to get a list of distinct category value for a particular uid
In my JpaRepository I have this:
#Query("SELECT DISTINCT product.category FROM Product as product WHERE product.customerNumber = :cn ORDER BY product.category")
Page<String> findDistinctCategoryByCustomerNumber(String cn,
Pageable pageable);
Without the #Query annotation, the ids are returned, instead of the category values. The generated SQL looks like this:
select distinct product0_.id as id1_0_, product0_.customer_number as customer2_0_, product0_.category as directory3_0_, product0_.name as name4_0_ from product product0_
where product0_.customer_number=?
order by product0_.id desc limit ?
But I need the distinct categories not the product entities. Short of another idea I added the #Query annotation above. But now I get this error:
Order by expression "PRODUCT0_.ID" must be in the result list in this case; SQL statement:
select distinct product0_.directory as col_0_0_ from product product0_ where product0_.customer_number=? order by product0_.directory, product0_.id desc limit ? [90068-197]
But I cannot add id to the result list because that would make the DISTINCT useless, as id is the primary key.
So I either need a suitable method name for automatic query generation or a way to stop JpaRepository from adding its order by clause to the end of my #Query.
The unwanted order by gets created since you are requesting a paged result. The notion of the n-th page only makes sense when your results are ordered and the ordering is coming from your Pageable method argument.
Remove the order by from your query and set the sort attribute of your Pageable to sort by category.

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();

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

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.

How to write the following MYSQL query in criteria query and hibernate query?

How can I write the criteria query and hibernate query for the following MySQL query
SELECT * FROM (SELECT * FROM outdatadetail where algorithmno="a0025_d2" and stringno=01 ORDER BY testid desc) sub_query GROUP BY subjectid;
Any suggestions.
String sql = "SELECT * FROM (SELECT * FROM outdatadetail where algorithmno='a0025_d2' and stringno=01 ORDER BY testid desc) sub_query GROUP BY subjectid;";
Session session = getSession().getSessionFactory().getCurrentSession();
Query query = session.createSQLQuery(sql);
As far as I understand after reading the documentation and looking at examples you don't need a sub-query to do what you are trying to.
Basically you write 1 query and set a projection to do the grouping.
Criteria query = currentSession.createCriteria(OutDataDetail.class);
query.setProjection(Projections.groupProperty("subjectid").as("subjectid"));
query.add(Restrictions.eq("algorithmno", "a0025_d2"));
query.add(Restrictions.eq("stringno", "01"));
query.addOrder(Order.desc("testid"));
return query.list();
The Criteria API by itself is fairly useful. But its real power comes when you start using classes like Projection, Subqueries, Order etc. in conjunction with your Criteria.
If you want to use the Criteria API with a sub-query you can do the following:
DetachedCriteria subquery = currentSession.createCriteria(OutDataDetail.class);
subquery.add(Restrictions.eq("algorithmno", "a0025_d2"));
subquery.add(Restrictions.eq("stringno", "01"));
subquery.addOrder(Order.desc("testid"));
Criteria query = currentSession.createCriteria(OutDataDetail.class);
query.setProjection(Projections.groupProperty("subjectid").as("subjectid"));
query.add(Subqueries.exists(subquery);
return query.list();
Both implementations should return a list of OutDataDetail objects (assuming that's the object you are working with).
DISCLAIMER: I have not tried any of this. It may be that this will not work for you. This answer is written based on my knowledge of working with the Criteria API and its associated classes in the past, and the Hibernate 4.1 Manual. You can see the manual section on Projections and grouping here.

Resources