Hibernate - Встраивание агрегированной колонки в Entity
У меня проблема с настройками отображения аннотаций в спящем режиме. Представьте себе следующие два класса на платформе социальных сетей:
@Entity
class User {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany
private List<Post> posts; //lazy-loaded, because of big amounts
}
@Entity
class Post {
@Id
@GeneratedValue
private Long id;
//large amounts of data
private String text;
private Date date;
@ManyToOne
private User author;
}
Самая интересная информация в моем случае использования - это самая последняя запись, которую написал каждый пользователь. Я мог бы прочитать в Users и добавить пользовательский запрос, например, так:
SELECT mx.userId,text,mx.date FROM
(SELECT user.id AS userId,max(date) AS date
FROM post,user
WHERE post.author=user.id
GROUP BY user.id) mx,
Post p
WHERE p.author=mx.userId
AND p.date=mx.date;
Мой вопрос сейчас заключается в том, как я могу встроить последнее сообщение в его сопоставленного пользователя в виде поля.
Новый пользователь:
@Entity
class User {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany
private List<Post> posts;
//@Filter?
//@Query?
private Post latestPost;
}
Я не хочу объединять данные из моего последнего пост-агрегирования с моими пользовательскими объектами в Java. Это не на вкус правильно. Поэтому я ищу решение встроить это агрегированное поле в мою базовую сущность. Где можно указать пользовательский поиск пользовательских объектов в Hibernate для добавления такого агрегированного поля?
Вы можете представить себе аналогичную проблему, например, со встроенными суммами торговых сумм определенного клиента в CRM.
Я надеюсь, я мог бы проиллюстрировать свои мысли и проблемы. Заранее спасибо!
1 ответ
Сама JPA не предоставляет такой аннотации.
Но специфичный Hibernate Where
аннотация делает именно то, что вы хотите. Единственный недостаток - для работы нужен сбор, который можно обойти с помощью конкретного геттера:
@OneToMany(mappedBy = "author")
@Where("date = (SELECT max(post.date) FROM post GROUP BY post.author)")
private Collection<Post> latestPost;
public Post getLatestPost() {
return latestPost.isEmpty() ? null : latestPost.iterator().next(0);
}