Я знаю, что слишком поздно ответить на этот вопрос. У меня такая же ситуация с методом 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();
}
}
спасибо за ваш комментарий, но я до сих пор считаю это недосмотром. Ваш комментарий о том, что «События созданы вокруг жизненного цикла объекта домена или документа по крайней мере» для меня, не исключает обновлений, в которых вы ссылаетесь на объект домена, по классу, как в MongoTemplate.updateMulti (запрос, обновление, DomainObject .class, collectionName); Это означает, что $ update является частью объекта домена, referencable посредством $ query и типа DomainObject. – rogodeter
Даже если это не исключает вас обновления, единственный способ реализовать это в основном подорвет эффективность операции обновления, так как мы должны сначала прочитать документ, материализовать ist, инициировать события, а затем записать его обратно. Это полностью подрывает намерение операции обновления, которая должна быть выполнена * в базе данных *. Если вы хотите, чтобы объекты домена были материализованы, прочитайте их, измените их и запишите. Вы не можете иметь оба одновременно. Так работают базы данных (в данном случае MongoDB). –
О том, если гипотетический прослушиватель обновлений (onBeforeUpdate) просто предоставил запрос DBO и обновил DBO слушателю. Это будет служить, по крайней мере, в двух случаях, о которых я думаю. Сначала замаскивается объект etag (который хранится в другой базе данных), второй отправляет webhook с обновленной информацией о состоянии. – rogodeter