批量插入时弹簧数据mongodb审核不起作用

时间:2018-02-08 07:41:59

标签: java spring mongodb spring-data-mongodb

我目前正在使用弹簧数据mongodb 1.10.9.RELEASE,它由spring boot starter data mongodb 1.5.9导入。

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

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

这是一个bug还是故意或我发现错了?

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

private void save(List<byte[]> msgs, Class clazz) {
        if (CollectionUtils.isEmpty(msgs))
            return ;
        BulkOperations bulk = template.bulkOps(BulkOperations.BulkMode.UNORDERED, clazz);

        for (byte[] value : msgs) {
           bulk.insert(JSONUtil.readValue(value, clazz););
        }

        bulk.execute();
}

1 个答案:

答案 0 :(得分:0)

issue 解释了未填充审核数据的原因:

<块引用>

仅当直接通过 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();
}

然后您将看到您的审核数据按预期填充。

Audit data was populated

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