我正在尝试映射我的域对象以使用新的Oracle 12c身份类型主键,在其他一些系统中使用AKA自动增量。
Hibernate 4没有Oracle12cDialect,它只有Oracle10gDialect。
Oracle10gDialect有一个名为supportsIdentityColumns()的方法,其中whitch被硬编码为false,因此将我的GORM域对象与生成器映射:“identity”会导致错误,表明Oracle10gDialect不支持身份生成器。
我不能使用GORM选择生成器,因为我没有辅助唯一键而且我不能使用Hibernate生成的密钥,因为Hibernate和其他(外部)插入表中会产生重叠键。
现有Oracle 12c DDL的示例:
create table person (
id number(10,0) generated by default as identity,
version number(10,0) not null,
home_address_id number(10,0),
name varchar(255) not null,
primary key (id)
);
GORM对象:
class Person {
String name
Address homeAddress
static mapping = {
id column: 'person_key', generator: 'identity'
}
static constraints = {
homeAddress nullable: true
}
}
在内存数据库结果中(完美工作):
Hibernate: create table person (person_key bigint generated by default as identity, version bigint not null, home_address_id bigint, name varchar(255) not null, primary key (person_key))
Hibernate: alter table person add constraint FK_bemy93e8a8i6nknj4n21m6fub foreign key (home_address_id) references address
Hibernate: insert into person (person_key, version, home_address_id, name) values (null, ?, ?, ?)
Oracle数据库结果(已损坏):
org.hibernate.MappingException: org.hibernate.dialect.Oracle10gDialect does not support identity key generation
如何让Grails 3.0.9使用上述Oracle表定义?
答案 0 :(得分:1)
无法将Hibernate 4配置为使用Oracle 12c身份密钥生成。
创建自定义Oracle12cDialect不允许我们使用身份密钥生成。它需要Hibernate 4中没有的额外支持。
Oracle10gDialect和使用生成器的工作原理是什么:' sequence-identity'然后像这样命名序列:
static mapping = {
id column: 'person_key', generator: 'sequence-identity', params:[sequence:'person_seq']
}
除了在DDL中创建具有标识关键字的表之外,这实际上实现了相同的结果。即使我们能够在表定义中获取identity关键字,Oracle也只是在后台创建了自己的序列,以便在每次插入记录时使用。使用序列标识而不是序列,也避免了双DB调用以插入新行。使用identity-sequence,插入DML是一个单独的调用,如下所示:
insert into person (person_key, version, home_address_id, name) values (person_seq.nextval, ?, ?, ?)
使用发电机:'序列'新记录插入成为两个DB调用:
select person_seq.nextval from dual;
insert into person (person_key, version, home_address_id, name) values (?, ?, ?, ?)
所以我看到的唯一缺点就是身份序列'过度身份'只是Oracle不会自动跟踪哪个序列用于哪个表,并在insert语句中没有提供键值时自动使用它。但即便如此,也许可以通过一个插入触发器来处理,此时如果Hibernate 4支持生成器,那么你可能几乎就是你所在的位置:identity。
答案 1 :(得分:0)
Hibernate 5 确实拥有Oracle 12c Dialect,特别添加了“identity”支持:org.hibernate.dialect.Oracle12cDialect。所以要么使用Hibernate 5,要么写一个基于12c的自定义Dialect for Hibernate 4。