Spring Boot @RepositoryEventHandler 未调用

Posted

技术标签:

【中文标题】Spring Boot @RepositoryEventHandler 未调用【英文标题】:Spring Boot @RepositoryEventHandler not invoked 【发布时间】:2015-12-24 02:30:58 【问题描述】:

我已经设置了一个@RepositoryEventHandler,但由于某种未知原因它没有被调用。

@Component
@RepositoryEventHandler(User.class)
public class UserEventHandler 

    @Autowired
    private PasswordCrypto passwordCrypto;

    @HandleBeforeSave
    public void handleUserSave(User user) 
        if (user.getPassword() != null && !"".equals(user.getPassword())) 
            user.setPassword(passwordCrypto.encrypt(user.getPassword()));
        
    

    @HandleBeforeCreate
    public void handleUserCreate(User user) 
        user.setPassword(passwordCrypto.encrypt(user.getPassword()));
    

存储库:

public interface UserRepository extends CrudRepository<User, Long> 
    Optional<User> findOneByUsername(String username);

还有我的主要课程:

@SpringBootApplication
@EntityScan("de.ihrig.feuerwehr.hydranet.model")
@EnableJpaRepositories
@ComponentScan(
    "somepath",
    "somepath including the UserEventHandler"
)
public class ServerApplication 

    public static void main(String[] args) 
        SpringApplication.run(ServerApplication.class, args);
    

提前感谢您的帮助,我只是找不到错误。

【问题讨论】:

请您解释一下您所说的不工作是什么意思?你是如何调用你的休息服务的?同样的设置对我有用,我相信问题可能在于你如何断定它不起作用。 好吧,我想我误解了@RepositoryEventHandler 的概念。它在对 Data-REST 公开的存储库执行的 HTTP 请求上调用,但不是在您以编程方式使用任何存储库方法时调用,这就是我所做的。注释的命名以某种方式误导...... ^^ 我想这就是你的答案。 有没有办法监听以编程方式完成的存储库更改? 如果你使用注解,你可以像@PrePersist这样使用JPA回调。 【参考方案1】:

可能会发生一些事情。

你的 repo 没有注释 @RestResource,但我猜这只是一个疏忽。

我猜 cmets 是正确的,您正在通过单元测试进行测试,其入口点未通过 REST API。 handlers 仅捕获通过该向量的 Repo 事件。

如果你想捕获任何 repo 事件,不管入口点,那么你想使用AbstractRepositoryEventListener

Spring Data Rest Events documentation 涵盖了这一点。另见listening for repository events in spring boot。

【讨论】:

哦,还有这个:***.com/questions/4895854/… “如果你想捕获任何 repo 事件,不管入口点如何,那么你想使用 AbstractRepositoryEventListener” @SebastiaanvandenBroek 我认为你是对的。这些文档是针对 SDR 的,它们清楚地声明“_REST 导出器发出了八种不同的事件_”,因此表明这些事件仅通过 SPR 触发。另一种选择可能是将Spring Data JPA Auditing hooks 用于AuditingEntityListener@Pre/@Post 注释,但我不确定可能会引入什么包袱。 我想你必须以某种方式拦截调用,确定它是否通过 REST API 调用,如果不是,然后发布 BeforeSaveEvent 但根据我的经验w/ SDR,这似乎是一个危险的提议。更好的方法可能是拥有一个应用程序事件侦听器,它使用UserEventHandler 已经在执行的函数来装饰创建的 repo bean。或者走简单的路线,覆盖 setPassword 以始终立即加密。 我不是 OP,出于另一个原因,我需要参与此事件,但在我的情况下它不是超级关键,我可以解决它。不过,我会看看这些选项,谢谢。

以上是关于Spring Boot @RepositoryEventHandler 未调用的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》

spring-boot-quartz, 依赖spring-boot-parent

spring-boot系列:初试spring-boot

Spring Boot:Spring Boot启动原理分析

Spring Boot:Spring Boot启动原理分析