멀티 데이터 소스가 아닌 일반 JPA 설정 클래스

안상철·2023년 1월 7일
0

Kotlin Spring Boot

목록 보기
12/14
post-thumbnail

여기서 작성했던 멀티 데이터 소스말고,, 일반 jpa 설정을 위해 필요한 클래스를 알아보자

1. ApiApplication

@ConfigurationPropertiesScan
@SpringBootApplication(
    scanBasePackages = ["kr.co.도메인디렉토리 등등", "kr.co.참고할디렉토리 등등", "kr.co.apexsoft.gradnet2.api"]
)
class ApiApplication

fun main(args: Array<String>) {
    runApplication<ApiApplication>(*args)
}

스프링 이니셜라이저로 생성 한 프로젝트에 필수로 생성되는 어플리케이션 클래스에 basePacakage를 기재 해 주자. 내 경우 도메인이나 기타 라이브러리가 들어있는 domain, lib모듈의 위치를 기재했다.

2. JpaConfig

위치는 어느곳에 작성해도 상관 없는데, api 모듈의 config 디렉토리에 생성했다.

/**
 * JPA 설정 클래스
 * 2개의 빈은 디비 테이블에 createdAt, createdBy 등 audit 정보를 자동으로 저장하는데 사용
 */
@Configuration
@EntityScan(basePackages = ["kr.co.~.domain"])
@EnableJpaRepositories(basePackages = ["kr.co.~.domain"])
@EnableJpaAuditing(dateTimeProviderRef = "auditingDateTimeProvider")
class JpaConfig {

    @Bean
    fun auditingDateTimeProvider() = DateTimeProvider {
        Optional.of(LocalDateTime.now())
    }

    @Bean
    fun auditorAwareProvider() = AuditorAware {
        val authentication = SecurityContextHolder.getContext().authentication
        if (authentication == null) {
            Optional.empty()
        } else when (val principal: Any = authentication.principal) {
            is String -> Optional.of(principal)
            is AuthUser -> Optional.of(principal.userId)
            else -> Optional.empty()
        }
    }
}

@EntityScan 어노테이션 부분에는 읽어올 엔터티들이 들어있는 위치를, @EnableJpaRepositories 에는 Repo를 읽어올 위치를 적어준다. 보통 엔터티 클래스와 Repo는 함께 있기 때문에 동일한 디렉토리를 기재 해 주었다.

@EnableJpaAuditingSpring Audit 기능을 사용하기 위해 필요한 어노테이션인데, DB에 createdAt, lastModified 등 모든 테이블에 공통으로 들어갈 속성을 정의하고자 할 때 사용한다.

참고: https://mia-dahae.tistory.com/150

3. AbstractEntity

@MappedSuperclass
@EntityListeners(AuditingEntityListener::class)
abstract class AbstractEntity : Serializable {
    @CreatedDate
    @Column(name = "CREATED_DATE", updatable = false, columnDefinition = "DATETIME")
    protected lateinit var createdTime: LocalDateTime

    @Column(name = "CREATED_BY", updatable = false)
    @CreatedBy
    protected var createdBy: String? = null

    @LastModifiedDate
    @Column(name = "LAST_MODIFIED_DATE", columnDefinition = "DATETIME")
    protected lateinit var lastModifiedTime: LocalDateTime

    @Column(name = "LAST_MODIFIED_BY", updatable = true)
    @LastModifiedBy
    protected var lastModifiedBy: String? = null
}

도메인 모듈에 AbstractEntity라는 이름으로 추상 클래스를 작성 해 주었다.

@Entity
@Table(name = "USER")
class User(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "oid")
    val oid: Long? = null, //pk

    @Column(name = "USER_ID")
    val userId: String,

    @Column(name = "PASSWORD")
    private var password: String,

    @Column(name = "ROLES")
    @Convert(converter = RoleEnumToListConvert::class)
    private var roles: List<Role>,

) : AbstractEntity() {

    enum class RoleType (
        val id: Long
    ) {
        ROLE_USER(100),
        ROLE_SYS_ADMIN(200),
        ROLE_SCHL_ADMIN(210),
        ROLE_SET_ADMIN(220),
        ROLE_STLM_ADMIN(230),
        ROLE_TIME_INDEPENDENT(300)
    }

}

User클래스를 예로 가져왔는데, AbstractEntity를 상속받으면 자동생성 컬럼이 User 테이블에 적용된다.

다른 모든 엔터티 클래스에도 적용할 수 있다.

profile
웹 개발자(FE / BE) anna입니다.

0개의 댓글