Java 批量插入时spring数据mongodb审核不起作用

Java 批量插入时spring数据mongodb审核不起作用,java,spring,mongodb,spring-data-mongodb,Java,Spring,Mongodb,Spring Data Mongodb,我目前正在使用SpringDataMongoDB1.10.9.RELEASE,它由SpringBootStarter数据MongoDB1.5.9导入 在我的配置类上添加@EnableMongoAuditing并使用crudepository的函数save时,我的createdTime被透明地设置 但是,当我使用bulk.insert时,它不再起作用。我发现bulk.insert不发送BeforeConvertEvent,并且没有调用AuditingEventListener的onApplicat

我目前正在使用SpringDataMongoDB1.10.9.RELEASE,它由SpringBootStarter数据MongoDB1.5.9导入

在我的配置类上添加@EnableMongoAuditing并使用crudepository的函数save时,我的createdTime被透明地设置

但是,当我使用bulk.insert时,它不再起作用。我发现bulk.insert不发送BeforeConvertEvent,并且没有调用AuditingEventListener的onApplicationEvent(BeforeConvertEvent事件)。因此,尚未设置我的createdTime

那么这是一个bug还是故意的,或者我的发现是错误的

这是我的简单代码(未设置createdTime):

private void save(列出MSG、类clazz){
if(收款项为空(msgs))
返回;
BulkOperations bulk=template.bulkOps(BulkOperations.BulkMode.UNORDERED,clazz);
for(字节[]值:msgs){
bulk.insert(JSONUtil.readValue(value,clazz););
}
bulk.execute();
}
这解释了未填充审核数据的原因:

仅当通过IsNewAwareAuditingHandler直接处理实体时才应用审核,而不适用于基于查询/批量更新。基于查询的更新需要与实体类型关联,仅使用集合名称的更新不能参与审核更新

MongoTemplate没有直接批量更新实体列表的方法,因此我们必须逐个保存实体以获得审计数据,这会导致性能损失。它从我们的应用程序到数据库进行了多次往返

要利用具有良好性能的批量更新并拥有我们的审核数据,可以通过以下不需要太多更改的方式完成:

import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.Update;
import org.bson.Document;
import your.auditable.entity.MyEntity;

......

private Update convertToAuditableUpdateDocument(MyEntity entity)
    Document updateDoc = new Document();
    mongoConverter.write(entity, updateDoc);
    return Update.fromDocument(updateDoc)
            // for populating auditable data using bulk / query-based updates
            .set("lastModifiedBy", auditor)
            .set("lastModifiedDate", ZonedDateTime.now())
            .setOnInsert("createdBy", auditor)
            .setOnInsert("createdDate", ZonedDateTime.now());
}

....

private void bulkUpsertEntities(MongoTemplate template, List<Pair<Query, Update>> bulkUpsertList) {
    template.bulkOps(BulkOperations.BulkMode.UNORDERED, MyEntity.class)
              .upsert(bulkUpsertList)
              .execute();
}
import org.springframework.data.mongodb.core.convert.MongoConverter;
导入org.springframework.data.mongodb.core.query.Update;
导入org.bson.Document;
导入您的.auditable.entity.MyEntity;
......
私有更新转换为AuditableUpdateDocument(MyEntity实体)
Document updateDoc=新文档();
mongoConverter.write(实体,updateDoc);
返回Update.fromDocument(updateDoc)
//用于使用基于批量/查询的更新填充可审核数据
.set(“lastModifiedBy”,审计员)
.set(“lastModifiedDate”,ZonedDateTime.now())
.setOnInsert(“createdBy”,审计员)
.setOnInsert(“createdDate”,ZonedDateTime.now());
}
....
私有void bulkUpsertEntities(MongoTemplate模板,列表bulkUpsertList){
template.bulkOps(BulkOperations.BulkMode.UNORDERED,MyEntity.class)
.upsert(bulkUpsertList)
.execute();
}
然后您将看到审计数据按预期填充


注意:使用~890个实体进行测试,通过使用批量更新,执行时间从7秒减少到0.5秒。

是否可以更新堆栈日志以检查错误消息?批量操作不会发出事件,因此审核将不起作用,这是在Spring数据中故意以这种方式写入的mongodb@SunandPadmanabhan你能解释一下原因吗?如果我想在批量插入中设置我的createdTime,我该如何执行?@saif ali没有错误消息或任何日志,因为这不是一个错误,只是不要发送事件并触发相应的函数。@Gilad Peleg你是对的,但没有其他方法为我设置这些字段。如果你发现了,请告诉我。
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.Update;
import org.bson.Document;
import your.auditable.entity.MyEntity;

......

private Update convertToAuditableUpdateDocument(MyEntity entity)
    Document updateDoc = new Document();
    mongoConverter.write(entity, updateDoc);
    return Update.fromDocument(updateDoc)
            // for populating auditable data using bulk / query-based updates
            .set("lastModifiedBy", auditor)
            .set("lastModifiedDate", ZonedDateTime.now())
            .setOnInsert("createdBy", auditor)
            .setOnInsert("createdDate", ZonedDateTime.now());
}

....

private void bulkUpsertEntities(MongoTemplate template, List<Pair<Query, Update>> bulkUpsertList) {
    template.bulkOps(BulkOperations.BulkMode.UNORDERED, MyEntity.class)
              .upsert(bulkUpsertList)
              .execute();
}