▤ 목차
개요
JPA를 사용할 때 보통 id는 시퀀스 id를 자주 사용합니다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
만약 요구사항으로 "앞에 특정 문자를 포함한 아이디 체계"
를 사용해야 한다고 하면 어떻게 해야할까 고민해보다가 내용을 찾고 정리해봤습니다.
IdGeneratorType Annotation
검색을 해보면 GenericGenerator
애너테이션을 사용해서 Generator
구현체와 함께 사용하는 예제들을 많지만 해당 애너테이션은 deprecated
되어있었습니다.
다른 방식으로는 IdGeneratorType
으로 애너테이션을 만들어서 사용하는 방법이 있습니다.
내부에는 Generator
를 상속 받는 클래스를 받고 있습니다.
해당 애너테이션으로 prefix
가 붙는 형식의 id를 만들어보겠습니다.
@IdGeneratorType(PrefixIdGenerator::class)
@Target(AnnotationTarget.FIELD, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class PrefixId(
val name: String,
val prefix: String = ""
)
방법은 간단합니다.
애너테이션을 만들고 IdGeneratorType
에 Generator
구현체를 넣으면 됩니다.
저는 추가적으로 Generator
구현체에서 사용할 파라미터도 같이 추가했습니다.
Generator 구현
이제 Generator
를 구현해 보겠습니다.
Generator
는 IdentifierGenerator
를 상속 받아 generate
함수를 override
해서 사용하면 됩니다.
애노테이션에서 받은 파라미터들은 구현체 클래스의 프로퍼티로 애너테이션을 받아서 값을 가져올 수 있습니다.
class PrefixIdGenerator(config: PrefixId) : IdentifierGenerator {
// 1)
private val prefix: String = config.prefix
override fun generate(session: SharedSessionContractImplementor, `obj`: Any): Any {
// 2)
val identifierPropertyName = session.getEntityPersister(obj.javaClass.name, obj).identifierPropertyName
// 3)
val query = java.lang.String.format(
"select %s from %s order by %s desc limit 1",
identifierPropertyName,
obj.javaClass.getSimpleName(),
identifierPropertyName
)
val ids = session.createQuery(query, String::class.java)
.stream()
// 4)
val max: Long = ids.findFirst()
.map { o -> o.toString().replace(prefix, "").toLong() }
.getOrElse {0L}
// 5)
return prefix + (max + 1)
}
}
- 프로퍼티로 받은 값을 가져와서 사용 할 수 있습니다.
- 해당
generator
를 사용하는 entity의 아이디 이름을 가져옵니다. - 마지막 id값을 가져오기 위한 쿼리문을 생성하고 실행시킵니다.
- 가져온 아이디값의 prefix제거하고 뒤에 숫자만 가져옵니다.
- prefix를 추가해서 마지막 id에 +1을 한 값으로 반환해서 아이디가 적용됩니다.
위에 예제는 auto_increment
로 되어있는 id 앞에 prefix
를 넣는 방식으로 구현해 봤습니다.
DB를 조회해서 아이디를 만드는 방식이 아닌 유일 아이디 생성기같은걸 만들어서 사용해도 될 것 같습니다.
'Backend > Spring' 카테고리의 다른 글
Spring boot 3.x OAuth2(Google, Kakao) 로그인/회원가입 구현 2 - API 개발 (1) | 2024.10.02 |
---|---|
Spring boot 3.x OAuth2(Google, Kakao) 로그인/회원가입 구현 1 - Flutter (1) | 2024.07.31 |
이커머스 서비스에서 동시성 문제 처리해보기 (0) | 2024.05.08 |
Spring Transactional Isolation (0) | 2023.01.04 |
Spring Transactional Propagation (0) | 2022.12.28 |