我正在为我之前构建的API准备通知系统。基本上我有一个方面,它监听projectRepository.save
方法。我想要实现的是检查实体中的项目状态,它是保存方法的参数,具有数据库记录中的原始状态。我注意到,当我按id搜索DB记录时,它返回缓存值,因此它始终与保存方法中的对象相同,即使数据库仍然有旧的值。我可以强制Spring Data Jpa返回数据库记录而不是缓存的实体吗?
@Aspect
@Component
@RequiredArgsConstructor
public class NotificationAspect {
private final UserService userService;
private final ProjectRepository projectRepository;
private final NotificationService notificationService;
@Pointcut("execution(* *com.stars.domain.project.ProjectRepository.save(..))")
public void projectSavePointcut() {}
@Before("projectSavePointcut()")
public void sendNotificationOnStatusChange(JoinPoint joinPoint) {
if(joinPoint.getArgs().length > 0 && joinPoint.getArgs()[0] instanceof Project) {
Project projectToUpdate = (Project) joinPoint.getArgs()[0];
Optional<Project> oldProject = projectRepository.findById(projectToUpdate.getProjectId());
if(oldProject.isPresent() && !oldProject.get().getStatus().equals(projectToUpdate.getStatus())) {
notificationService.saveNotification(
MessageFormat.format("Project: {} status has been changed from: {} to: {}",
projectToUpdate.getName(),
oldProject.get().getStatus(),
projectToUpdate.getStatus()),
List.of(userService.getUser(projectToUpdate.getCreatedBy())));
}
}
}
}
即使数据库记录具有不同的值,该行也始终返回true。
oldProject.get().getStatus().equals(projectToUpdate.getStatus())
1条答案
按热度按时间sgtfey8w1#
我能想到两个办法。
首先,如果你只对
status
字段感兴趣,你可以在存储库中创建一个自定义的native查询,它将绕过EntityManager
,例如:第二种方法看起来不太好,但应该可行--您可以让实体管理器的缓存分离所有托管实体,这样它将被迫再次进行DB调用。
为此,在Aspect bean中注入
EntityManager
,并在调用projectRepository.findById
方法之前调用它的.clear()
方法。