![](/img/trans.png)
[英]@CreatedDate annotation does not work with spring-data-elasticsearch
[英]Spring Data MongoDB - Annotation @CreatedDate does not work while using with custom Id field
我有一個簡單的持久化類:
public class Profile implements Persistable<String>{
@Id
private String username;
@CreatedDate
public Date createdDate;
public Profile(String username) {
this.username = username;
}
@Override
public String getId() {
return username;
}
@Override
public boolean isNew() {
return username == null;
}
}
和一個簡單的存儲庫:
public interface ProfileRepository extends MongoRepository<Profile, String> {
}
我的 Spring Boot Application 類也用 @EnableMongoAuditing 進行了注釋。 但我仍然無法獲得注釋 @CreatedDate 工作。
ProfileRepository.save(new Profile("user1")) 寫入沒有字段 createdDate 的實體。 我做錯了什么?
編輯:這是我的應用程序類(沒有@EnableMongoRepositories,但它可以工作,因為存儲庫在我猜的子包中)
@SpringBootApplication
@EnableMongoAuditing
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
編輯:同時添加注釋 EnableMongoRepositories 沒有改變任何東西。
我自己剛剛遇到了這個問題,這是因為您自己創建了 id。
public Profile(String username) {
this.username = username;
}
通過這樣做,mongo 認為它不是一個新對象並且不使用 @CreatedDate 注釋。 您還可以使用 @Document 批注而不是實現 Persistable 類,如下所示:
@Document
public class Profile{}
您只應該將提交的@Version
添加到您的@Document
類並離開@EnableMongoAuditing
即
@Document
public class Profile implements Persistable<String>{
@Version
private Long version;
@Id
private String username;
@CreatedDate
public Date createdDate;
public Profile(String username) {
this.username = username;
}
@Override
public String getId() {
return username;
}
@Override
public boolean isNew() {
return username == null;
}
}
這是一個相關的問題: https : //jira.spring.io/browse/DATAMONGO-946
如果那是您真正的課程( Profile
),那么您無法使用標准工具做任何事情。
您的isNew
方法將始終返回false
,因為您自己設置了用戶名,並且當Profile
即將被 Spring 保存時,它會檢查isNew
並且您可能已經設置了username
。 @LastModifiedDate
會在你的情況下工作,但@CreatedDate
不會。
如果您沒有可以在isNew
方法中使用的其他字段,那么您必須手動設置createdDate
的值(或者可能有某種攔截器可以包裝所有 mongo 模板方法,但我不會那樣做) .
例如,檢查數據庫中是否已經存在具有給定用戶名的配置文件,如果是,則獲取它的 createdDate(您可以在此處使用投影)並設置為您將要保存的配置文件。 否則將 createdDate 設置為新日期。
如 Spring Data MongoDB 問題DATAMONGO-946中所述,創建日期功能使用isNew()
方法來確定是否應設置創建日期,因為實體是新的。 在您的情況下,您的isNew
方法始終返回 false,因為始終設置username
。
問題中的評論為這個問題提供了兩種可能的解決方案。
Persistable
解決方案第一個選項是修復isNew
策略,以便它正確注冊新對象。 評論中建議的一種方法是更改實現以檢查createdDate
字段本身,因為它應該只在非新對象上設置。
@Override
public boolean isNew() {
return createdDate == null;
}
第二個選項是從實現Persistable
改為使用持久化實體,並使用@Version
注釋在持久化 MongoDB 實體中注入version
屬性。 請注意,這將改變數據的持久化方式,因為它向數據添加了一個自動遞增的version
字段。
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class Profile {
@Id
private String username;
@CreatedDate
public Date createdDate;
@Version
public Integer version;
public Profile(String username) {
this.username = username;
}
}
我有一個類似的情況,我有時需要手動設置 id,如果不首先搜索數據庫來確定,真的沒有辦法提前知道 id 是新的還是更新的。 我也知道在實體的生命周期中,我會多次更新我的實體,但只創建一次。 所以為了避免額外的數據庫操作,我采用了這個解決方案:
Profile savedProfile = profileRepo.save(profile);
if (savedProfile.getCreatedDate() == null ){
savedProfile.setCreatedDate(savedProfile.getLastModifiedDate());
savedProfile = profileRepo.save(profile);
}
這是利用這樣一個事實,即我在 Profile 上也有一個@LastModifiedDate
字段,當保存實體時,該字段總是由 spring 數據更新。
對我來說,我只是這樣做:
@CreatedDate
@Field("created_date")
@JsonIgnore
private Instant createdDate = Instant.now();
並確保 Get/Set 可用。 希望這有幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.