【发布时间】:2022-11-07 19:08:11
【问题描述】:
我正在使用带有 Spring Data 的 Hibernate @Filter 为我的项目中的每个查询添加特定的“where”子句。问题是只要我为我的“findAll”方法使用@Transactional 注释,它就可以工作。有什么办法可以避免使用@Transactional?为什么在这里很重要?
这是过滤器配置:
@FilterDef(name = "testFilter",
parameters = @ParamDef(name = "company_id", type = "long"),
defaultCondition = "company_id=:companyId")
@Filter(name = "testFilter")
@EntityListeners(EmployeeListener.class)
@NoArgsConstructor
public class Employee {//basic fields}
存储库:
@Repository
public interface EmployeeRepository extends PagingAndSortingRepository<Employee, UUID> {
}
启用过滤器的方面:
@Aspect
@Component
public class TestAspect {
private final SecurityAspect securityAspect;
private final Logger logger;
@PersistenceContext
private EntityManager entityManager;
@Autowired
public TestAspect(SecurityAspect securityAspect, Logger logger) {
this.securityAspect = securityAspect;
this.logger = logger;
}
@Around("execution(* org.springframework.data.repository.CrudRepository+.findAll(..))")
public Object aroundFindAllTenantAware(ProceedingJoinPoint joinPoint) {
Session session = this.entityManager.unwrap(Session.class);
session.enableFilter("testFilter")
.setParameter("companyId", this.securityAspect.getCompanyId());
Object retValue = null;
try {
retValue = joinPoint.proceed();
} catch (Throwable throwable) {
logger.error(throwable.getMessage(), throwable);
} finally {
session.disableFilter("testFilter");
}
return retValue;
}
}
最后,我的服务:
@Service
@Transactional
public class EmployeeApiServiceImpl {
private final EmployeeRepository repository;
@Autowired
public EmployeeApiServiceImpl(EmployeeRepository repository) {
this.employeeRepository = employeeRepository; }
@Override
public Response listProfiles(SecurityContext securityContext) {
List<Employee> employees = repository.findAll();
return Response.ok().entity(employees).build();
}
没有@Transactional 注释,它不起作用。当我调试方面时,我可以看到过滤器已启用,但查询没有改变。当我添加注释时,一切正常。但我不明白为什么会这样。这个注释不应该出现在 read 方法上,而且在每个教程中,没有它一切都可以工作,但在我的情况下不是。
【问题讨论】:
-
请提供足够的代码,以便其他人可以更好地理解或重现该问题。
-
我猜测了一下,但我认为
this.entityManager.unwrap(Session.class)和@Transaction存在一些问题,您得到正确的Session该交易,但没有您收到的@Transaction会话可能与查询执行无关 -
我也有同样的想法。我正在激活与当前查询无关的错误会话。实际上,我不是在做宠物项目,所以很多人也在做它,在我们项目的每个服务中使用@Transactional 是不可接受的。有什么办法可以避免吗?我试图手动处理事务但无济于事......
标签: java spring hibernate jpa filter