MySQL 및 Oracle로 최대 절전 모드 자동 키 생성
저는 동일한 데이터베이스 스키마를 가진 두 개의 서로 다른 데이터베이스에서 CRUD 작업(Hibernate 4.3.8 사용)을 수행하는 Java 애플리케이션을 작업하고 있습니다.MySQL(버전 5.1.73) 및 Oracle(11g Express Edition 릴리스 11.2.0.2.0 - 64비트) 데이터베이스가 있습니다.
JPA 주석이 있는 Java 클래스는 최대 절전 모드 코드 생성이 있는 데이터베이스 테이블에서 생성되었습니다.
문제는 이제 자동 기본 키 생성을 사용해야 하고 MySQL은 GenerationType을 사용해야 한다는 것입니다.IDENTITY 및 Oracle은 GenerationType을 사용합니다.순서.또한 드문 경우에 기본 키를 직접 수동으로 설정할 수 있는 기능이 필요합니다.
주석이 달린 클래스의 다음 코드는 두 데이터베이스의 자동 키 생성과 함께 작동하지만 기본 키가 자체 설정된 경우 실패합니다.
@GeneratedValue(strategy=GenerationType.AUTO, generator="sequence_generator")
@SequenceGenerator(name="sequence_generator", sequenceName="SEQUENCE1")
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
@GeneratedValue 및 @SequenceGenerator 주석이 없으면 기본 키를 수동으로 설정할 수 있지만 자동 생성이 작동하지 않습니다.
사용했더라도GenerationType.AUTO
SEQUENCE 관련 매개 변수가 없으면 할당된 식별자를 저장할 수 없습니다.
타협할 의사가 있는 경우 몇 가지 해결 방법이 있습니다.
한 가지 방법은 할당된 식별자로 전환하는 것입니다.MySQL 및 Oracle 모두에 대해 작동하는 UUID 식별자를 사용할 수 있으며 값을 수동으로 할당할 수도 있습니다.
다른 방법은 사용자 정의 테이블 생성기를 사용하는 것입니다.
먼저 식별 가능한 인터페이스를 정의합니다.
public interface Identifiable<T extends Serializable> {
T getId();
}
그런 다음 테이블 생성기를 확장합니다.
public class AssignedTableGenerator extends TableGenerator {
@Override
public Serializable generate(SessionImplementor session, Object obj) {
if(obj instanceof Identifiable) {
Identifiable identifiable = (Identifiable) obj;
Serializable id = identifiable.getId();
if(id != null) {
return id;
}
}
return super.generate(session, obj);
}
}
이 생성기는 할당된 식별자를 합성 생성된 식별자와 혼합할 수 있습니다.
doInTransaction(session -> {
for (int i = 0; i < 5; i++) {
session.persist(new AssignTableSequenceIdentifier());
}
AssignTableSequenceIdentifier tableSequenceIdentifier = new AssignTableSequenceIdentifier();
tableSequenceIdentifier.id = -1L;
session.merge(tableSequenceIdentifier);
session.flush();
});
다음 문 생성:
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
insert into sequence_table (sequence_name, next_val) values (default,1)
update sequence_table set next_val=2 where next_val=1 and sequence_name=default
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
update sequence_table set next_val=3 where next_val=2 and sequence_name=default
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
update sequence_table set next_val=4 where next_val=3 and sequence_name=default
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
update sequence_table set next_val=5 where next_val=4 and sequence_name=default
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
update sequence_table set next_val=6 where next_val=5 and sequence_name=default
select identityvs0_.id as id1_0_0_ from assigneTableIdentifier identityvs0_ where identityvs0_.id=-1
insert into assigneTableIdentifier (id) values (1, 2)
insert into assigneTableIdentifier (id) values (2, 4)
insert into assigneTableIdentifier (id) values (5, -1)
오라클의 경우 SEQUENCE와 할당된 생성기를 결합할 수 있습니다.간단히 말해서, 다음 생성기를 고려해 보십시오.
public class AssignedSequenceStyleGenerator
extends SequenceStyleGenerator {
@Override
public Serializable generate(SessionImplementor session,
Object obj) {
if(obj instanceof Identifiable) {
Identifiable identifiable = (Identifiable) obj;
Serializable id = identifiable.getId();
if(id != null) {
return id;
}
}
return super.generate(session, obj);
}
}
다음과 같이 엔티티에 매핑할 수 있습니다.
@Id
@GenericGenerator(
name = "assigned-sequence",
strategy = "com.vladmihalcea.book.hpjp.hibernate.identifier.AssignedSequenceStyleGenerator",
parameters = @org.hibernate.annotations.Parameter(
name = "sequence_name",
value = "post_sequence"
)
)
@GeneratedValue(
generator = "assigned-sequence",
strategy = GenerationType.SEQUENCE
)
private Long id;
모든 코드는 깃허브에서 사용할 수 있으며 매력적으로 작동합니다.
다음과 같은 방법을 사용해 보십시오.
@Id
@Column( name = "ID" )
@TableGenerator(
name = "AppSeqStore",
table = "APP_SEQ_STORE",
pkColumnName = "APP_SEQ_NAME",
pkColumnValue = "LISTENER_PK",
valueColumnName = "APP_SEQ_VALUE",
initialValue = 1,
allocationSize = 1 )
@GeneratedValue( strategy = GenerationType.TABLE, generator = "AppSeqStore" )
데이터베이스의 다음 표:
CREATE TABLE APP_SEQ_STORE (
APP_SEQ_NAME VARCHAR(255) NOT NULL,
APP_SEQ_VALUE NUMBER(10) NOT NULL,
PRIMARY KEY(APP_SEQ_NAME)
)
INSERT INTO APP_SEQ_STORE VALUES ('LISTENER_PK', 0)
이 모든 것은 JBoss를 App Server로 사용하는 Oracle, MS SQL Server 및 MySql에서 작동합니다.
자세한 내용은 여기에서 확인하십시오. http://www.developerscrappad.com/408/java/java-ee/ejb3-jpa-3-ways-of-generating-primary-key-through-generatedvalue/
언급URL : https://stackoverflow.com/questions/30731627/hibernate-auto-key-generation-with-mysql-and-oracle
'programing' 카테고리의 다른 글
테이블이 돌연변이 중이므로 트리거/기능이 이를 보지 못할 수 있습니다(평균 기울기가 2.5 미만으로 떨어지는 것을 방지). (0) | 2023.07.20 |
---|---|
데이터를 포함하는 동안 열 유형을 숫자에서 varchar2로 변경하는 Oracle SQL (0) | 2023.07.20 |
"excel package"로 색상 또는 배경을 설정하는 방법 (0) | 2023.07.20 |
파이썬에서 "if someobj == 없음:"보다 "if someobj:"가 더 나은 이유는 무엇입니까? (0) | 2023.07.20 |
SQL Oracle LEFT JOIN 및 SUBQUERY 오류: ORA-00905: 키워드 누락 (0) | 2023.07.20 |