views:

39

answers:

2

Hi all,

I wanted to know if there is a way to get in a One2Many relationship a field of the One side that is an aggregate of the Many side.

Let's take the following example:

@Entity
public class A {
 @Id
 private Long id;
 @OneToMany (mappedBy="parentA")
 private Collection<B> allBs;

 // Here I don't know how to Map the latest B by date
 private B latestB;
    // Acceptable would be to have : private Date latestBDate;
}

@Entity
public class B {
 @Id
 private Long id;
 private Date date;
 @ManyToOne (targetEntity=A.class)
 private A parentA;
}

My question is how can I make the mapping of the field latestB in the A entity object without doing any de-normalization (not keeping in sync the field with triggers/listeners)?

Perhaps this question gives some answers, but really I don't understand how it can work since I still want to be able to fetch all childs objects.

Thanks for reading/helping.

PS: I use hibernate as ORM/JPA provider, so an Hibernate solution can be provided if no JPA solution exists.
PS2: Or just tell me that I should not do this (with arguments of course) ;-)

A: 

See,

http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Filtering.2C_Complex_Joins

Basically JPA does not support this, but some JPA providers do.

You could also, - Make the variable transient and lazy initialize it from the OneToMany, or just provide a get method that searches the OneToMany. - Define another foreign key to the latest. - Remove the relationship and just query for the latest.

James
Thx for helping.> Make the variable transient and lazy initialize it from the OneToMany: what do you mean? traverse the collection?> provide a get method that searches the OneToMany : isn't it quite an ugly solution to query the EntityManager inside an Entity object?Also, what I would like to be able to do is to have the result in one single SQL query.
Matthieu BROUILLARD
A: 

I use hibernate as ORM/JPA provider, so an Hibernate solution can be provided if no JPA solution exists.

Implementing the acceptable solution (i.e. fetching a Date for the latest B) would be possible using a @Formula.

@Entity
public class A {
    @Id
    private Long id;
    @OneToMany (mappedBy="parentA")
    private Collection<B> allBs;

    @Formula("(select max(b.some_date) from B b where b.a_id = id)")
    private Date latestBDate;
}

References

Resources

Pascal Thivent
Will accept this answer as it is the nearest that I wanted to do, but it has the drawback to generate N+1 queries, hasn't it?
Matthieu BROUILLARD
@Matthieu Yes, it has. Maybe you could use a "special" version of the entity with the `@Formula` only for the use case that needs it.
Pascal Thivent