使用标识PK为Oracle 12c配置Grails 3.0.9?

时间:2015-11-13 16:58:20

标签: gorm grails-domain-class oracle12c grails-3.0 hibernate-5.x

我正在尝试映射我的域对象以使用新的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表定义?

2 个答案:

答案 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。