I have the following entity structure: Business --> Campaign --> Promotion, where ONE Business can have MANY Campaigns and ONE Campaign can have MANY Promotions. Both one-to-man
The generated sql would look something like:
select * from Business b
left outer join campaigns c on c.business_id = b.id
left join promotions p on p.campaign_id = c.id
where b.id=:id
Internally Hibernate will have only one Business instance, however the duplicates will be preserved in the result set. This is expected behaviour. The behaviour you require can be acheived either by using the DISTINCT clause, or by using a LinkedHashSet to filter results:
Collection result = new LinkedHashSet(query.getResultList());
which will return only unique results, preserving insertion order.
The "org.hibernate.HibernateException: cannot simultaneously fetch multiple bags" happens whenever you try to eagerly fetch more than one collection in an ordered fashion (and possibly duplicated items). This does sort of make sense if you consider the generated SQL. Hibernate has no way of knowing whether a duplicated object was caused by the join or by actual duplicate data in the child table. Look at this for a good explanation.