ABOUT ME

-

Total
-
  • Spring Boot: Kotlin + Cassandra 에서 @CreatedDate null 해결
    컴퓨터/Spring Boot 2023. 12. 16. 17:40
    728x90
    반응형

    코틀린 스프링 부트에서 Apache Cassandra/Scylla 데이터 베이스를 사용할 때 Auditing을 해도

    @CreatedDate 어노테이션이 작동을 안 해서 null이다.

    @LastModifiedDate는 근데 작동을 잘한다.

     

    Main.kt

    @EnableScheduling
    @SpringBootApplication
    @EnableCassandraAuditing
    class KotlinTestApplication {
    
    //    @PostConstruct
    //    fun setTimeZone() {
    //        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"))
    //    }
    
        companion object {
            @JvmStatic
            fun main(args: Array<String>) {
                SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL)
                runApplication<KotlinTestApplication>(*args)
            }
        }
    }

     

    그래서 Persistable 인터페이스를 구현해서 isNew 방식을 사용해야 한다.

    Kotlin 클래스 필드에서 isNew를 사용하면 Persistable에 있는 isNew 오버라이딩 함수와 겹쳐서

    backing field로 해야한다. (이름 피하기)

     

    User.kt

    새로 생성할 때 수동으로 markAsNew를 불러서 isNew를 true로 만들고 업데이트할 때는 false로 만들어주면 된다.

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Table("users")
    data class User(
        @field:PrimaryKey(value = "id") val userId: UUID = Uuids.timeBased(),
    
        @field:Column("created_at") @CreatedDate val createdAt: Instant? = null,
    
        @field:Column("updated_at") @LastModifiedDate val updatedAt: Instant? = null,
        ) : Persistable<UUID> {
    
        @org.springframework.data.annotation.Transient
        @JsonIgnore
        private var _isNew: Boolean = false // Backing field
    
        fun update(name: String?, picture: String?): User {
            this.userName = name
            this.picture = picture
            this._isNew = false
            return this
        }
    
        fun markAsNew() {
            _isNew = true
        }
    
        override fun getId(): UUID = userId
        override fun isNew(): Boolean = _isNew
    }

     

    saving.kt

    유저 저장 예제

    fun toEntity(): User {
            val user = User(
                userName = name,
                permissions = setOf("ROLE_USER"),
            )
            user.markAsNew()
            return user
        }

     

    init.cql

    CREATE TABLE IF NOT EXISTS cswkotlin.users
    (
        id           uuid PRIMARY KEY,
        created_at   timestamp,
        updated_at   timestamp,
    );

     

    CQLSH 결과

    created_at에 생성 시각이 잘 들어간 것을 알 수 있다.

    728x90

    댓글