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);
}
Другие вопросы по тегам