当前位置: 首页 > 面试题库 >

Spring @Async:LAZY集合上的空休眠会话

饶德本
2023-03-14
问题内容

我在@Async服务层方法上使用注释。

当我紧急加载@OneToMany集合字段时,一切工作正常,但是当我尝试访问LAZY加载的元素时,我发现Hibernate
SessionImplementor对象session为null。这显然给了我一个例外:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:
....

这是我的收藏字段:

@OneToMany(mappedBy="abc", fetch=FetchType.LAZY, cascade=CascadeType.REMOVE)
@OrderBy(value="xsd asc")
@JsonIgnore
private Set<Item> items = new HashSet<Item>();

我如何绑定hibernate会话以便将对象延迟加载到@Async上下文中?

编辑

这是我的trancactionManager / entityManager配置

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="emf"/>
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter">

    </property>
    <property name="packagesToScan" value="it.domain"/>

    <property name="persistenceUnitName" value="persistenceUnit"/>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
            <!--${hibernate.format_sql} -->
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            <!-- ${hibernate.show_sql} -->
            <prop key="hibernate.show_sql">false</prop>

            <prop key="hibernate.connection.charSet">UTF-8</prop>

            <prop key="hibernate.max_fetch_depth">3</prop>
            <prop key="hibernate.jdbc.fetch_size">50</prop>
            <prop key="hibernate.jdbc.batch_size">20</prop>

            <prop key="org.hibernate.envers.audit_table_suffix">_H</prop>
            <prop key="org.hibernate.envers.revision_field_name">AUDIT_REVISION</prop>
            <prop key="org.hibernate.envers.revision_type_field_name">ACTION_TYPE</prop>
            <prop key="org.hibernate.envers.audit_strategy">org.hibernate.envers.strategy.ValidityAuditStrategy</prop>
            <prop key="org.hibernate.envers.audit_strategy_validity_end_rev_field_name">AUDIT_REVISION_END</prop>
            <prop key="org.hibernate.envers.audit_strategy_validity_store_revend_timestamp">True</prop>
            <prop key="org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name">AUDIT_REVISION_END_TS</prop>               
        </props>
    </property>
</bean>

<jpa:repositories base-package="it.repository"
                  entity-manager-factory-ref="emf"
                  transaction-manager-ref="transactionManager"/>

<jpa:auditing auditor-aware-ref="auditorAwareBean" />
<bean id="auditorAwareBean" class="it.auditor.AuditorAwareBean"/>

问题答案:

使用ThreadLocals保留Spring的事务上下文。这意味着您的SessionFactory仅可用于调度您的请求的线程,因此,如果创建一个新线程,您将获得null和相应的异常。

您的@Async方法所做的是使用TaskExecutor在另一个线程中运行您的方法。因此,您的服务正在发生上述问题。

我引用了Spring的JpaTransactionManager文档:

单个JPA EntityManagerFactory的PlatformTransactionManager实现。 将JPA
EntityManager从指定的工厂绑定到线程

,可能允许每个工厂一个线程绑定的EntityManager。SharedEntityManagerCreator和@PersistenceContext知道线程绑定的实体管理器,并自动参与此类事务。支持该事务管理机制的JPA访问代码需要使用其中一种。

如果要保留注释,则应查看Hibernate
CurrentSessionContext并以某种方式自行管理会话。



 类似资料:
  • 问题内容: 在具有两种类型的实体(父级和子级)的场景中: 父母-@OneToMany Collection孩子; 默认设置是对子级集合进行延迟加载。这种模式对少数儿童非常有效,但是如果这个数字很大,这似乎是不可持续的。因此,在某些情况下,我认为孩子的数量会很大,因此我使用了分页的服务方法(例如“ getChildren(父父母,int偏移量,int计数)”)。 问题是:这是处理此类情况的最佳方法吗

  • 问题内容: 我想问一下是否有可能使用hibernate方式做到这一点。假设我已经运行了HQL并检索了一个集合。是否可以使用hibernate进一步过滤它? 我试图在标头类中使用,并在查询之前添加session.enable(),但似乎无法正常工作。 样例代码 精简HQL 问题答案: 不。至少不是您问的方式。一旦您要求Hibernate(使用方法)访问数据库,Hibernate就发挥了作用,结果现在

  • 问题内容: 我正在测试休眠并将此查询提供给 我在命令行中得到这些查询: 我使用的是“合并不保存”,所以为什么休眠要更新我的对象,所以不应该更新。对吗 怎么了 问题答案: 我将尝试使用一个更具体的示例进行解释。假设您有以下情况: 尝试重新附加分离的对象时发生异常,userA。 为了解决上述问题,使用了merge(),如下所示:

  • 问题内容: 欢迎, Hibernate映射存在一些问题。 数据库结构: POJO结构: 我想拥有的是TableC Pojo映射中TableB元素的集合,映射键是tableA。 该集合应该是只读的。 映射应为hbm而非注释。 我可能已经以各种可能的方式完成了此操作…我遇到的关闭情况是,当我对一个TableC对象进行操作时,一切都是正确的,但是如果我加载它们的集合,则只有最后一个具有正确的集合集。 更

  • 问题内容: 我在hibernate和延迟加载方面遇到问题。 背景:我有一个Spring MVC Web应用程序,我将Hibernate用于持久层。我正在使用OpenSessionInViewFilter使我能够在视图层中延迟加载实体。我正在扩展HibernateDaoSupport类,并使用HibernateTemplate保存/加载对象。一切都进行得很好。直至现在。 问题:我有一个可以通过Web

  • 问题内容: 我一直遇到这个问题: 我想让休眠管理一个表,该表代表一个集合的集合。例如: 地图地图 套装清单 清单地图 例如,我希望能够代表这一点: 作为一个表: 没有自定义的休眠代码似乎是不可能的,我不介意。但是我希望有人对自定义代码的外观有所指导。 我应该扩展AbstractPersistentCollection吗? CompositeUserType? 可以管理多个表是否正常,但是从数据库角