java - Spring Boot mongo审计@version问题
问题描述
我刚开始一个新项目,想使用 Sprint Boot 2.1,一开始就遇到了问题。我想做的是使用 Spring Boot Mongo 来管理数据库。我想要一个带有@Version
注释的乐观锁。但是,我发现它似乎@Version
会影响save()
MongoRepository 中的行为,这意味着 dup key 错误。
以下是示例代码。
POJO
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document
public class Person {
@Id public ObjectId id;
@CreatedDate public LocalDateTime createOn;
@LastModifiedDate public LocalDateTime modifiedOn;
@Version public long version;
private String name;
private String email;
public Person(String name, String email) {
this.name = name;
this.email = email;
}
@Override
public String toString() {
return String.format("Person [id=%s, name=%s, email=%s, createdOn=%s, modifiedOn=%s, version=%s]", id, name, email, createOn, modifiedOn, version);
}
}
MongoConfig
@Configuration
@EnableMongoRepositories("com.project.server.repo")
@EnableMongoAuditing
public class MongoConfig {
}
存储库
public interface PersonRepo extends MongoRepository<Person, ObjectId> {
Person save(Person person);
Person findByName(String name);
Person findByEmail(String email);
long count();
@Override
void delete(Person person);
}
如Official Doc中所示,我的version
字段位于 中long
,但 dup 键错误发生在 second save
,这意味着它再次尝试insert
,即使对象中有 id。
我也尝试了Long
inversion
字段,它没有发生 dup 键并按预期保存为更新,但createdOn
成为null
第一个save
(这意味着insert
)
控制器
Person joe = new Person("Joe", "aa@aa.aa");
System.out.println(joe.toString());
this.personRepo.save(joe);
Person who = this.personRepo.findByName("Joe");
System.out.println(who.toString());
who.setEmail("bb@bb.bb");
this.personRepo.save(who);
Person who1 = this.personRepo.findByName("Joe");
Person who2 = this.personRepo.findByEmail("bb@bb.bb");
System.out.println(who1.toString());
System.out.println(who2.toString());
使用 dup 键( long version
)登录
2018-11-11 02:09:31.435 INFO 4319 --- [on(6)-127.0.0.1] org.mongodb.driver.connection : Opened connection [connectionId{localValue:2, serverValue:186}] to localhost:27017
Person [id=null, name=Joe, email=aa@aa.aa, createdOn=null, modifiedOn=null, version=0]
2018-11-11 02:09:37.254 DEBUG 4319 --- [nio-8080-exec-1] o.s.data.auditing.AuditingHandler : Touched Person [id=null, name=Joe, email=aa@aa.aa, createdOn=2018-11-11T02:09:37.252, modifiedOn=2018-11-11T02:09:37.252, version=0] - Last modification at 2018-11-11T02:09:37.252 by unknown
2018-11-11 02:09:37.259 DEBUG 4319 --- [nio-8080-exec-1] o.s.data.mongodb.core.MongoTemplate : Inserting Document containing fields: [createOn, modifiedOn, version, name, email, _class] in collection: person
2018-11-11 02:09:37.297 DEBUG 4319 --- [nio-8080-exec-1] o.s.d.m.r.query.MongoQueryCreator : Created query Query: { "name" : "Joe" }, Fields: { }, Sort: { }
2018-11-11 02:09:37.304 DEBUG 4319 --- [nio-8080-exec-1] o.s.data.mongodb.core.MongoTemplate : find using query: { "name" : "Joe" } fields: Document{{}} for class: class com.seedu.server.model.Person in collection: person
Person [id=5be71ee11ad34410df06852c, name=Joe, email=aa@aa.aa, createdOn=2018-11-11T02:09:37.252, modifiedOn=2018-11-11T02:09:37.252, version=0]
2018-11-11 02:09:37.323 DEBUG 4319 --- [nio-8080-exec-1] o.s.data.auditing.AuditingHandler : Touched Person [id=5be71ee11ad34410df06852c, name=Joe, email=bb@bb.bb, createdOn=2018-11-11T02:09:37.323, modifiedOn=2018-11-11T02:09:37.323, version=0] - Last modification at 2018-11-11T02:09:37.323 by unknown
2018-11-11 02:09:37.324 DEBUG 4319 --- [nio-8080-exec-1] o.s.data.mongodb.core.MongoTemplate : Inserting Document containing fields: [_id, createOn, modifiedOn, version, name, email, _class] in collection: person
org.springframework.dao.DuplicateKeyException: E11000 duplicate key error collection: seedu.person index: _id_ dup key: { : ObjectId('5be71ee11ad34410df06852c') }; nested exception is com.mongodb.MongoWriteException: E11000 duplicate key error collection: seedu.person index: _id_ dup key: { : ObjectId('5be71ee11ad34410df06852c') }
使用 createdDate null ( Long version
)记录
2018-11-11 02:07:28.858 INFO 4310 --- [on(6)-127.0.0.1] org.mongodb.driver.connection : Opened connection [connectionId{localValue:2, serverValue:183}] to localhost:27017
Person [id=null, name=Joe, email=aa@aa.aa, createdOn=null, modifiedOn=null, version=null]
2018-11-11 02:07:31.519 DEBUG 4310 --- [nio-8080-exec-1] o.s.data.auditing.AuditingHandler : Touched Person [id=null, name=Joe, email=aa@aa.aa, createdOn=null, modifiedOn=2018-11-11T02:07:31.518, version=0] - Last modification at 2018-11-11T02:07:31.518 by unknown
2018-11-11 02:07:31.525 DEBUG 4310 --- [nio-8080-exec-1] o.s.data.mongodb.core.MongoTemplate : Inserting Document containing fields: [modifiedOn, version, name, email, _class] in collection: person
2018-11-11 02:07:31.564 DEBUG 4310 --- [nio-8080-exec-1] o.s.d.m.r.query.MongoQueryCreator : Created query Query: { "name" : "Joe" }, Fields: { }, Sort: { }
2018-11-11 02:07:31.571 DEBUG 4310 --- [nio-8080-exec-1] o.s.data.mongodb.core.MongoTemplate : find using query: { "name" : "Joe" } fields: Document{{}} for class: class com.seedu.server.model.Person in collection: person
Person [id=5be71e631ad34410d6a3b123, name=Joe, email=aa@aa.aa, createdOn=null, modifiedOn=2018-11-11T02:07:31.518, version=0]
2018-11-11 02:07:31.590 DEBUG 4310 --- [nio-8080-exec-1] o.s.data.auditing.AuditingHandler : Touched Person [id=5be71e631ad34410d6a3b123, name=Joe, email=bb@bb.bb, createdOn=null, modifiedOn=2018-11-11T02:07:31.590, version=1] - Last modification at 2018-11-11T02:07:31.590 by unknown
2018-11-11 02:07:31.598 DEBUG 4310 --- [nio-8080-exec-1] o.s.data.mongodb.core.MongoTemplate : Calling update using query: { "_id" : { "$oid" : "5be71e631ad34410d6a3b123" }, "version" : { "$numberLong" : "0" } } and update: { "modifiedOn" : { "$date" : 1541873251590 }, "version" : { "$numberLong" : "1" }, "name" : "Joe", "email" : "bb@bb.bb", "_class" : "com.seedu.server.model.Person" } in collection: person
2018-11-11 02:07:31.602 DEBUG 4310 --- [nio-8080-exec-1] o.s.d.m.r.query.MongoQueryCreator : Created query Query: { "name" : "Joe" }, Fields: { }, Sort: { }
2018-11-11 02:07:31.602 DEBUG 4310 --- [nio-8080-exec-1] o.s.data.mongodb.core.MongoTemplate : find using query: { "name" : "Joe" } fields: Document{{}} for class: class com.seedu.server.model.Person in collection: person
2018-11-11 02:07:31.603 DEBUG 4310 --- [nio-8080-exec-1] o.s.d.m.r.query.MongoQueryCreator : Created query Query: { "email" : "bb@bb.bb" }, Fields: { }, Sort: { }
2018-11-11 02:07:31.604 DEBUG 4310 --- [nio-8080-exec-1] o.s.data.mongodb.core.MongoTemplate : find using query: { "email" : "bb@bb.bb" } fields: Document{{}} for class: class com.seedu.server.model.Person in collection: person
Person [id=5be71e631ad34410d6a3b123, name=Joe, email=bb@bb.bb, createdOn=null, modifiedOn=2018-11-11T02:07:31.590, version=1]
Person [id=5be71e631ad34410d6a3b123, name=Joe, email=bb@bb.bb, createdOn=null, modifiedOn=2018-11-11T02:07:31.590, version=1]
据我所知,spring 使用 id 存在作为保存行为控制,这意味着如果 id 存在,那么保存就像 mongo 的插入一样。但是,在这里,版本似乎也会影响保存行为或影响spring识别id存在的方式。
问题:如何将 MongoAudit 与 MongoRepository 一起使用?我犯了任何错误/错误吗?
解决方案
对于使用@Version
,您必须首先从数据库中检索数据模型,并且在更新数据后,您必须将相同的数据保存到数据库中。例如:
personRepo.findByName(name).ifPresent(person-> {
person.setEmail("email@gamil.com");
personRepo.save(person);
log.info("Updated Data: {}", person);
});
@CreatedDate
null
如果您没有将其添加@Version
到您的模型类中,将永远如此。它适用于@Version
如果您没有添加@Version
到模型类并且您尝试使用具有模型类来更新相同的模型类,那么这里还要添加一点@Version
,它会再次给您重复 id 错误。
推荐阅读
- java - Android Studio NO image is seen in Image-Layout over Grid Layout
- php - 可以在对象中动态添加特征吗?
- c++ - 如何在命名空间中正确调用此函数?C++
- amazon-web-services - CNAME 条目在使用 Amazon Certificate Manager 的 NameCheap 上不起作用
- python - PyTorch 线性回归问题
- redux - 如何在 redux“timeoutScheduler”中间件文档示例中使用取消功能?
- c# - 查看器-pdf-工具栏上的硒
- python - 如何使用列表作为 numpy ndarrays 的索引参数?
- javascript - 从 Blob 或 base64 img src 将图像添加到织物 js 画布
- javascript - 如何使用引导程序 4 创建 3 状态复选框按钮