17

I am trying to add a RepositoryEventHandler as described on Spring Data REST documentation to the REST repository shown below:

@RepositoryRestResource(collectionResourceRel = "agents", path = "/agents")
public interface AgentRepository extends CrudRepository<Agent, Long> {
    // no implementation required; Spring Data will create a concrete Repository
}

I created an AgentEventHandler:

@Component
@RepositoryEventHandler(Agent.class)
public class AgentEventHandler {

    /**
     * Called before {@link Agent} is persisted 
     * 
     * @param agent
     */
    @HandleBeforeSave
    public void handleBeforeSave(Agent agent) {

        System.out.println("Saving Agent " + agent.toString());

    }
}

and declared it in a @Configuration component:

@Configuration
public class RepositoryConfiguration {

    /**
     * Declare an instance of the {@link AgentEventHandler}
     *
     * @return
     */
    @Bean
    AgentEventHandler agentEvenHandler() {

        return new AgentEventHandler();
    }
}

When I am POSTing to the REST resource, the Entity gets persisted but the method handleBeforeSave never gets invoked. What am I missing?

I'm using: Spring Boot 1.1.5.RELEASE

dimi
  • 1,496
  • 2
  • 15
  • 27
  • Does it work if you rather extend `AbstractRepositoryEventListener`? – Oliver Drotbohm Aug 26 '14 at 16:28
  • @OliverGierke (thanks for stepping in) no that made no difference [public class AgentEventHandler extends AbstractRepositoryEventListener] nor [public class AgentEventHandler extends AbstractRepositoryEventListener] – dimi Aug 26 '14 at 16:34
  • Are you sure the `RepositoryConfiguration` class is picked up by Boot? If so, any chance you create a tiny failing sample project and create a ticket in our [JIRA](https://jira.spring.io/browse/DATAREST)? – Oliver Drotbohm Aug 26 '14 at 16:37
  • @OliverGierke I think it is (I added a System.out.println("registering AgentEventHandler"); inside the agentEvenHandler method...if there are better ways to check this please let me know). Jira: I'll give it a shot! – dimi Aug 26 '14 at 16:49
  • @OliverGierke Not sure if it's really a bug or something I've misconfigured..So I pushed an example project on [github](https://github.com/dbalaouras/test-spring-data-rest-eventhandlers) instead of creating a ticket. – dimi Aug 26 '14 at 21:00
  • Okay, a few first impressions. First: the test case is sort of invalid as the event handler is only invoked by the rest layer, not the repositories. Second, you don't need to both import and extend `RepositoryRestMvcConfiguration`. One of that should be sufficient. – Oliver Drotbohm Aug 27 '14 at 06:57
  • RepositoryRestMvcConfiguration: yep, makes sense. Test case: also makes sense..but still it doesn't work when calling the api with curl e.g. I'll try to reproduce in a new test case. Any other thoughts in the meanwhile? – dimi Aug 27 '14 at 07:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60086/discussion-between-dimi-and-oliver-gierke). – dimi Aug 27 '14 at 13:18
  • The Spring Data REST documentation link is broken – TerekC May 09 '17 at 17:05
  • @TerekC thanks; fixed! – dimi Jun 13 '17 at 13:09

2 Answers2

29

Sometimes obvious mistakes go unnoticed.

POST-ing a Spring Data REST resource, emits a BeforeCreateEvent. To catch this event, the method handleBeforeSave must be annotated with @HandleBeforeCreate instead of @HandleBeforeSave (the latter gets invoked on PUT and PATCH HTTP calls).

Tests pass successfully on my (cleaned up) demo app now.

dimi
  • 1,496
  • 2
  • 15
  • 27
  • Before I start doing a little matrix myself over which events are emitted on specific HTTP calls, is this documented somewhere? I had a look in the Spring Data REST documentation, but it only mentions the events, not in detail to which HTTP call they will be emitted. – Beamie Jun 13 '17 at 06:25
  • 1
    @Beamie I did a quick search and couldn't find any documentation linking Spring Data REST events with HTTP verbs. The following should work tho: POST=>*CreateEvent, PUT=>*SaveEvent, DELETE=>*DeleteEvent. Detailed list of events: https://docs.spring.io/spring-data/rest/docs/current/reference/html/#events – dimi Jun 13 '17 at 12:58
  • Note for future readers: the Events (BeforeCreate, BeforeSave, etc) are not called if you override the default controller methods, so keep that in mind. – Vinícius M May 08 '20 at 01:08
1

How does your main Application class look like? Does it import the RepositoryRestMvcConfiguration as described in https://spring.io/guides/gs/accessing-data-rest/?

Marcel Overdijk
  • 11,041
  • 17
  • 71
  • 110
  • Marcel: I pushed an example project on [github](https://github.com/dbalaouras/test-spring-data-rest-eventhandlers). Appreciate your help. – dimi Aug 26 '14 at 21:00