나는 진정으로 의아해합니다 ...하지만 먼저, 대략적인 개요를 드리겠습니다.데이터베이스와 JPA에서 서로 다른 PostgreSQL 시퀀스 ID
저는 4 개의 테이블을 2 개로 병합하여 데이터베이스에서 일부 구조 조정을했습니다. 모든 테이블에는 기본 숫자 키로 간단한 숫자 시퀀스가 있습니다. 테이블은 실제로 쌍으로 아주 (매우) 비슷했습니다. 두 가지로 분리 된 유일한 이유는 가져와야하는 역사적인 데이터를 기반으로했습니다. 이 분할이 없었다면 많은 중복성이 있었을 것이고 개념적으로는 의미가 있습니다.
이제 데이터 정리에 많은 노력을 기울인 후에 마침내이를 병합하고 필드 중 하나를 판별 자로 사용하기 만하면됩니다. 덜 추상적 인 이야기를하기 위해 테이블에는 기업이 포함되어 있습니다. 그리고 그들은 지역 주민이거나 그렇지 않습니다 (두 클래스). 우편 번호 (판별 자 필드)로 쉽게 구별 할 수 있습니다. 이 테이블은 천천히 변화하는 차원입니다 (시퀀스가 서로 게이트입니다). 다른 두 테이블에는 이러한 SCD에 첨부 된 일반 데이터가 들어 있습니다. 따라서 4 개의 테이블. 2 개는 현지 회사, 2 개는 비 주민용입니다.
이 표는 이제 단순화되고 병합되었으므로 이제는 Company
과 CompanyData
만 있습니다.
역사적인 정보가 손실되지 않도록 안전하고 새로운 시퀀스 필드가있는 두 개의 새 테이블을 만들었습니다. 10 년 후 예전의 순서가 유지됩니다. 뭔가 잘못되었다는 것을 깨닫게됩니다.)
지금까지 그렇게 좋았습니다.
구조 조정은 매우 쉽고, 올바른 항목을 다시 연결하는 것도 간단합니다. 다음으로이 DB와 인터페이스하는 응용 프로그램을 업데이트해야했습니다.이 작업은 좀 더 쉽지만 여전히 쉽습니다. 이 애플리케이션은 이미 PostgreSQL 9.0 데이터베이스 위에 EclipseLink 2.0을 사용하여 JPA를 사용합니다. 나는 새로운 회사를 삽입 할 때
, 나는 주어진 ID가 이미 존재한다는, 중복 키 오류가 발생합니다 :
그리고 여기가 이상한 부분을 온다. 하지만 그것은 시퀀스 객체에 의해 처리되어야합니다 ... 그렇지 않아야합니까?
그래서 나는 주위를 파고 들었다. 연속적인 비활성으로 인해 실제로 번으로 개의 ID가 중복 된 키 오류가 반환되는지 확인할 수있었습니다. 즉, 시퀀스 논리가 OK입니다. 유일한 문제는 현재 값이 너무 낮다는 것입니다. 따라서 nextval (또는 JPA가 사용하는 것)을 호출하면 이미 존재하는 ID가 반환됩니다.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "enterprise_id_seq")
@Column(name = "id", nullable = false)
private Integer id;
그리고 내 순서는 다음과 같습니다 :
나는이 (가) JPA 엔티티에 다음이
[...]
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.1.v20100213-
r6600): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "enterprise_pkey"
Detail: Key (id)=(19611) already exists.
Error Code: 0
Call: INSERT INTO en...
[...]
로 :
test_db=# \d enterprise_id_seq
Sequence "public.enterprise_id_seq"
Column | Type | Value
---------------+---------+---------------------
sequence_name | name | enterprise_id_seq
last_value | bigint | 19659
start_value | bigint | 1
increment_by | bigint | 1
max_value | bigint | 9223372036854775807
min_value | bigint | 1
cache_value | bigint | 1
log_cnt | bigint | 32
is_cycled | boolean | f
is_called | boolean | t
오류 나는 얻을이 있습니다 id가 19611
인 엔티티를 삽입하려하지만 시퀀스의 마지막 값은입니다.. 분명히 틀렸어.
나는 또한이 모든 것의 뒤에서 응용 프로그램 서버를 다시 시작하여 열려있는 모든 연결과 세션을 닫으려고했습니다. 행운을 빌어 요 ... 내가 알아챈 또 다른 것 :이 필드는 Integer
으로 정의됩니다. 오히려 Long
일까요? 이는 코드의 변경을 필요로 할 것이며 아직 수정하지는 못했습니다.단순히 삽입 50 번 실행을 시도 할 수 있습니다,하지만 난 오히려 잘못되었는지 정확히 알 것 뒤에 난 단지 50 개 항목 해요으로
...
내가 무슨 말이냐?
업데이트
: 좀 더 파고 후, 나는 흥미롭게도,이 제가 보는 ID의 차이에 상당히 가깝게 (50)의 기본을 가지고 allocationSize을 가로 질러왔다. 일부 테스트 및 조정으로 인해 100 % 동일하지 않을 수도 있습니다. 그것은 관련 될 수 있습니까? 솔직히이 설정 뒤에있는 아이디어를 이해하지 못했습니다 ...
이전 매핑이 다른 시퀀스와 하나의 시퀀스가 '뒤에'있었습니까? 또 다른 질문 : 다른 환경의 데이터를 복사 했습니까? 시퀀스를 복사하지 않고 모든 테이블을 마이그레이션 할 수 있기 때문입니다. – Augusto
안녕하세요 Augusto, 빠른 답장을 보내 주셔서 감사합니다. 첫째, 데이터는 동일합니다. 그것은 다른 환경에서 온 것이 아닙니다. 나는 단지 테이블을 재 배열하고 떨어 뜨렸다. 또한, 매핑이 다른 시퀀스를 사용했다고 생각하지 않습니다. 새 시퀀스는 완전히 새로운 전용 시퀀스가있는 완전히 새로운 열입니다. - 한 쪽 메모 : 나는 방금 말하는 "allocationSize"설정과 우연히 만난다. 그것은 관련 될 수 있습니까? – exhuma