使用 postgres table 序列而不是共享 hibernate_sequence
Use postgres table sequence instead of sharing hibernate_sequence
当我用 table 做任何事情时,它总是显示错误:
Hibernate: select nextval ('hibernate_sequence')
2019-07-20 16:15:44.877 WARN 58376 --- [nio-9000-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42P01
2019-07-20 16:15:44.877 ERROR 58376 --- [nio-9000-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist
我不想使用 hibernate_sequence 在 table 之间共享 id 序列,但想为每个 table 定义 id seq 并分别使用它们。
我使用 Spring Boot 2.1.6.RELEASE、Spring Data JPA (Hibernate 5.3.10.Final) 和 Postgres 11.2,并使用 BigSerial 定义 id 字段输入并希望在各自的实体 class.
中使用每个 table 的 id 序列
演示代码库在这里:https://github.com/Redogame/share_hibernate_sequence
创建用户 table(使用身份作为 table 名称,因为 user 是 Postgres 保留关键字)。
通过定义bigserial类型的id,Postgres会自动创建一个identity_id_seq,我验证了identity_id_seq已经创建成功。
create table identity
(
id bigserial not null
constraint identity_pkey
primary key,
name varchar(255) not null
constraint identity_name_key
unique
constraint identity_name_check
check ((name)::text <> ''::text),
created_date timestamp not null,
created_by_id bigint not null
constraint identity_identity_id_fk
references identity,
last_modified_date timestamp not null,
last_modified_by_id bigint not null
constraint identity_identity_id_fk_2
references identity,
version bigint not null
);
指定序列生成器以使用此 ID 序列:
@Table(name = "identity")
public class UserEntity extends Auditable<Long> {
@Id
@SequenceGenerator(name="identity_id_seq", sequenceName = "identity_id_seq", initialValue=1, allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="identity_id_seq")
private Long id;
但是没用。我也试过配置 spring.jpa.hibernate.use-new-id-generator-mappings
和 spring.jpa.properties.hibernate.id.new_generator_mappings
,但还是不行。
spring:
jpa:
hibernate:
use-new-id-generator-mappings: false
properties:
hibernate:
id:
new_generator_mappings: false
我预计不会使用 hibernate_sequence,即:不要执行 select nextval ('hibernate_sequence') before/after 任何 SQL 语句。
尝试以下步骤
如果不存在则创建序列 manual_seq;
更改创建 table 脚本
create table identity
(
id integer NOT NULL DEFAULT nextval('manual_seq'::regclass),
name varchar(255) not null
constraint identity_name_key
unique
constraint identity_name_check
check ((name)::text <> ''::text),
created_date timestamp not null,
created_by_id bigint not null,
last_modified_date timestamp not null,
last_modified_by_id bigint not null,
version bigint not null,
CONSTRAINT manual_seq_pkey PRIMARY KEY (id)
);
出于测试目的,我删除了外键约束。
- 更新实体映射
@Entity
@Table(name = "identity")
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserEntity extends Auditable<Long> {
@Id
@SequenceGenerator(name="manual-seq", sequenceName = "manual_seq",allocationSize = 1)
@GeneratedValue(generator="manual-seq")
private Long id;
@Basic
@Column(name = "name", nullable = false)
private String name;
@MappedSuperclass
@JsonIgnoreProperties({"new", "createdDate", "createdById", "lastModifiedDate", "lastModifiedById", "version"})
abstract class Auditable<PK extends Serializable>{
@NotAudited
@CreatedDate
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
@NotAudited
@CreatedBy
private Long createdById;
@LastModifiedDate
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
@LastModifiedBy
private Long lastModifiedById;
@NotAudited
@Version
private Long version;
还原 spring.jpa.hibernate.use-new-id-generator-mappings
问题是扩展 AbstractPersistable 因为没有使用哪个数据库序列。另请注意,出于测试目的,我已删除审核。
我也遇到了同样的问题。我明确设置了 spring.jpa.properties.hibernate.id.new_generator_mappings=false
但 select nextval ('hibernate_sequence')
仍然是 Hibernate 运行。
我发现当我们使用@GeneratedValue
注解而不设置策略时,它默认为AUTO
,这意味着,Hibernate会尝试使用hibernate_sequence
生成ID值并且那么它将失败,因为它不存在于数据库中。
所以,我做了 @GeneratedValue (strategy = GenerationType.IDENTITY)
并再次尝试。在这种情况下,ID 值是由我在数据库中的标识列(自动递增的主键)生成的,而不是由 hibernate_sequence
.
生成的
create table users (id serial not null, name varchar(250), primary key (id));
当我用 table 做任何事情时,它总是显示错误:
Hibernate: select nextval ('hibernate_sequence')
2019-07-20 16:15:44.877 WARN 58376 --- [nio-9000-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42P01
2019-07-20 16:15:44.877 ERROR 58376 --- [nio-9000-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist
我不想使用 hibernate_sequence 在 table 之间共享 id 序列,但想为每个 table 定义 id seq 并分别使用它们。
我使用 Spring Boot 2.1.6.RELEASE、Spring Data JPA (Hibernate 5.3.10.Final) 和 Postgres 11.2,并使用 BigSerial 定义 id 字段输入并希望在各自的实体 class.
中使用每个 table 的 id 序列演示代码库在这里:https://github.com/Redogame/share_hibernate_sequence
创建用户 table(使用身份作为 table 名称,因为 user 是 Postgres 保留关键字)。 通过定义bigserial类型的id,Postgres会自动创建一个identity_id_seq,我验证了identity_id_seq已经创建成功。
create table identity
(
id bigserial not null
constraint identity_pkey
primary key,
name varchar(255) not null
constraint identity_name_key
unique
constraint identity_name_check
check ((name)::text <> ''::text),
created_date timestamp not null,
created_by_id bigint not null
constraint identity_identity_id_fk
references identity,
last_modified_date timestamp not null,
last_modified_by_id bigint not null
constraint identity_identity_id_fk_2
references identity,
version bigint not null
);
指定序列生成器以使用此 ID 序列:
@Table(name = "identity")
public class UserEntity extends Auditable<Long> {
@Id
@SequenceGenerator(name="identity_id_seq", sequenceName = "identity_id_seq", initialValue=1, allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="identity_id_seq")
private Long id;
但是没用。我也试过配置 spring.jpa.hibernate.use-new-id-generator-mappings
和 spring.jpa.properties.hibernate.id.new_generator_mappings
,但还是不行。
spring:
jpa:
hibernate:
use-new-id-generator-mappings: false
properties:
hibernate:
id:
new_generator_mappings: false
我预计不会使用 hibernate_sequence,即:不要执行 select nextval ('hibernate_sequence') before/after 任何 SQL 语句。
尝试以下步骤
如果不存在则创建序列 manual_seq;
更改创建 table 脚本
create table identity
(
id integer NOT NULL DEFAULT nextval('manual_seq'::regclass),
name varchar(255) not null
constraint identity_name_key
unique
constraint identity_name_check
check ((name)::text <> ''::text),
created_date timestamp not null,
created_by_id bigint not null,
last_modified_date timestamp not null,
last_modified_by_id bigint not null,
version bigint not null,
CONSTRAINT manual_seq_pkey PRIMARY KEY (id)
);
出于测试目的,我删除了外键约束。
- 更新实体映射
@Entity
@Table(name = "identity")
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserEntity extends Auditable<Long> {
@Id
@SequenceGenerator(name="manual-seq", sequenceName = "manual_seq",allocationSize = 1)
@GeneratedValue(generator="manual-seq")
private Long id;
@Basic
@Column(name = "name", nullable = false)
private String name;
@MappedSuperclass
@JsonIgnoreProperties({"new", "createdDate", "createdById", "lastModifiedDate", "lastModifiedById", "version"})
abstract class Auditable<PK extends Serializable>{
@NotAudited
@CreatedDate
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
@NotAudited
@CreatedBy
private Long createdById;
@LastModifiedDate
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
@LastModifiedBy
private Long lastModifiedById;
@NotAudited
@Version
private Long version;
还原 spring.jpa.hibernate.use-new-id-generator-mappings
问题是扩展 AbstractPersistable 因为没有使用哪个数据库序列。另请注意,出于测试目的,我已删除审核。
我也遇到了同样的问题。我明确设置了 spring.jpa.properties.hibernate.id.new_generator_mappings=false
但 select nextval ('hibernate_sequence')
仍然是 Hibernate 运行。
我发现当我们使用@GeneratedValue
注解而不设置策略时,它默认为AUTO
,这意味着,Hibernate会尝试使用hibernate_sequence
生成ID值并且那么它将失败,因为它不存在于数据库中。
所以,我做了 @GeneratedValue (strategy = GenerationType.IDENTITY)
并再次尝试。在这种情况下,ID 值是由我在数据库中的标识列(自动递增的主键)生成的,而不是由 hibernate_sequence
.
create table users (id serial not null, name varchar(250), primary key (id));