【问题标题】:@RepositoryEventHandler only invoked via HTTP - why?@RepositoryEventHandler 仅通过 HTTP 调用 - 为什么?
【发布时间】:2016-10-05 01:21:54
【问题描述】:

当我使用 @RepositoryEventHandler 时,它的方法只有在通过 HTTP 进入存储库时才会被调用。

有什么理由吗?好的,它被称为 Spring Data REST,但是当我直接调用我的存储库而不是通过 HTTP 时,调用处理程序不是很有用吗?

有什么方法可以在直接调用时调用处理程序(一些神奇的 AOP 东西)?

谢谢

【问题讨论】:

    标签: spring-data-rest


    【解决方案1】:

    原因是不同 Spring Data 模块所涵盖的不同持久性机制已经附带了事件机制。根据您使用的机制,您现在可以使用不同的机制。

    不幸的是,这不能统一为例如使用 JPA,并非所有持久性操作都需要首先通过存储库,因为 JPA 会自动刷新在 EntityManager 刷新时对附加实例所做的所有更改。在这种情况下,即使是存储库实例上的 AOP 也无济于事。

    所以你基本上有两个选择:

    • Spring Data REST 为所有存储库公开的事件(因为我们基本上不使用 JPA 中的自动更改跟踪)。
    • 存储特定的事件机制将确保持久性机制按照记录公开事件。

    【讨论】:

    • “Spring Data REST 为所有存储库公开的事件”是什么意思? “商店特定的事件机制”:因为我使用 JPA:你是指像 @PrePersist 等生命周期事件吗?
    • "…for all repositories" — 适用于所有独立于其支持持久性技术的存储库。 “……JPA”——是的。
    • 你的意思是 AbstractRepositoryEventListener?当我直接调用存储库而不是通过 HTTP 时会调用它吗? @PrePersist & Co:但是在这里我不允许调用 EntityManager 方法,例如当我想在创建实体时创建其他实体时。
    【解决方案2】:

    我不知道我在下面从其他 stackoverflow 问题中提出的解决方案是否会被 @Olivier-drotbohm 视为可以接受,但来自:

    SpringDataRest @RepositoryEventHandler not running when Controller is added

    @RepositoryEventHandler events stop with @RepositoryRestController

    您可以注入/自动装配“ApplicationEventPublisher”并手动触发 BeforeCreateEvent/AfterCreateEvent 以触发 RepositoryEventHandler。

    这不是一个完美的解决方案,但我希望它对你来说已经足够好了(我们已经测试过了:它有效)。

    【讨论】:

    • 另外,请注意这种方法:事件被触发,但您不能保证在事件处理程序中对实体进行的任何操作都会在事件触发之后的代码之前执行。例如:如果您在“Item”实体上触发 onBeforeCreate 然后保存它,并在 onBeforeCreate 的处理程序中更改项目的标题,它很可能不会与更改的标题一起保存。触发事件是异步的,而通过 REST 对存储库的调用通过 AOP 链接到 EventHandler。
    猜你喜欢
    • 2020-05-19
    • 2015-12-24
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多