Как получить сумму @ElementCollection с Hibernate? - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть таблица сущностей со следующим:

@ Entity общедоступный пост класса {

@Id
@GeneratedValue
private Long id;

@NotBlank
@Size(min = 1, max = 2014)
private String text;

@NotNull
@Temporal(TemporalType.TIMESTAMP)
private Date created;

@NotNull
@ManyToOne
private User author;

@ElementCollection(fetch = FetchType.EAGER)
private Set<String> votesFor;

@ElementCollection(fetch = FetchType.EAGER)
private Set<String> againstFor;

@OneToMany(mappedBy = "post", cascade = CascadeType.REMOVE)
private List<Comment> comments;

public Post() {
    votesFor = new HashSet<>();
    againstFor = new HashSet<>();
    comments = new ArrayList<>();
}

Я хочу сделать TypedQuery, где я смогу получить пост с наибольшим количеством голосов. Я добавляю голосование в @ElementCollection, используя следующий код ниже.

Как мне суммировать @ElementCollection и затем возвращать список с сообщениями с наибольшим количеством голосовДля начала и окончания с меньшим количеством голосовДля?

public void votesFor(String userId, long postId) {

    Post post = em.find(Post.class, postId);
    if(post == null) {
        throw new IllegalArgumentException("Post not exists: " + postId);
    }

    if(post.getVotesFor().contains(userId)) {
        throw new IllegalArgumentException("User " + userId + " have already voted");
    }

    post.getVotesFor().add(userId);
    post.getAgainstFor().remove(userId);
}

1 Ответ

0 голосов
/ 27 апреля 2018

В JPQL вы можете использовать функцию SIZE для получения размера ElementCollection.

Я не совсем понимаю, как именно вы хотите запрашивать ваши данные, поэтому я приведу вам два разных примера возможного использования в вашей примерной структуре сущностей.

Получите N самых популярных сообщений

Чтобы получить N самых популярных постов, нам нужно

  1. Сортируйте наши сообщения по размеру голосов за коллекцию.
  2. Ограничить по N.

Просто так:

select p from Post p order by SIZE(p.votesFor) desc limit :n

где : n - некоторый параметр в вашем запросе

Получать сообщения не менее чем с N голосами за

Второй возможный способ - запрашивать сообщения, по крайней мере, с некоторым количеством голосов «За». Для этого вам нужно будет использовать выражение WHERE, вот так:

select p from Post p where SIZE(p.votesFor) >= :n

где: n - количество минимальных голосов, которые вы ищете.

Подробнее о специальных операторах, таких как SIZE ЗДЕСЬ

...