0

I am having a problem concerning hibernate annotation mapping configurations. Imagine the following two classes on a social media platform:

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

The most interesting information in my Use Case is the most recent Post every User wrote. I could read in the Users and append a custom query just like this:

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;

My Question now is, how I can embed the latest post in its mapped user as a field.

New User:

@Entity
class User {
  @Id
  @GeneratedValue
  private Long id;

  private String name;

  @OneToMany
  private List<Post> posts;

  //@Filter?
  //@Query?
  private Post latestPost;
}

I don't want to Join the data from my 'latest-post'-aggregation with my User-Objects in Java. This does not taste right. So I am searching for a solution to embed this aggregated field into my base-entity. Where can I specify a custom retrieval of User-Objects in Hibernate to add such an aggregated field?

You could imagine a similar problem with e.g. embedded sums of trade-amounts of a specific customer in a CRM.

I hope, i could illustrate my thoughts and problem. Thanks in advance!

Simon K.
  • 348
  • 1
  • 7
  • 24
  • Is it possible ot create a subselect and join in the @Where-clause? And how? Is this a good idea? – Simon K. Nov 13 '15 at 11:35
  • I would think it is possible - see my answer. I didn't test the query - it could be that there is some "finetuning" necessary... – Tobias Liefke Nov 13 '15 at 12:55

1 Answers1

0

JPA itself does not provide such an annotation.

But the Hibernate specific Where annotation does exactly what you want. The only disadvantage - it needs a collection to work, which you can workaround with a specific 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);
}
Tobias Liefke
  • 8,637
  • 2
  • 41
  • 58