Oracle 自动生成的主键,在我的实体中是 @Id

Posted

技术标签:

【中文标题】Oracle 自动生成的主键,在我的实体中是 @Id【英文标题】:Primary key auto generated by Oracle, which is @Id in my Entity 【发布时间】:2019-02-06 11:47:48 【问题描述】:

我有一个实体,其 @Id 列的值是从数据库端的序列为每个插入生成的,即我不必在执行插入时从我的服务中填充此值。

如果我不填充值,JPA/Hibernate 会抱怨我的 @Id 不能为空。如果我使用 Oracle 序列生成器并在插入时为我的 @Id 填充一个值,我的数据库会抱怨说“无法插入生成的始终标识列”

我正在使用 Oracle10g 方言。

我尝试了 GenerationType 的所有策略 - AUTO、IDENTITY、SEQUENCE、TABLE,但没有提及任何序列。

@GeneratedValue(strategy=GenerationType.SEQUENCE)
@Column(name = "INTERACTION_ID", unique = true, nullable = false)
public BigDecimal getINTERACTION_ID() 
    return INTERACTION_ID;

很遗憾,我的数据库团队不同意更改此列的限制。 我正在寻找一个选项,我可以通过我的持久对象插入数据,而不必为 @Id 列填充值并让数据库为我自动插入。

这是我的 DDL 的一部分:

CREATE TABLE MY_SCHEMA.MY_TABLE
(
INTERACTION_ID NUMBER(28, 0) DEFAULT "MY_SCHEMA"."ISEQ$$_85362".nextval NOT 
NULL,
...,
...)

请帮帮我。

【问题讨论】:

JPA 注释中序列定义的其余部分在哪里?对任何 JPA 文档的简单检查都会告诉您如何做到这一点。发布列的 DDL 使用 IDENTITY 生成器会出现什么错误? @Sikorski - java.lang.IllegalArgumentException: org.hibernate.dialect.Oracle10gDialect 不支持身份密钥生成 那么你应该改变你的表 DDL,制定一个明确的序列并且不要使用默认子句。在您的 Java 代码中使用 SequenceGenerator 和策略 SEQUENCE,在此处给出序列名称。 【参考方案1】:

尝试将可插入和可更新设置为 false 以避免 Hibernate 尝试设置 id。

@Id
@Column(name = "INTERACTION_ID", unique = true, nullable = false, insertable = false, updatable = false)
public BigDecimal getINTERACTION_ID() 
    return INTERACTION_ID;

【讨论】:

没用。它说“org.hibernate.id.IdentifierGenerationException:必须在调用 save() 之前手动分配此类的 id” 不。它说“java.lang.IllegalArgumentException:org.hibernate.dialect.Oracle10gDialect 不支持身份密钥生成”。我也尝试过 SEQUUENCE、TABLE 和 AUTO。 在那种情况下,我认为这是不可能的。 至少 insertable=false 方法为我节省了一天,当时 Oracle 拒绝插入错误消息“...GENERATED ALWAY ...”

以上是关于Oracle 自动生成的主键,在我的实体中是 @Id的主要内容,如果未能解决你的问题,请参考以下文章

oracle:物化视图中的主键列

oracle怎么查询所有的表有没有主键

mysql的主键是自动增长的,oracle的主键是起啥作用的

实体框架中的 Oracle 物化视图问题

如何将房间自动生成的主键作为外键添加到另一个实体

ORACLE: 查询(看)表的主键外键唯一性约束和索引