보통 테이블의 키값은 DB에서 제공하는 sequence나 auto increment 같은 증가 값 형태를 많이 사용하는데요. 특정 방식으로 키값을 관리해야 하는 경우도 있습니다. 예를 들면 uuid나 주문번호처럼 일정 패턴으로 생성하는 값을 키값으로 사용하는 경우가 있습니다.

UUID로 ID 생성

Hibernate에서 기본적으로 제공하는 uuid를 이용해서 처리하는 방법을 먼저 확인해보겠습니다. 아래와 같이 entity 정의하고 저장하면 길이 36의 문자 uuid 값으로 생성되는 것을 확인할 수 있습니다. @GenericGenerator 애노테이션의 strategy 속성에서 uuid2으로 설정하면 org.hibernate.id.UUIDGenerator를 이용해서 키값을 생성하게 됩니다.

@Entity
@Table(name = """"order"""")
class Order{

  @Id  
  @GeneratedValue(generator = "uuid")  
  @GenericGenerator(name = "uuid", strategy = "uuid2")  
  @Column(name = "order_no")  
  val orderNo: String = ""

  @Column(name = "order_amt")
  var orderAmt: BigDecimal = BigDecimal.ZERO
    private set

  companion object {
    fun create(orderAmt: BigDecimal): Order {
      return Order().apply {
        this.orderAmt = orderAmt
      }
    }
  }
}

hibernate에서 제공하는 다른 종류의 기본 전략은 DefaultIdentifierGeneratorFactory에서 확인할 수 있습니다.

Custom ID 생성

custom ID를 생성하기 위해서 IdentifierGenerator 인터페이스를 이용해서 generate() 메서드를 구현합니다. session를 이용해서 쿼리를 실행하는 형태로도 만들 수 있지만, 현재 시간 정보와 6자리 랜덤 문자를 결합한 형태의 주문번호를 사용한다고 가정하고 만들겠습니다.

class OrderNoGenerator: IdentifierGenerator {
  override fun generate(session: SharedSessionContractImplementor,
                        entity: Any): Serializable {
    return System.currentTimeMillis().toString() +
        (1..999999).random().toString().padStart(6, '0')
  }
}

주문번호 생성을 위해 만든 OrderNoGenerator를 @Id 애노테이션이 있는 곳에 설정합니다.

@Id  
@GeneratedValue(generator = "orderNo")  
@GenericGenerator(name = "orderNo",   
 strategy = "com.order.entity.OrderNoGenerator")  
@Column(name = "order_no")  
val orderNo: String = ""

테스트 코드를 실행하면 ‘1583553989221246952’ 형태로 값이 생성되는 것을 확인할 수 있습니다. ID가 아닌 곳에 값을 설정하고 싶다면 지난 포스트 Hibernate에서 Custom Value 생성하기를 참고해 주세요.

끝.

Reference

댓글남기기