使用Spring AOP时,我在将日志(或任何其他信息)保存在数据库中时遇到问题。
这是问题的根源:
@Aspect
@Configuration
@Component
@EnableAspectJAutoProxy
public class LoggingAspect {
@Autowired
private LogService logService;
@AfterThrowing(pointcut = "execution(* org.springframework.web.client.RestTemplate+.*(..))", throwing = "ex")
public void logError(Exception ex) {
Log log = new Log("Error!");
logService.save(log);
}
}
logService
实例是一个简单的@Service
类,它在内部调用@Repository
方法。没什么特别的。 Log
类更简单:)它仅包含一个变量(如果包含id,则包含两个):
@Entity
@Table
public class Log {
@Id
private Long id;
@Column
private String message;
//getters, setters, constructors, etc.
}
LoggingAspect
正常工作。如有任何异常,@AfterThrowing
通知会被正确调用。但是在调用save
方法之后,什么都不会保存在db中。
当我尝试调用getAll()
方法而不是save
时,一切正常。所有数据均从数据库加载。
此问题仅适用于save
方法。
如果有任何提示,我将不胜感激。
编辑:
如前所述,@Service
和@Repository
类目前非常基础。也许值得添加外部方面类,使一切运行正常。可以将日志保存在数据库中。仅在保存时才发生此问题,并且仅在各种建议中使用时才发生此问题。
已添加服务代码
@Service
public class LogService {
@Autowired
private LogRepository logRepository;
@Transactional(readOnly = true)
public List<Log> getAllLogs() {
return logRepository.findAll();
}
@Transactional
public void save(Log log) {
logRepository.save(log);
}
}
已添加存储库代码
@Repository
public interface LogRepository extends JpaRepository<Product, Log> {
}
答案 0 :(得分:1)
听起来像交易处理。
但是更多信息会很好,我只能在这里猜测。这么点检查,如果您还没有的话。
我猜您在服务或存储库上使用了@Transational,对吗?从Spring默认的代理机制开始,还要确保您在单独的类中具有Repository,Service。
调试并添加jpa,hibernate和spring事务的日志记录。
答案 1 :(得分:0)
好的。我找到了解决方案!
我怀疑这是交易问题。无论任何现有事务如何,都必须开始一个新事务。因此@Service
类中缺少一行(或更确切地说是交易属性)
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Log log) {
logRepository.save(log);
}
感谢所有帮助解决问题的人。