web-dev-qa-db-ja.com

IDを手動で割り当てると、Spring Data MongoDBアノテーション@CreatedDateが機能しない

監査を使用してdateCreateddateUpdatedをオブジェクトに保存しようとしていますが、IDを手動で設定しているため、追加の作業がいくつかあります。

DATAMONGO-946 でのOliver Gierkeの提案に従って、正しく実装する方法を見つけようとしています。

上記のJiraタスクの元のポスターとして、ここから例をダウンロードしました https://github.com/spring-guides/gs-accessing-data-mongodb.git と少し変更しました:

package hello;

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.domain.Persistable;

import Java.util.Date;

public class Customer implements Persistable<String> {
    @Id
    private String id;
    @CreatedDate
    private Date createdDate;
    @LastModifiedDate
    private Date lastModifiedDate;
    private String firstName;
    private String lastName;
    private boolean persisted;

    public Customer() {
    }

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public void setPersisted(boolean persisted) {
        this.persisted = persisted;
    }

    @Override
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public boolean isNew() {
        return !persisted;
    }

    @Override
    public String toString() {
        return String.format(
                "Customer[id=%s, createdDate=%s, lastModifiedDate=%s, firstName='%s', lastName='%s']",
                id, createdDate, lastModifiedDate, firstName, lastName);
    }
}

そして

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.config.EnableMongoAuditing;

@SpringBootApplication
@EnableMongoAuditing
public class Application implements CommandLineRunner {

    @Autowired
    private CustomerRepository repository;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {

        repository.deleteAll();

        // create a customer
        Customer c = new Customer("Alice", "Smith");
        c.setId("test_id");

        // save a customer
        repository.save(c);

        // fetch all customers
        System.out.println("Customers found with findAll():");
        System.out.println("-------------------------------");
        for (Customer customer : repository.findAll()) {
            System.out.println(customer);
        }
        System.out.println();

        // create another customer with same id
        c = new Customer("Bob", "Smith");
        c.setId("test_id");
        c.setPersisted(true);
        repository.save(c);

        // fetch all customers
        System.out.println("Customers found with findAll():");
        System.out.println("-------------------------------");
        for (Customer customer : repository.findAll()) {
            System.out.println(customer);
        }
        System.out.println();
    }
}

そして実行の結果はこれです:

Customers found with findAll():
-------------------------------
Customer[id=test_id, createdDate=Wed Feb 24 00:43:47 WITA 2016, lastModifiedDate=Wed Feb 24 00:43:47 WITA 2016, firstName='Alice', lastName='Smith']

Customers found with findAll():
-------------------------------
Customer[id=test_id, createdDate=null, lastModifiedDate=Wed Feb 24 00:43:47 WITA 2016, firstName='Bob', lastName='Smith']

オブジェクトの更新後、createdDatenullになります。

ここで何が欠けていますか?また、Persistableを正しく実装して監査を適切に機能させるにはどうすればよいですか?

9
and_rew

コードは期待どおりに機能しています。 Persistableを実装すると、_@CreatedDate_アノテーションが機能していることがわかります。

createdDateは、nullの2回目の呼び出しでsaveであることを確認してください。オブジェクトが既にデータベースに存在し、_createdDate = null_で更新したためです。 _@CreatedDate_のドキュメントからわかるように:

@CreatedDateアノテーション。これは、エンティティが初めてデータベースに永続化されるときに値が設定されるフィールドを識別します。

したがって、2回目の呼び出しでcreatedDatenullで上書きしないようにするには、c = repository.findOne("test_id");を使用してデータベースから顧客を取得し、それを更新する必要があります。

8
Orest