2016-03-07 4 views
1

Похоже, что обновление для mongoOperations не активирует события в AbstractMongoEventListener.Почему Spring Data MongoDB не предоставляет события для обновления ... (...) методов?

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

Есть ли в настоящее время какой-либо способ для прослушивания, чтобы обновить события, как показано ниже? Это кажется довольно большим упущением, если это так.

MongoTemplate.updateMulti() 

Спасибо!

ответ

1

Это не надзор. События создаются по всему жизненному циклу объекта домена или документа по крайней мере, что означает, что они обычно содержат экземпляр интересующего объекта домена.

Обновления, с другой стороны, полностью обрабатываются в базе данных. Таким образом, нет документов или даже объектов домена, обработанных в MongoTemplate. Рассмотрите это в основном так же, как JPA @EntityListener s запускаются только для объектов, которые вначале загружаются в контекст персистентности, но не запускаются, когда запрос выполняется по мере выполнения запроса в базе данных.

+0

спасибо за ваш комментарий, но я до сих пор считаю это недосмотром. Ваш комментарий о том, что «События созданы вокруг жизненного цикла объекта домена или документа по крайней мере» для меня, не исключает обновлений, в которых вы ссылаетесь на объект домена, по классу, как в MongoTemplate.updateMulti (запрос, обновление, DomainObject .class, collectionName); Это означает, что $ update является частью объекта домена, referencable посредством $ query и типа DomainObject. – rogodeter

+0

Даже если это не исключает вас обновления, единственный способ реализовать это в основном подорвет эффективность операции обновления, так как мы должны сначала прочитать документ, материализовать ist, инициировать события, а затем записать его обратно. Это полностью подрывает намерение операции обновления, которая должна быть выполнена * в базе данных *. Если вы хотите, чтобы объекты домена были материализованы, прочитайте их, измените их и запишите. Вы не можете иметь оба одновременно. Так работают базы данных (в данном случае MongoDB). –

+0

О том, если гипотетический прослушиватель обновлений (onBeforeUpdate) просто предоставил запрос DBO и обновил DBO слушателю. Это будет служить, по крайней мере, в двух случаях, о которых я думаю. Сначала замаскивается объект etag (который хранится в другой базе данных), второй отправляет webhook с обновленной информацией о состоянии. – rogodeter

2

Я знаю, что слишком поздно ответить на этот вопрос. У меня такая же ситуация с методом MongoTemplate.findAndModify, и причина, по которой мне нужны события, предназначена для целей аудита. вот что я сделал.

1.EventPublisher (который OFC методы MongoTemplate в)

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 Событие

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 Слушатель

public class FindandUpdateMongoEventListner implements ApplicationListener<AfterFindAndModify> { 

    @Autowired 
    MongoOperations mongoOperations; 

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

, а затем

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

    //..... 

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

} 
Смежные вопросы