我正在开发一个遗留代码库,在我们的自定义存储库中看到了一些令人不安的东西。 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的数量?它还可能造成其他危险吗?还是我做的太多了?
1条答案
按热度按时间zqdjd7g91#
这实际上取决于应用程序上下文的配置,如果您使用spring boot,它可能会通过spring boot进行配置,但一般来说,对于典型的设置,这不是问题。
在这种设置中,应用程序上下文不包含单个(或一组有限的)
EntityManager
示例,但EntityManagerFactory
它可以创造EntityManager
按需示例。而且你也不会被正常人注射EntityManager
或者,但是一个代理在不同的调用中指向不同的示例,通常每个线程都有自己的示例EntityManager
在一个web请求完成后,由同一线程处理的下一个请求将获得一个新的示例。如果您仍然担心,我建议使用调试器来检查
EntityManager
并确认它确实是一个代理,并且它为不同的线程委托不同的实际示例。您可能还想看看这个关于spring作用域的问题,它是springbean作用域的底层抽象