0

I'm using Hibernate 3.3.2. I have class A, which has a property b, which maps a many-to-many relation to B.

Class A has the following mapping:

<set name="b" table="a_b" lazy="true">
   <key column="id_a"/>
   <many-to-many class="B" column="id_b" outer-join="auto" />
</set>

I am trying the following:

Criteria c = HibernateUtil.getSession().createCriteria(A.class);
ProjectionList pl = Projections.projectionList();
pl.add(Projections.property("id_a"), "id_a");
pl.add(Projections.property("b"), "b");
c.setProjection(pl);
c.add(Restrictions.eq("id", id));
Object o = c.list();

This code doesn't load any instance of B; the element corresponding to b in the returned ArrayList is null. Do you have any idea?

Thanks.

Marco
  • 26
  • 1
  • 2

2 Answers2

1

The code you provided fetchs the list of B entity of a specific A row. You should do the join in the inverse way, fetch B and join A just to restrict the query:

Criteria c = HibernateUtil.getSession().createCriteria(B.class);
c.createCriteria("a").add(Restrictions.eq("id", id));
List<B> o = (List<B>) c.list();

The above code should do the trick.

Renato Oliveira
  • 494
  • 4
  • 10
0

Since fetchType is lazy you need to create an alias for b: c.createAlias(...) so that hibernate will join A with B.

Stijn Geukens
  • 15,454
  • 8
  • 66
  • 101
  • I tried c.createAlias("b", "b"), but nothing changed. I suppose it has something to do with the cardinality of the relation. – Marco Apr 21 '11 at 10:54
  • Here is the code:`Criteria c = HibernateUtil.getSession().createCriteria(A.class); ProjectionList pl = Projections.projectionList(); pl.add(Projections.property("id_a"), "id_a"); pl.add(Projections.property("b"), "b"); c.setProjection(pl); c.createAlias("b", "b"); c.add(Restrictions.eq("id", id)); Object o = c.list();` – Marco Apr 21 '11 at 11:10
  • You are trying to fetch the id of a and the entity b? That will not work. Projections are not for loading entities but for aggregation and fetching specific properties of entities. In your case I don't see the need for Projections. Simply: ...`createCriteria(A.class).createAlias("b").list()`. This will load all A's with their B's. – Stijn Geukens Apr 21 '11 at 11:22
  • The entity A has many properties, so I need to project on a subset of them (I can't modify A). In the previous code I showed only the id. I'd like to load these properties with "b" too. – Marco Apr 21 '11 at 11:42
  • Ok, you could also specify which properties of b you want to fetch and then use like an AliasToBeanResultTransformer but for this scenario I would still advice to simply load A's with their B's. I doubt their will be any performance gain using Projections. Keep it simple. – Stijn Geukens Apr 21 '11 at 11:47