JPA 및 Hibernate를 사용할 때 ID 생성 전략을 선택하는 방법


102

Hibernate 참조 가이드의 Id 생성 섹션과 "Hibernate를 사용한 자바 지속성"을 살펴 보았습니다.

Hibernate와 JPA를 결합하여 사용할 수있는 몇 가지 옵션이 있습니다.

특정 ID 생성 전략을 선택하는 방법에 대한 추가 문서를 찾고있었습니다.

나는 또한 티핑 포인트를 찾고 있습니다.

예를 들어, hilo 전략은 경합을 줄일 것으로 예상됩니다. 나는이 선택과 관련된 트레이드 오프가 있어야한다고 가정하고있다.

트레이드 오프에 대해 교육 받고 싶습니다.

사용할 수있는 문헌이 있습니까?

답변:


92

API의 문서는 이 매우 명확하다.

모든 생성기는 org.hibernate.id.IdentifierGenerator 인터페이스를 구현합니다. 이것은 매우 간단한 인터페이스입니다. 일부 애플리케이션은 고유 한 특수 구현을 제공하도록 선택할 수 있지만 Hibernate는 다양한 내장 구현을 제공합니다. 내장 생성기의 바로 가기 이름은 다음과 같습니다.

증가

다른 프로세스가 동일한 테이블에 데이터를 삽입하지 않는 경우에만 고유 한 long, short 또는 int 유형의 식별자를 생성합니다. 클러스터에서 사용하지 마십시오.

정체

DB2, MySQL, MS SQL Server, Sybase 및 HypersonicSQL에서 ID 열을 지원합니다. 반환 된 식별자는 long, short 또는 int 유형입니다.

순서

DB2, PostgreSQL, Oracle, SAP DB, McKoi의 시퀀스 또는 Interbase의 생성기를 사용합니다. 반환 된 식별자는 long, short 또는 int 유형입니다.

Hilo

hi / lo 알고리즘을 사용하여 hi 값의 소스로 테이블과 열 (각각 기본적으로 hibernate_unique_key 및 next_hi)이 주어지면 long, short 또는 int 유형의 식별자를 효율적으로 생성합니다. hi / lo 알고리즘은 특정 데이터베이스에 대해서만 고유 한 식별자를 생성합니다.

Seqhilo

hi / lo 알고리즘을 사용하여 명명 된 데이터베이스 시퀀스가 ​​주어지면 long, short 또는 int 유형의 식별자를 효율적으로 생성합니다.

UUID

128 비트 UUID 알고리즘을 사용하여 네트워크 내에서 고유 한 문자열 유형의 식별자를 생성합니다 (IP 주소가 사용됨). UUID는 길이가 32 자리 16 진수 문자열로 인코딩됩니다.

GUID

MS SQL Server 및 MySQL에서 데이터베이스 생성 GUID 문자열을 사용합니다.

원주민

기본 데이터베이스의 기능에 따라 ID, 시퀀스 또는 hilo를 선택합니다.

할당

응용 프로그램이 save ()가 호출되기 전에 객체에 식별자를 할당하도록합니다. 요소가 지정되지 않은 경우 이것이 기본 전략입니다.

고르다

고유 키로 행을 선택하고 기본 키 값을 검색하여 데이터베이스 트리거에 의해 할당 된 기본 키를 검색합니다.

외국

다른 관련 개체의 식별자를 사용합니다. 일반적으로 기본 키 연결과 함께 사용됩니다.

시퀀스 동일성

실제 값 생성을 위해 데이터베이스 시퀀스를 사용하지만이를 JDBC3 getGeneratedKeys와 결합하여 삽입 문 실행의 일부로 생성 된 식별자 값을 반환하는 특수 시퀀스 생성 전략입니다. 이 전략은 JDK 1.4를 대상으로하는 Oracle 10g 드라이버에서만 지원됩니다. Oracle 드라이버의 버그로 인해 이러한 삽입 문에 대한 주석을 사용할 수 없습니다.

동시 사용자가 많지 않은 간단한 애플리케이션을 빌드하는 경우 증가, ID, hilo 등 을 사용할 수 있습니다 . 이들은 구성이 간단하고 db 내부에 많은 코딩이 필요하지 않았습니다.

데이터베이스에 따라 sequence 또는 guid를 선택해야합니다 . id데이터베이스 내에서 생성이 이루어 지기 때문에 안전하고 더 좋습니다 .

업데이트 : 최근에 기본 유형 (int)이 대신 warapper 유형 (Integer)을 사용하여 수정 된 idendity 문제가 발생했습니다.


응답 해주셔서 감사합니다. 나는 이미 문서를 보았다. 그러나 사람들이 hilo 및 seqhilo와 같은 것을 사용하는 이유를 찾고 있습니다. 우리는 언제 그 선택을합니까. select의 사용 사례는 무엇입니까?

시퀀스 나 GUID처럼 간단한 것이있을 때 개발자가 다른 방법을 선택해야 할 수 있습니다.

1
내 답변을 업데이트했습니다. 실제로 증가, 신원, hilo 등이 더 간단합니다. 그러나 엔터프라이즈 애플리케이션에는 적합하지 않습니다. 모든 옵션을 유지하는 것은 문제가되지 않지만 가장 적합한 옵션을 사용하십시오!
ManuPK

네. 지금까지 나는 찬성하거나 수락 할 특권이 없었습니다.

시간이 있으면 알려주세요.

45

기본적으로 두 가지 주요 선택이 있습니다.

  • 식별자를 직접 생성 할 수 있으며이 경우 할당 된 식별자를 사용할 수 있습니다 .
  • @GeneratedValue주석을 사용할 수 있으며 Hibernate가 식별자를 할당합니다.

생성 된 식별자의 경우 두 가지 옵션이 있습니다.

숫자 식별자의 경우 세 가지 옵션이 있습니다 .

  • 정체
  • 순서

IDENTITY는 JDBC 배치 업데이트를 비활성화 하므로 SEQUENCE (예 : MySQL)를 사용할 수없는 경우에만 좋은 선택 입니다.

SEQUENCE는 특히 pooled 또는 pooled-lo 와 같은 식별자 최적화 프로그램과 함께 사용될 때 선호되는 옵션 입니다.

TABLE은 별도의 트랜잭션을 사용하여 제대로 확장되지 않는 행 수준 잠금 및 식별자를 가져 오기 때문에 어떤 비용 으로든 피해야 합니다.


20


얼마 전에 Hibernate 키 생성기에 대한 자세한 기사를 썼습니다 : http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html

올바른 생성기를 선택하는 것은 복잡한 작업이지만 가능한 한 빨리 올바르게 시도하는 것이 중요합니다. 늦은 마이그레이션은 악몽 일 수 있습니다.

주제에서 약간 벗어 났지만 API를 통해 애플리케이션간에 키를 공유하는 것이 일반적으로 간과되는 문제를 제기 할 수있는 좋은 기회입니다. 개인적으로 저는 항상 대리 키를 선호하며 다른 시스템과 개체를 통신해야하는 경우 키를 노출하지 않습니다 (대리 키 임에도 불구하고). 추가 '외부 키'를 사용합니다. 컨설턴트로서 저는 1 년 또는 2 년 후에 한쪽이 키 범위 또는 무언가에 문제가 있음을 찾기 위해 객체 키를 사용하는 '훌륭한'시스템 통합을 두 번 이상 보았습니다 ( '그냥 사용하겠습니다'접근 방식). 내부 키를 노출하는 시스템에서 심층 마이그레이션이 필요한 종류. 키를 노출한다는 것은 코드의 기본 측면을 외부 제약에 노출시키는 것이 실제로 노출되어서는 안된다는 것을 의미합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.