개요
회사에서 Spring Data r2dbc를 이용해서 레거시 프로젝트를 마이그레이션 하고 있습니다.
DB도 레거시 스타일로 되어 있었는데 PK가 복합키로 되어 있는 상황입니다.
create table Example
(
column1 long comment '다른 테이블 PK',
column2 varchar(10) comment '구분 타입',
created_at datetime,
updated_at datetime,
primary key (column1, column2)
);
예시와 같이 PK가 다른 테이블의 PK와 그것을 구분하는 타입으로 되어 있는 구조여서 PK를 직접 설정해서 insert를 해야했습니다.
하지만, PK를 직접 입력하고 repository.save() 메서드를 호출하면 update 쿼리가 나가는 문제가 발생했습니다.
해결
이를 해결하기 위해 Persistable을 구현하여 isNew를 재정의했습니다.
@Table("example")
data class Example(
@Id
@Column("column1") var id: Long? = null,
@Column("column2") val type: String?,
): Persistable<Long> {
@CreatedDate
@Column("created_at") var createdAt: LocalDateTime? = null
@LastModifiedDate
@Column("updated_at") var updatedAt: LocalDateTime? = null
override fun getId(): Long? {
return termId
}
override fun isNew(): Boolean {
return createdAt == null
}
}
save가 된 시점에서는 @CreatedAt을 이용해서 createdAt은 이미 값이 채워져있으므로 이를 이용해서 insert를 해야할지 update 를 해야할지 판단하도록 했습니다.
public class SimpleR2dbcRepository<T, ID> implements R2dbcRepository<T, ID> {
@Override
@Transactional
public <S extends T> Mono<S> save(S objectToSave) {
Assert.notNull(objectToSave, "Object to save must not be null");
if (this.entity.isNew(objectToSave)) { // isNew로 insert 여부 판단
return this.entityOperations.insert(objectToSave);
}
return this.entityOperations.update(objectToSave);
}
}
궁금한점
사실 save 전에 createdAt이 채워지는 것은 검색을 통해 찾았는데 이게 어느 시점에서 넣어지는지는 추가로 찾아서 정리하겠습니다