Hibernate Jpa-主键(Sequence)上的约束冲突异常



我在应用程序中使用Hibernate JPA。我有一个表,它有一个主键(序列(。服务将记录插入该表。

版本:Oracle 12c

方言:org.hibernate.Dialect.Oracle10g方言

问题:

在负载测试过程中,我们面临问题(SEQUENCE Key上的唯一约束冲突(。

问题:

  1. 此问题并非一直发生。但仅在负载测试期间。有人能检查并帮助使用线程安全生成器吗?

  2. 是DB端的序列定义问题还是Java端的问题?

DB序列:

CREATE SEQUENCE MY_SEQ    
START WITH 1
INCREMENT BY 1
NOMINVALUE
NOMAXVALUE
CACHE 30
NOORDER;
CREATE TABLE MY_TABLE    (  
MY_PRIMARY_KEY INT default MY_SEQ.nextval NOT NULL,
VALUE_COL VARCHAR2(10) NULL       
);

实体:

public class MyTableEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "MY_PRIMARY_KEY")
@GenericGenerator(
        name = "mySequenceGenerator",
        strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
        parameters = {
                @Parameter(name = "sequence_name", value = "SEQUENCE MY_SEQ"),
                @Parameter(name = "increment_size", value = "1")
        }
)
@GeneratedValue(generator = "mySequenceGenerator")
private long myPrimaryKey;
@Column(name = "VALUE")
private String value;
}

Oracle 10方言

对于Oracle10gDialect使用此配置

@Id
@Column(name = "MY_PRIMARY_KEY")
@GeneratedValue(strategy=GenerationType.AUTO)
Long myPrimaryKey;

Hibernate创建一个表和一个序列:

create table MY_TABLE (
MY_PRIMARY_KEY number(19,0) not null, 
VALUE varchar2(255 char), 
primary key (MY_PRIMARY_KEY))
create sequence hibernate_sequence 

在存储时,首先获取新的序列ID,然后将其传递到INSERT语句中

select hibernate_sequence.nextval from dual
insert into MY_TABLE (VALUE, MY_PRIMARY_KEY) values (?, ?)

甲骨文12方言

如果您使用本机支持IDENTITY columnOracle12,则最好升级到Oracle12cDialect(请注意,这需要Hibernate 5.3(

strategy设置为GenerationType.IDENTITY

@Id
@Column(name = "MY_PRIMARY_KEY", updatable = false, nullable = false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
Long myPrimaryKey;

创建了下表——重要的部分是generated as identity,它提供了独特的速度。请注意,不需要创建显式sequence,它是在内部管理的。

create table MY_TABLE (
MY_PRIMARY_KEY number(19,0) generated as identity, 
VALUE varchar2(255 char), 
primary key (MY_PRIMARY_KEY))

存储时,INSERT中没有传递任何ID,它由Oracle分配并返回到会话

insert into MY_TABLE (VALUE) values (?) RETURNING MY_PRIMARY_KEY INTO ? 

请注意,与Oracle10相反,您可以节省一次数据库往返行程。

将long更改为long

因为如果使用long,它(默认情况下(为0。任何生成器都不允许更改现有值!

https://docs.oracle.com/javaee/7/api/javax/persistence/GeneratedValue.html

最新更新