Сгенерированный sql будет выглядеть примерно так:
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
Внутренне Hibernate будет иметь только один бизнес-экземпляр, однако дубликаты будут сохранены в наборе результатов. Это ожидаемое поведение. Требуемое поведение может быть достигнуто либо с помощью предложения DISTINCT, либо с помощью LinkedHashSet для фильтрации результатов:
Collection result = new LinkedHashSet(query.getResultList());
, который будет возвращать только уникальные результаты, сохраняя порядок вставки.
«org.hibernate.HibernateException: не может одновременно получить несколько сумок» возникает всякий раз, когда вы пытаетесь охотно получить более одной коллекции упорядоченным способом (и, возможно, дублировать элементы). Это имеет смысл, если учесть сгенерированный SQL. В Hibernate нет способа узнать, был ли дублированный объект вызван объединением или фактическими дублирующимися данными в дочерней таблице. Посмотрите на это для хорошего объяснения.