본문 바로가기
백엔드/Spring

[Spring] Spring MongoTemplate에서 @LastModifiedDate와 Auditing 사용

by 작은소행성 2024. 12. 2.
mongoTemplate.updateFirst()를 사용하는 경우, Spring Data MongoDB의 Auditing 기능 (@LastModifiedDate, @CreatedDate)은 자동으로 적용되지 않는다. 

이는 mongoTemplate가 @LastModifiedDate 어노테이션을 처리하는 AuditingEntityListener를 트리거하지 않기 때문이다.

두개 동시 사용 관련된 내용

 

 

해결 방법

mongoTemplate.updateFirst()를 사용할 때도 @LastModifiedDate와 같은 기능을 구현하려면, 업데이트 쿼리에서 명시적으로 lastModifiedDate 필드를 설정해야 합니다.

 

 

업데이트 시 직접 필드 추가

mongoTemplate.updateFirst()를 사용할 때 현재 시간을 수동으로 추가하는 방법이다.

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;

@Service
public class YourService {

    @Autowired
    private ReactiveMongoTemplate mongoTemplate;

    public Mono<UpdateResult> updateEntity(String id, String newValue) {
        Query query = new Query(Criteria.where("id").is(id));
        Update update = new Update()
                .set("someField", newValue)
                .set("modifiedDate", LocalDateTime.now()); // lastModifiedDate를 명시적으로 설정

        return mongoTemplate.updateFirst(query, update, YourEntity.class);
    }
}

 

 

Auditing 가능하게 변경

Auditing 기능을 사용하려면 mongoTemplate 대신 save() 메서드를 사용하는 구조로 바꾸는 것이 좋다.

import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

@Service
public class YourService {

    @Autowired
    private YourEntityRepository repository;

    public Mono<YourEntity> updateEntity(String id, String newValue) {
        return repository.findById(id)
            .map(entity -> {
                entity.setSomeField(newValue);
                // Auditing으로 lastModifiedDate가 자동 갱신됨
                return entity;
            })
            .flatMap(repository::save);
    }
}

 

 

 

Auditing과 mongoTemplate 병합

mongoTemplate를 계속 사용하면서 Auditing 기능을 유지하려면 AuditingHandler를 직접 호출해서 @LastModifiedDate 필드를 업데이트할 수 있다.

import org.springframework.data.auditing.ReactiveIsNewAwareAuditingHandler;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.stereotype.Component;

@Component
public class CustomAuditingHandler {

    private final ReactiveIsNewAwareAuditingHandler auditingHandler;

    public CustomAuditingHandler(PersistentEntities entities) {
        this.auditingHandler = new ReactiveIsNewAwareAuditingHandler(entities);
    }

    public <T> T markAudited(T entity) {
        auditingHandler.markModified(entity);
        return entity;
    }
}

 

 

Handler 적용 코드 

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

@Service
public class YourService {

    @Autowired
    private ReactiveMongoTemplate mongoTemplate;

    @Autowired
    private CustomAuditingHandler auditingHandler;

    public Mono<UpdateResult> updateEntity(String id, String newValue) {
        Query query = new Query(Criteria.where("id").is(id));
        Update update = new Update().set("someField", newValue);

        // Auditing 적용
        YourEntity entity = new YourEntity();
        entity.setId(id);
        auditingHandler.markAudited(entity);

        update.set("lastModifiedDate", entity.getLastModifiedDate());

        return mongoTemplate.updateFirst(query, update, YourEntity.class);
    }
}

 

 

반응형