【发布时间】:2021-03-10 03:35:45
【问题描述】:
Vlad 关于如何修复 MultipleBagsException 的示例将是我们的起点: How to fix 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();
作为参考,这是一个部署到 Wildfly 20 的 JavaEE 项目(不是 Spring)。 持久化单元在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 上下文?
【问题讨论】:
-
为什么除了使用实体管理器的实际类之外还包括所有内容?知道您是否在 EJB 中可能并不重要吗?
-
在无状态EJB中被异步方法调用。
-
我确信有数百个使用实体管理器的异步 EJB 方法示例,无需手动事务,因此它可能不是基本的 JEE 问题...
-
那么,在为 EJB 禁用事务之后,您想知道同一个 EJB 不会自动启动事务吗?
-
来自您发布的链接:“容器管理的扩展持久性上下文只能在有状态会话 bean 的范围内启动。”
标签: java hibernate jpa wildfly java-ee-8