简体   繁体   中英

JPQL ManyToMany query with count field

I have a Many to Many relationship between two entities, User and Movies in a spring boot application with spring security.

I want to made a REST API that finds all the movies and includes a new field that shows if the logged user did watched the movie or no.

I can't find an easy way to do it, I only found a solution creating a new DTO object in the query. I show my code next.

The entities are the following:

Movies:

@Entity
@Table(name = "movies")
public class Movies implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;

@NotNull
@Size(max = 100)
@Column(name = "name", length = 100, nullable = false)
private String name;

@Column(name = "jhi_year")
private Long year;

@Size(max = 100)
@Column(name = "category", length = 100)
private String category;

@ManyToMany(mappedBy = "movies")
@JsonIgnore
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<User> users = new HashSet<>();

User:

@Entity
@Table(name = "user")
public class User implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;

@Size(max = 50)
@Column(name = "login", length = 50)
private String login;

@Size(max = 250)
@Column(name = "bio", length = 250)
private String bio;

@ManyToMany
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JoinTable(name = "user_movies",
           joinColumns = @JoinColumn(name="user_id", referencedColumnName="id"),
           inverseJoinColumns = @JoinColumn(name="movies_id", referencedColumnName="id"))

What I did is a @Repository class with a JPQL @query like this one:

@Query("select new com.test.service.dto.MoviesDTO(movies.id, movies.name, movies.year, movies.category, " +
" count(users.id)) from Movies movies left join movies.users users on users.login = ?#{principal.username} group by movies.id ")
Page<MoviesDTO> findAll(Pageable pageable);

This works fine, but is there a simpler way to do the this? It would be perfect to find a method to do this adding a new object in the entity class, avoiding making a new DTO object in the query.

I know that it is almost same issue than this one posted by myself some time ago, which remains a mystery to me.

Many, many thanks!

Thanks to jasarez for the answer. I changed the DOT for a projection and it works like a charm!

The repository:

@Query("select movies.id as id, movies.name as name, movies.year as year, movies.category as category, count(users.id) as moviesCount " +
    "from Movies movies left join movies.users users on users.login = ?#{principal.username} group by movies.id")
     Page<MovieWithUserData> findAllWithUserData(Pageable pageable);

and the projection:

public interface MovieWithUserData {

    Long getId();

    String getName();

    String getCategory();

    Integer getYear();

    Long getMoviesCount();

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM