Equivalent of criteria in spring-data-jpa
Asked Answered
T

3

9

I was using hibernate but i heard that spring-data-jpa is the best so i try it and i'm satisfy with it until i face this issue.

I have a search form in my jsp with many criteria and the user can choose whatever he want.

So what is the equivalent of this request in spring-data-jpa

if(startDate!=null){
    criteria.add(Expression.ge("date",startDate));
}
if(endDate!=null){
    criteria.add(Expression.le("date",endDate));
}
if(volume!=null){
    criteria.add(Expression.ge("volume",volume));
}
if ....
Timework answered 29/6, 2014 at 23:16 Comment(0)
P
20

It's QueryDSL. Here's a blog post on how to use it with Spring Data.

Pneumo answered 29/6, 2014 at 23:42 Comment(1)
I think you should have added an excerpt of the blog here, just in case the link stop working. Great info, by the way.Frankie
P
6

the Equivalent in Spring Jpa Data is Specification, and you can use the repository SpecificationExecutor<T> and Jpa MetaModel to create your Jpa Criteria.

You can find an introduction about Jpa JpaSpecificationExecutor

A quick example :

  1. Entity

@Entity

public class ClassRoom {
    // id and other properties

    @ManyToOne
    private School school;

    private Date creationDate;

    private String reference;
    // Getters and setters
}

2.Repository:

    @Repository
public interface ClassRoomRepository extends JpaSpecificationExecutor<ClassRoom>{
}

2.Service interface:

public interface ClassRoomService {

List<ClassRoom> list(String reference, String schoolName,
        Date creationDate)
}

3.Service Implementaion:

import static yourpackage.ClassRoomSpecifications.*;
import static org.springframework.data.jpa.domain.Specifications.*;
@Service
public class ClassRoomServiceImpl implements ClassRoomService {

    @Resource
    private ClassRoomRepository repository;


    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public List<ClassRoom> list(String reference, String schoolName,
            Date creationDate) {

        Specifications<ClassRoom> spec = null;
        Specifications<ClassRoom> tempo = null;

        spec = where(findPerSchool(schoolName));

        if (reference != null) {
            tempo = where(findPerReference(reference));
        }

        if (creationDate!=null) {
            tempo = tempo == null ? where(findPerCreationDate(creationDate):tempo.and(findPerCreationDate(creationDate));
        }
        spec = tempo == null ? spec : spec.and(tempo);
        return repository.findAll(spec);
    }
}
Proper answered 29/6, 2014 at 23:47 Comment(2)
Specification are hard to code and very verbose as the say in the link you give me.Timework
Checkout the example at petrikainulainen.net/programming/spring-framework/…Nonchalant
L
6

With Spring data you just need to use repositories.

   And  findByLastnameAndFirstname  … where x.lastname = ?1 and x.firstname = ?2
   Or   findByLastnameOrFirstname   … where x.lastname = ?1 or x.firstname = ?2
   Between  findByStartDateBetween  … where x.startDate between 1? and ?2
   LessThan findByAgeLessThan   … where x.age < ?1
   GreaterThan  findByAgeGreaterThan    … where x.age > ?1
   IsNull   findByAgeIsNull … where x.age is null
   IsNotNull,NotNull    findByAge(Is)NotNull    … where x.age not null
   Like findByFirstnameLike … where x.firstname like ?1
   NotLike  findByFirstnameNotLike  … where x.firstname not like ?1
   OrderBy  findByAgeOrderByLastnameDesc    … where x.age > ?1 order by x.lastname desc
   Not  findByLastnameNot   … where x.lastname <> ?1
Lardner answered 30/6, 2014 at 8:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.