2015-11-13 67 views
1

我有关于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; 
} 

我不想从我的“在Java中我的用户对象的最新-post'聚集加入数据。这味道不对。所以我正在寻找一个解决方案来将这个聚合字段嵌入到我的基础实体中。我在哪里可以指定在Hibernate中的用户对象的自定义检索来添加这样的聚合字段?

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

我希望我能说明我的想法和问题。提前致谢!

+0

是否有可能创建一个子选择并加入@ Where子句?如何?这是一个好主意吗? –

+0

我认为这是可能的 - 请参阅我的答案。我没有测试这个查询 - 可能有一些“微调”是必要的...... –

回答

0

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); 
} 
+0

如果我完全使用这个Annotations,Hibernate会创建并使用一个特定的表'user_latest_post'。这不是我期望发生的原因。 –

+0

好的,在这种情况下,它可以帮助设置'mappedBy'。 –