我在应用程序中使用了Hibernate JPA。我有一个具有主键(序列)的表。服务将记录插入到该表中。
版本:Oracle 12c
方言:org.hibernate.dialect.Oracle10gDialect
问题:
在负载测试过程中,我们遇到问题(在SEQUENCE键上违反唯一约束)。
问题:
此问题并非一直存在。但仅在负载测试期间。有人可以检查并帮助使用线程安全生成器吗?
是DB端序列定义问题还是Java端?
数据库序列:
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;
}
答案 0 :(得分:0)
因为使用long类型,所以它(默认情况下)为0。不允许任何生成器更改现有值!
https://docs.oracle.com/javaee/7/api/javax/persistence/GeneratedValue.html
答案 1 :(得分:0)
对于 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 (?, ?)
如果您使用本机支持IDENTITY column
的 Oracle 12 ,则最好升级到 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 ,但该ID由Oracle分配并返回到会话
insert into MY_TABLE (VALUE) values (?) RETURNING MY_PRIMARY_KEY INTO ?
请注意,与Oracle 10相反,您节省了一次往返数据库的时间。