Пример Влада по исправлению MultipleBagsException будет нашей отправной точкой: Как исправить MultipleBagsException — Vlad Mihalcea
В нем он делает 2 последовательных запроса HQL, чтобы загрузить 2 лениво загруженных отношения (мешки).
Пытаясь применить это в нашем проекте, я заметил, что это работает только в том случае, если 2 запроса находятся в транзакции. Поэтому нам нужно создать транзакцию только для того, чтобы она заработала, а затем вскоре после этого откатить указанную транзакцию.
Пример:
utx.begin();
List<Post> posts = entityManager.createQuery("""
select distinct p
from Post p
left join fetch p.comments
where p.id between :minId and :maxId""", Post.class)
.setParameter("minId", 1L)
.setParameter("maxId", 50L)
.setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
.getResultList();
posts = entityManager.createQuery("""
select distinct p
from Post p
left join fetch p.tags t
where p in :posts""", Post.class)
.setParameter("posts", posts)
.setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
.getResultList();
utx.rollback();
Для справки: это проект JavaEE (не Spring), развернутый в Wildfly 20. Модуль сохранения определен как таковой в файле persistence.xml.
<persistence-unit name="some-p-unit-name">
<jta-data-source>java:/jdbc/someDB</jta-data-source>
</persistence-unit>
И EntityManager определяется как таковой:
@PersistenceContext(type = PersistenceContextType.EXTENDED, unitName = "some-p-unit-name")
private EntityManager em;
@Produces
@RequestScoped
@SomeResource // this is an annotation to differentiate it from another entity manager that can also be injectable
public EntityManager getEm() {
return em;
}
Так почему же нам нужно запускать транзакцию, чтобы PersistenceContext был включен, даже если мы настраиваем его на использование контекста EXTENDED?