在多线程环境下使用自定义entityManager

问题描述 投票:0回答:1

我使用EntityManager做了一些自定义查询,但遇到了一些问题。

  1. 首先,我将entityManager定义为单例bean,并注入到我的服务中,但是如果多个用户同时请求我的服务,我的后端将抛出异常“语句已关闭”。然后我意识到entityManager不是线程安全的。

2.所以我在我的entityManager bean上方添加了

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
注释。但这会导致另一个问题,数据库连接泄漏..

  1. 在Google上搜索后,有人说可以使用@PersistenceContext来注入bean,我尝试了一下,不幸的是,我遇到了另一个问题,
    ClassCastException: class jdk.proxy2.$Proxy288 cannot be cast to class org.hibernate.query.sql.internal.NativeQueryImpl

哦..我的环境:SpringBoot 3.1.11,hibernate-core:6.2.24.Final,HikariCp:5.0.1 我的代码片段:

    @Bean(name = "primaryEntityManager")
    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public EntityManager entityManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) {
        return factory.createEntityManager();
    }
String nativeSql = getNativeSql(methods, methodName, parameterMap);
            // 3.add parameters
String pagingSql = JpaUtils.addPageRequest(nativeSql, pageRequest);
jakarta.persistence.Query nativeQuery = addParameters(null, pagingSql, parameterMap);
            nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
            //nativeQuery.unwrap(NativeQueryImpl.class).setResultListTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List<Map<String, Object>> resultList = nativeQuery.getResultList();

当前异常:

java.lang.ClassCastException: class jdk.proxy2.$Proxy288 cannot be cast to class org.hibernate.query.sql.internal.NativeQueryImpl (jdk.proxy2.$Proxy288 is in module jdk.proxy2 of loader 'app'; org.hibernate.query.sql.internal.NativeQueryImpl is in unnamed module of loader 'app')
spring-boot jpa entitymanager
1个回答
0
投票

确实建议使用

@PersistenceContext
而不是直接将 EntityManager 定义为
@Bean
,因为 Spring 的
@PersistenceContext
注入会自动管理每个请求/事务范围的 EntityManager 实例,确保线程安全并避免连接泄漏。

@Configuration
public class EntityManagerConfig {

    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    public EntityManager getEntityManager() {
        return this.entityManager;
    }

Spring 将管理 EntityManager 生命周期,您可以避免多线程访问造成的泄漏或异常风险。

© www.soinside.com 2019 - 2024. All rights reserved.