views:

253

answers:

2

My problem seems pretty straightforward to me, but I just can't seem to find an answer that works. I have a Hibernate Entity which has a ManyToMany association with another Entity, which is fetched lazily by default. I want to create a Criteria which will return the Entity with the ManyToMany association loaded eagerly.

Here is the Entity in question (with irrelevant parts removed):

@Entity
public class Order {

  @ManyToMany
  private List<Item> items;

  @ManyToMany
  private List<Discount> discountEntries;

  ...

}

Here are my notable attempts thus far and the results:

Criteria criteria = getSession().createCriteria(Order.class)
                                .setFetchMode("items", FetchMode.SELECT)
                                .setFetchMode("discountEntries", FetchMode.SELECT);
criteria.list();

- Loads the items lazily

Criteria criteria = getSession().createCriteria(Order.class)
                                .setFetchMode("items", FetchMode.JOIN)
                                .setFetchMode("discountEntries", FetchMode.JOIN);
criteria.list();

- Cannot fetch multiple bags

Criteria criteria = getSession().createCriteria(Order.class)
                                .createAlias("items", "items", CriteriaSpecification.INNER_JOIN)
                                .setFetchMode("items", FetchMode.JOIN)
                                .createAlias("discountEntries", "discountEntries", CriteriaSpecification.INNER_JOIN)
                                .setFetchMode("discountEntries", FetchMode.JOIN);
criteria.list();

- Returns an empty list

EDIT: Added another ManyToMany association as that seems to be part of the problem.

+2  A: 

Did you try: @ManyToMany(fetch = FetchType.EAGER)? what was the result?

Sharon Sofer
It loads the items correctly - eagerly, but I only want to do this for one Criteria, not all the time. Thus I need some way to load it eagerly on the Criteria.
Zecrates
+1  A: 

Get the collection with the LAZY setting and :

List list = criteria.list();
Hibernate.initialize(list);

This will initialize it immediately, only for this case.

Bozho
To add to your answer - this will result in an outer join unless you use @Fetch(FetchMode.SUBSELECT) on the association in your entity.
Zecrates