JPA specification - query the top result after ordering by date
Asked Answered
B

0

0

It is my first experience with JPA-Specification.

I tried to implement a sample project with same requirements of my real project.

Here Are my Entities: Movie and Actor

@Entity
@Table(name = "MOVIE")
public class Movie {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "TITLE")
    @Basic
    private String title;

    @Column(name = "GENRE")
    @Basic
    private String genre;

    @Column(name = "RATING")
    @Basic
    private double rating;

    @Column(name = "WATCH_TIME")
    @Basic
    private double watchTime;

    @Column(name = "RELEASE_YEAR")
    @Basic
    private int releaseYear;
}

@Entity
@Table(name = "ACTOR")
public class Actor {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME")
    @Basic
    private String name;

    @Column(name = "FAMILY")
    @Basic
    private String family;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "MOVIE_ID")
    @Fetch(FetchMode.JOIN)
    private Movie movie;

    @Basic
    @Column(name = "DATE_TIME")
    private Timestamp dateTime;
}

Also I have their repositories which extends JpaSpecificationExecutor<> And my ActorSpecification is as below:

public class ActorSpecification implements Specification<Actor> {

    private List<SearchCriteria> list;

    public ActorSpecification() {
        this.list = new ArrayList<>();
    }

    public void add(SearchCriteria criteria) {
        list.add(criteria);
    }

    @Override
    public Predicate toPredicate(Root<Actor> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
        //create a new predicate list
        List<Predicate> predicates = new ArrayList<>();

        //add criteria to predicates
        for (SearchCriteria criteria : list) {
            Join<Actor, Movie> join = root.join(Actor_.MOVIE);
            query.orderBy(builder.desc(root.get(Actor_.DATE_TIME)));
            if (criteria.getOperation().equals(SearchOperation.IN_MOVIE_ID)) {
                predicates.add(join.get(Movie_.ID).in(Arrays.asList(72, 74, 76, 78)));
            } else if (criteria.getOperation().equals(SearchOperation.IN_MOVIE_WATCHTIME)) { 
                predicates.add(join.get(Movie_.WATCH_TIME).in(Arrays.asList(135, 126)));
            }
        }
        return builder.and(predicates.toArray(new Predicate[0]));
    }
}

And this is the way I use to filter my data and fetch data:

ActorSpecification actorsInMovieIdList = new ActorSpecification();
actorsInMovieIdList.add(new SearchCriteria("MovieId", "72, 74, 76, 78", SearchOperation.IN_MOVIE_ID));
List<Actor> actorsMovieIdList = actorRepository.findAll(actorsInMovieIdList);

ActorSpecification actorsInMovieWatchTime = new ActorSpecification();
actorsInMovieWatchTime.add(new SearchCriteria("MovieWatchTime", "135 ,126", SearchOperation.IN_MOVIE_WATCHTIME));
List<Actor> actorsMoviesWatchTime = actorRepository.findAll(actorsInMovieIdList.and(actorsInMovieWatchTime));

AND NOW MY REQUIREMENT:

As we have many Actor in each Movie, so the join result will return list of Actors of each movie that matches our conditions for filtering movies.

Now I need to just return the Actor of that movie which has the greatest DATE_TIME ,is there any way for doing it with JpaSpecification or I need to implement a filter method myself.

If I want to tell you about my real project in order to make it more clear. I have STOCK and DAILY_PRICE Tables and of course any Stock has many Daily_Price, So I just want to fetch the last Daily_price joining my Stock record.

Can anyone help me in this issue??

Any help will be appreciated!!

Bradway answered 19/12, 2021 at 7:58 Comment(4)
Why don't you write a simple SQL query? Do you need an entity as a result?Asperse
@SimonMartinelli , I have many filtering options in client-side, so i searched a little and find out that with using JPA-Specification I can handle it easily ant it can help me to have dynamic queries!!Bradway
I understand. You could use docs.spring.io/spring-data/jpa/docs/current/reference/html/…Asperse
@SimonMartinelli , I will check it out and try to implement it, thanks for your nice and quick feedback Mr.Martinelli.Bradway

© 2022 - 2024 — McMap. All rights reserved.