简体   繁体   English

为什么 hibernate 持久性上下文在事务之外不可用?

[英]Why is the hibernate Persistence Context not available outside of a transaction?

Vlad's example for how to fix the MultipleBagsException will be our starting point: How to fix MultipleBagsException - Vlad Mihalcea Vlad 关于如何修复 MultipleBagsException 的示例将是我们的起点: 如何修复 MultipleBagsException - Vlad Mihalcea

In it it does 2 subsequent HQL queries in order to load 2 lazy loaded relationships (bags).在其中它执行 2 个后续 HQL 查询以加载 2 个延迟加载的关系(包)。

When trying to apply this in our project, I've noticed that it only works if the 2 queries are within a transaction.当试图在我们的项目中应用它时,我注意到它只有在 2 个查询在一个事务中时才有效。 So we have to create a transaction just to get it working and then rollback said transaction soon after.所以我们必须创建一个事务来让它工作,然后很快回滚所说的事务。
Example:例子:

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();

For reference, this is a JavaEE project (not Spring) deployed to Wildfly 20. The persistence unit is defined as such in persistence.xml作为参考,这是部署到 Wildfly 20 的 JavaEE 项目(不是 Spring)。持久化单元在 persistence.xml 中定义为

<persistence-unit name="some-p-unit-name">
    <jta-data-source>java:/jdbc/someDB</jta-data-source>
</persistence-unit>  

And the EntityManager is defined as such: 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;
}

So why do we need to start a transaction in order for the PersistenceContext to be enabled, even though we're setting it to use the EXTENDED context?那么为什么我们需要启动一个事务才能启用 PersistenceContext,即使我们将它设置为使用 EXTENDED 上下文?

Thanks @Smutje for leading me to the right answer.感谢@Smutje 引导我找到正确的答案。 The solution in our case was to annotate the class defining the EntityManager with @Stateful, as per the documentation the PersistenceContext is only available for Stateful EJBs in container managed scenarios.在我们的案例中,解决方案是使用 @Stateful 注释定义 EntityManager 的 class,根据文档,PersistenceContext 仅适用于容器管理场景中的有状态 EJB。

Sample Code below.下面的示例代码。 Note the Stateful annotation and also the persistence context type = EXTENDED.请注意有状态注释以及持久性上下文类型 = EXTENDED。

@Stateful
public class Resources {
    @PersistenceContext(type = PersistenceContextType.EXTENDED, unitName = "some-p-unit-name")
    private EntityManager em;

    @Produces
    @RequestScoped
    public EntityManager getEm() {
        return em;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 JTA 持久性上下文而不设置 hibernate.transaction.jta.platform - Using a JTA persistence context without setting hibernate.transaction.jta.platform 使用用户事务在Tomcat中进行Hibernate Persistence - Hibernate Persistence in Tomcat using User Transaction 生成持久性映射-&gt;通过休眠映射不可用Intellij - Generate persistence mappings -> by hibernate mappings not available Intellij 了解EJB和Hibernate上下文中的事务 - Understanding transaction in a context of EJB and Hibernate Spring Roo JPA-为什么在持久性上下文中自动提供手动数据库更新? - Spring Roo JPA - Why are manual DB updates automatically available in Persistence Context? 基于服务器主机和Jersey的Hibernate持久化上下文 - Hibernate persistence context based on server host with Jersey Hibernate 在选择之前不刷新持久性上下文 - Hibernate does not flush persistence context before selection 事务范围的持久化上下文和扩展持久化上下文有什么区别? - What is the difference between Transaction-scoped Persistence context and Extended Persistence context? javax.persistence.TransactionRequiredException: 没有 EntityManager 与当前线程可用的实际事务 - javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread Hibernate javax.persistence.RollbackException:提交事务时出错 - Hibernate javax.persistence.RollbackException: Error while committing the transaction
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM