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的主要内容,如果未能解决你的问题,请参考以下文章