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);
}
}
반응형
'백엔드 > Spring' 카테고리의 다른 글
[Spring] MongoDB - MongoTemplate 과 Auditing (0) | 2024.12.01 |
---|---|
[Spring] MongoDB 와 Redis 트랜잭션의 한계 와 대안 (0) | 2024.11.29 |
[Spring] Spring Web MVC, WebFlux 의존성 동시 사용 (0) | 2024.11.28 |
[Spring] Reactive MongoDB Stream의 Flux, Mono 조회 방법 비교 (0) | 2024.11.22 |
[Spring] ReactiveMongoTemplate vs ReactiveMongoRepository (0) | 2024.11.07 |