java—使用entitymanager作为spring存储库中的自动连接字段

ki0zmccv  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(357)

我正在开发一个遗留代码库,在我们的自定义存储库中看到了一些令人不安的东西。 EntityManager 直接自动连接到回购中。例如:

@Repository
public class OperationRepository {

    // Yikes
    private final EntityManager entityManager;

    private QOperation operation = QOperation.operation;

    @Autowired
    public OperationRepositoryImpl(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public Optional<Operation> findOneByIdAndType(Long operationId, OperationType type) {
        JPAQuery<Operation> query = new JPAQuery<>(entityManager);
        QOperation qOperation = QOperation.operation;
        query.select(operation).from(operation)
                .where(
                        operation.type.eq(type),
                ...
    }
}

我的理解是,这是危险的,因为 EntityManager 不是线程安全的,在这里作为字段进行管理。我在我们的任何配置文件中都没有明确的定义来提供 EntityManager 所以我不确定spring在这种情况下做了什么。
我要开始修复使用 @PersistenceContext 但我想知道,这么长时间以来,这对生产有什么影响,可能会产生什么后果。
我们是否将连接池大小限制为存储库bean中单个EntityManager的数量?它还可能造成其他危险吗?还是我做的太多了?

zqdjd7g9

zqdjd7g91#

这实际上取决于应用程序上下文的配置,如果您使用spring boot,它可能会通过spring boot进行配置,但一般来说,对于典型的设置,这不是问题。
在这种设置中,应用程序上下文不包含单个(或一组有限的) EntityManager 示例,但 EntityManagerFactory 它可以创造 EntityManager 按需示例。而且你也不会被正常人注射 EntityManager 或者,但是一个代理在不同的调用中指向不同的示例,通常每个线程都有自己的示例 EntityManager 在一个web请求完成后,由同一线程处理的下一个请求将获得一个新的示例。
如果您仍然担心,我建议使用调试器来检查 EntityManager 并确认它确实是一个代理,并且它为不同的线程委托不同的实际示例。
您可能还想看看这个关于spring作用域的问题,它是springbean作用域的底层抽象

相关问题