1

我正在尝试映射我的域对象以使用新的 Oracle 12c 身份类型主键,也就是其他一些系统中的自动增量。

Hibernate 4没有Oracle12cDialect,它只有Oracle10gDialect。

Oracle10gDialect 有一个名为 supportsIdentityColumns() 的方法,该方法被硬编码为返回 false,因此将我的 GORM 域对象映射到 generator:"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 表定义一起使用?

4

2 回答 2

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 中使用标识关键字创建表之外,这实际上实现了相同的结果。即使我们能够在表定义中获得标识关键字,Oracle 也会在后台创建自己的序列,以便在每次插入记录时使用。使用序列标识而不是序列,也避免了插入新行的双 DB 调用。使用身份序列插入 DML 是这样的单个调用:

insert into person (person_key, version, home_address_id, name) values (person_seq.nextval, ?, ?, ?)

使用 generator: 'sequence' 新记录插入成为两个数据库调用,如下所示:

select person_seq.nextval from dual;
insert into person (person_key, version, home_address_id, name) values (?, ?, ?, ?)

因此,我认为“identity-sequence”优于“identity”的唯一缺点就是 Oracle 不会自动跟踪用于哪个表的序列,并在插入语句中没有提供键值时自动使用它。但即使这样也可能由插入前触发器处理,此时如果 Hibernate 4 支持生成器:身份,那么您可能几乎完全处于您的位置。

于 2015-11-19T15:35:20.673 回答
0

Hibernate 5确实有一个 Oracle 12c 方言,特别是添加了“身份”支持:org.hibernate.dialect.Oracle12cDialect。因此,要么使用 Hibernate 5,要么为 Hibernate 4 编写基于 12c 的自定义方言。

于 2015-11-13T20:41:15.900 回答