How to use in clause in spring boot using CriteriaBuilder - spring

When i using CriteriaBuilder in clause query but this query not working.
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery userQuery = criteriaBuilder.createQuery(TTS_utilsEntity.class);
Root userRoot = userQuery.from(TTS_utilsEntity.class);
userQuery.select(userRoot);
userQuery.where(userRoot.get(TTS_utilsEntity_.id.getName()).in(ids));

Related

Subquery using CriteriaBuilder in Predicate overridden method Spring boot

I was trying to create one subquery in Springboot project, where I have created one custom class which is extending interface implements Specification<T> which gives overridden method #Override public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb).
Below is my SQL query which I would like to make it using CriteriaBuilder.
Select * from student_projects WHERE project_id IN (Select project_id
from student_courses where course_type = 3)
Below is the code snippet of the custom model class of implements Specification<T> which I have created,
#Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
query.distinct(true);
return root.join("student_courses", JoinType.LEFT).get("project_id").in("3");
}
Kindly suggest me if more information is needed. Thank you all

CriteriaBuilder OffsetDateTime Comparison

I use Springboot, and I'd like to implement a "search" API for an entity that has an "OffsetDateTime" attribute.
The attribute is of type "OffsetDateTime" in my Hibernate entity :
#Column(name = "creation_date")
private OffsetDateTime creationDate;
The attribute that I get from the API is of type "OffsetDateTime" too.
I use the Springboot Specification, with the OffsetDateTime value as criteria.getValue() :
#Override
public Predicate toPredicate(Root<Job> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) {
return builder.equal(root.get("creationDate"), criteria.getValue());
}
But the above code doesn't return me the entity with the specified date
However, the following code does :
#Override
public Predicate toPredicate(Root<Job> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) {
Predicate predicate = builder.between(root.<OffsetDateTime>get("creationDate"),
((OffsetDateTime) criteria.getValue()).minus(1, ChronoUnit.MILLIS),
((OffsetDateTime) criteria.getValue()));
}
In my DB I have "2020-03-12 17:25:11.047", and the value I pass to the API is "2020-03-12T17:25:11.047+01:00". I'm in France, so I have a 1 hour offset, and the time is saved as a local time in the db, but that doesn't seem to be the problem as the second solution does return the entity I want.
Do you know why the first solution doesn't return me the entity, and how I could get the entity without having to set a 1 millisecond interval ?

Select latest record for each id spring jpa

I have an entity like this:
#Entity
class Point{
#EmbeddedId
private PointIdentity pointIdentity;
private float latitude;
private float longitude;
#Embeddable
public static class PointIdentity implements Serializable {
private Long id;
private ZonedDateTime timestamp;
}
}
There is EmbeddedId, so in "id" column can be multiple records with the same ids.
And I need to get latest record for each id, using CriteriaQuery and JPA specifications I think, but don't know how.
In SQL, this would be something like this:
SELECT id, MAX(timestamp)
FROM geodata
GROUP BY id
Is there any way to do it?
Any help, thanks.
You can easily write a JPQL query:
TypedQuery<Object[]> query = entityManager.createQuery(
"select p.pointIdentity.id, max(p.pointIdentity.timestamp) from Point p group by p.pointIdentity.id",
Object[].class);
List<Object[]> results = query.getResultList();
which translates to:
select
point0_.id as col_0_0_,
max(point0_.timestamp) as col_1_0_
from
point point0_
group by
point0_.id
Alternatively, you can use criteria query:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Object[]> query = criteriaBuilder.createQuery(Object[].class);
Root<Point> point = query.from(Point.class);
query.groupBy(point.get("pointIdentity").get("id"));
query.multiselect(
point.get("pointIdentity").get("id"),
criteriaBuilder.max(point.get("pointIdentity").get("timestamp"))
);
TypedQuery<Object[]> typedQuery = entityManager.createQuery(query);
List<Object[]> results = typedQuery.getResultList();
which produces identical SQL.

How to perform sort with multiple fields on custom query JPQL with Spring Pageable

I am using Spring's Pageable to sort the columns.
A working example is below:
Pageable pageable = PageRequest.of(0, countOfBookData.intValue(), getSortingDirection(sortingOrder), sortingField);
Where sortingOrder = ASC and sortingField = bookName
Here is the query
#Query("SELECT bs FROM BookSummary bs WHERE bs.bookId=:bookId")
List<Books> getBookDetails(#Param("bookId") Integer bookId, Pageable pageable)
But I got stuck when I need to perform this sort on Custom my custom query.
So I have no idea how I can perform the sorting using Pageable for below custom query:
Public List<Tuple> getBookDetails(Integer bookId){
String query = "SELECT book.bookCd as bookCode, "
+ "book.name as bookName"
+ "FROM Book book WHERE book.bookId=:bookId";
return entityManager.createQuery(query , Tuple.class).setParameter("bookId", bookId).getResultList();
}
The same as in the first custom query but using the Projection, for example:
public interface BookDetails {
String getBookCode();
String getBookName();
}
#Query("select b.bookCd as bookCode, b.name as bookName from Book b where b.bookId = ?1")
List<BookDetails> getBookDetails(Integer bookId, Pageable pageable);
Note that projection method names must match with corresponding aliases in the query.
Or without the query:
List<BookDetails> getAllById(Integer bookId, Pageable pageable);

Select Count using Criteria builder in a OneToMany Relationship

I'm building a Spring web app and i'm new to JPA and I need to get the number of users in a specific group in my database.
Here is the sample code :
public long countAllUsersByGroup(int groupId) {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Long> cq = qb.createQuery(Long.class);
cq.select(qb.count(cq.from(User.class)));
//cq.where(qb.equal(cq.from(User.class).get("userGroup").get("id"),groupId));
return em.createQuery(cq).getSingleResult();
}
This code is working, it allows me to retrieve the number of users I have in the database which is pretty trivial.
This is my user Model :
public class User {
private String userFirstName;
private String userLastName;
/* some stuff */
#ManyToOne
private Group userGroup;
}
And my group model has an int attribute annotated with #Id and named id. How Can I get the number of user by group id in this case ?
P.S : I've tried and commented my try in the code above, unfortunately it was a failure ...
You can try the code below
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> q = cb.createQuery(Long.class);
ParameterExpression<Integer> p = cb.parameter(Integer.class);
q.select(q.count(q.from(User.class))).where(cb.gt(c.get("userGroup"), someId));

Resources