我有一个pojo,其外观如下:
@Document
public class MyPojo {
@Id
private String id;
...
@CreatedDate
private ZonedDateTime createdAt;
@LastModifiedDate
private ZonedDateTime modifiedAt;
}
我要使用以下逻辑对文档进行增补:
createdAt
和modifiedAt
都将设置为now
。createdAt
不应更新,modifiedAt
应该设置为now
。我尝试使用以下代码:
MongoTemplate template = ...; // wired
MyPojo obj = new MyPojo();
template.findAndReplace(
new Query().addCriteria(...),
obj,
new FindAndReplaceOptions().upsert());
此处,未设置成员id
,createdAt
和modifiedAt
(因此它们是null
)。
这似乎不起作用。永远不会设置数据库中BSON文档中的相应字段。
如何结合@CreatedDate
和@LastModifiedDate
批注来增补文档?这是可能的,还是我需要推出自己的产品。如果是后者,我如何实现如上所述的upsert逻辑?
我正在使用以下配置:
@Configuration
@EnableMongoAuditing(dateTimeProviderRef = "dateTimeConverter")
此处,dateTimeProviderRef
用于支持ZonedDateTime
对象。
也,我注意到,在调用template.save(obj)
或template.insert(obj)
而不是findAndReplace(...)
(如我的代码段)时,createdAt
和modifiedAt
如预期般在创建时设置。就是说,我相信我需要findAndReplace()
,因为我需要原子更新。
答案 0 :(得分:0)
您需要通过在@SpringBootApplication上使用@EnableMongoAuditing
启用审核
@SpringBootApplication
@EnableMongoAuditing(modifyOnCreate = false)
public class DemoApplication {
此外,不支持ZonedDateTime。请改为使用Instant。
参考:
请参见以下工作示例:
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.core.FindAndReplaceOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.Instant;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
@SpringBootApplication
@EnableMongoAuditing
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@RestController
class Ctrl {
@Autowired
MongoTemplate template;
@GetMapping("/templ")
void templ() throws InterruptedException {
template.insert(new MyPojo("TOM"));
template.insert(new MyPojo("HARRY"));
Thread.sleep(2000);
//update BOB to Robert if exists or insert new
//should inert new
template.findAndReplace(
query(where("name").is("BOB")),
new MyPojo("Robert"),
new FindAndReplaceOptions().upsert());
Thread.sleep(2000);
//update TOM to Tommy if exists or insert new
template.findAndReplace(
query(where("name").is("TOM")),
new MyPojo("Tommy"),
new FindAndReplaceOptions().upsert());
template.findAll(MyPojo.class).forEach(System.out::println);
}
}
@Document
@Data
@ToString
@NoArgsConstructor
class MyPojo {
public MyPojo(String name) {
this.name = name;
}
@Id
private String id;
String name = "";
@CreatedDate
private Instant createdAt;
@LastModifiedDate
private Instant modifiedAt;
}
输出:
MyPojo(id=5f736d33b72165754ea9fca1, name=Tommy, createdAt=2020-09-29T17:21:59.765Z, modifiedAt=null)
MyPojo(id=5f736d33b72165754ea9fca2, name=HARRY, createdAt=2020-09-29T17:21:55.732Z, modifiedAt=null)
MyPojo(id=5f736d352e78c143350ed0f8, name=Robert, createdAt=2020-09-29T17:21:57.748Z, modifiedAt=null)