Hibernate - 在实体中嵌入聚合列

时间:2015-11-13 08:18:47

标签: java sql hibernate annotations mappings

我遇到了有关hibernate注释映射配置的问题。想象一下社交媒体平台上的以下两个类:

@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;
}

我的用例中最有趣的信息是每个用户写的最新帖子。我可以在用户中阅读并附加一个自定义查询,如下所示:

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;
}

我不想加入我的最新帖子&#39; -aggregation中的数据和我的用户对象Java。这味道不对。所以我正在寻找一种解决方案,将这个聚合字段嵌入到我的基础实体中。在哪里可以在Hibernate中指定自定义检索用户对象以添加这样的聚合字段?

你可以想象一个类似的问题,例如嵌入式CRM中特定客户的交易金额。

我希望,我可以说明我的想法和问题。提前谢谢!

1 个答案:

答案 0 :(得分:0)

JPA本身不提供这样的注释。

但是Hibernate特定的Where注释完全符合您的要求。唯一的缺点 - 它需要一个集合才能工作,你可以使用特定的getter进行解决:

@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);
}