Why does Spring Data MongoDB not expose events for

2019-04-16 00:46发布

It appears that the update for mongoOperations do not trigger the events in AbstractMongoEventListener.

This post indicates that was at least the case in Nov 2014

Is there currently any way to listen to update events like below? This seems to be quite a big omission if it is the case.

MongoTemplate.updateMulti()

Thanks!

2条回答
祖国的老花朵
2楼-- · 2019-04-16 01:36

I know it's too late to answer this Question, I have the same situation with MongoTemplate.findAndModify method and the reason I needed events is for Auditing purpose. here is what i did.

1.EventPublisher (which is ofc MongoTemplate's methods)

public class CustomMongoTemplate extends MongoTemplate {

    private ApplicationEventPublisher applicationEventPublisher;


    @Autowired
    public void setApplicationEventPublisher(ApplicationEventPublisher
                                                         applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

   //Default Constructor here

    @Override
    public <T> T findAndModify(Query query, Update update, Class<T> entityClass) {
        T result = super.findAndModify(query, update, entityClass);

        //Publishing Custom Event on findAndModify
        if(result!=null && result instanceof Parent)//All of my Domain class extends Parent
            this.applicationEventPublisher.publishEvent(new AfterFindAndModify
                    (this,((Parent)result).getId(),
                            result.getClass().toString())
            );

        return result;
    } }

2.Application Event

public class AfterFindAndModify extends ApplicationEvent {

    private DocumentAuditLog documentAuditLog;

    public AfterFindAndModify(Object source, String documentId,
                            String documentObject) {
        super(source);
        this.documentAuditLog = new DocumentAuditLog(documentId,
                documentObject,new Date(),"UPDATE");
    }

    public DocumentAuditLog getDocumentAuditLog() {
        return documentAuditLog;
    }
}

3.Application Listener

public class FindandUpdateMongoEventListner implements ApplicationListener<AfterFindAndModify> {

    @Autowired
    MongoOperations mongoOperations;

    @Override
    public void onApplicationEvent(AfterFindAndModify event) {
        mongoOperations.save(event.getDocumentAuditLog());
    }
}

and then

@Configuration
@EnableMongoRepositories(basePackages = "my.pkg")
@ComponentScan(basePackages = {"my.pkg"})
public class MongoConfig extends AbstractMongoConfiguration {

    //.....

    @Bean
    public FindandUpdateMongoEventListner findandUpdateMongoEventListner(){
        return new FindandUpdateMongoEventListner();
    }   

}
查看更多
神经病院院长
3楼-- · 2019-04-16 01:40

This is no oversight. Events are designed around the lifecycle of a domain object or a document at least, which means they usually contain an instance of the domain object you're interested in.

Updates on the other hand are completely handled in the database. So there are no documents or even domain objects handled in MongoTemplate. Consider this basically the same way JPA @EntityListeners are only triggered for entities that are loaded into the persistence context in the first place, but not triggered when a query is executed as the execution of the query is happening in the database.

查看更多
登录 后发表回答