我目前正在使用弹簧数据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();
}
答案 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();
}
然后您将看到您的审核数据按预期填充。
注意:使用大约 890 个实体进行测试,通过使用批量更新,执行时间从 7 秒减少到 0.5 秒。