使用 Spring 存储库时如何解决“无法初始化代理 - 无会话”错误

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

我正在开发一个变异项目,它为每个租户维护不同的架构,遵循项目

由于我们动态切换租户,所以看起来好像遗漏了一些配置,即“关闭会话或不保持会话打开以获取 LAZY 加载的对象”。这会导致“无法初始化代理 - 无会话”错误。 请检查下面的链接以访问完整的项目和数据库模式脚本,请按照自述文件中给出的步骤操作。

项目

如果有人能指出代码中的问题将会很有帮助。

我尝试将服务方法放入@Transactional注释中,但这不起作用。

我期望它再次调用延迟加载的对象,这个项目是复杂项目的简化版本,实际上我有更多的延迟加载对象。

问题:- 我没有收到会话错误“无法初始化代理 [com.amran.dynamic.multitenant.tenant.entity.Tenant#1] - 无会话” 在第 26 行(/dynamicmultitenant/src/main/java/com/amran/dynamic/multitenant/tenant/service/ProductServiceImpl.java)

spring-boot hibernate spring-data-jpa microservices multi-tenant
2个回答
2
投票
TenantDatabaseConfig

MasterDatabaseConfig
中,您已正确添加
@EnableTransactionManagement
,它将根据请求设置交易。
但是 - 具有(隐式) 

@Transactional

注释的最外层组件是

ProductRepository
(由于它是由
SimpleJpaRepository
类实现的 - 该类已应用注释 -
https://github.com/studygolang/growth/ com/spring-projects/spring-data-jpa/blob/864c7c454dac61eb602674c4123d84e63f23d766/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java#L95
因此您的

productRepository.findAll();

调用将启动一个事务,创建一个JPA会话,运行查询,关闭会话,关闭事务,这意味着不再有任何打开的事务/会话来执行延迟加载.

因此,你最初的尝试

我尝试将服务方法放入@Transactional注释中,但这不起作用。

这是

正确的做法。 您没有准确地说出您尝试做什么以及在哪里,但有一些事情可能会出错。首先,确保您添加的是

org.springframework.transaction.annotation.Transactional

而不是 javax.transaction.Transactional 注释。

其次(在这种情况下更可能出现问题),您需要使用事务应该绑定到的
which
事务管理器来配置注释,否则它可能会使用针对主数据库连接创建的现有/新事务,不是租客。

在这种情况下,我认为

@Service @Transactional(transactionManager = "tenantTransactionManager") public class ProductServiceImpl implements ProductService { 应该适合您,并使服务的所有方法都绑定到租户数据库连接上的事务。

编辑:

回答后续问题:

您能否建议一种更好的方法在我的所有服务类中注入我的tenantTransactionManager,因为我不想在所有服务类中提及tenantTxnManger(如果有更好的方法的话)?

是的,当然。您可以创建一个应用多个其他注释的元注释,这样您就可以创建:

/** * Marks class as being a service operating on a single Tenant */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Service @Transactional("tenantTransactionManager") public @interface TenantService { }

然后您可以简单地用

@TenantService
 而不是 
@Service

来注释您的服务类:

@TenantService
public class ProductServiceImpl implements ProductService {
    

当在打开的上下文之外访问延迟加载模型时
Hibernate会话则出现此异常。

0
投票
您可以使用方法级别的@Transactional 注解。就这样吧

public interface ProductService { @Transactional YourDto methodTobeImplemented(Params); } // And implementation service class no need to annotated. @Service public class ProductServiceImpl implements ProductService { @Override YourDto methodTobeImplemented(Params){ return yourDto } }

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