H2 数据库:使用 jdbcTemplate 插入记录时,列 "ID" 不允许为 NULL
H2 database: NULL not allowed for column "ID" when inserting record using jdbcTemplate
我使用 hibernate 的 hbm2ddl 自动生成模式。这是我的域名:
@Entity
public class Reader {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Long id;
@Column(nullable=false,unique=true)
String name;
@Enumerated(EnumType.STRING)
Gender gender;
int age;
Date registeredDate = new Date();
// getter and setter ...
}
当我使用 hibernate 保存 reader
时,它按预期工作正常,因为它为 reader
生成了一个 id。但是当我用jdbcTemplate插入一条纯SQL的记录时,报错:
org.springframework.dao.DataIntegrityViolationException: StatementCallback;
SQL [insert into reader(name,gender,age) values('Lily','FEMALE',21)];
NULL not allowed for column "ID";
SQL statement:insert into reader(name,gender,age) values('Lily','FEMALE',21) [23502-192];
nested exception is org.h2.jdbc.JdbcSQLException: NULL not allowed for column "ID";
SQL statement: insert into reader(name,gender,age) values('Lily','FEMALE',21) [23502-192]
如何解决?
- 我调试发现hb2ddl生成的DDL是
create table Book (id bigint not null, author varchar(255), name varchar(255), price double not null, type varchar(255), primary key (id))
。 hiberate 似乎以自己的方式处理 id 策略,但是如何处理?
-
@GeneratedValue(strategy=GenerationType.AUTO)
应该在 DDL 的语句中生成 auto increment
但我没有找到。我错过了吗?
尝试使用 strategy=GenerationType.IDENTITY
而不是 strategy=GenerationType.AUTO
也可能是错的hibernate.dialect
试试
hibernate.dialect=org.hibernate.dialect.H2Dialect
Hibernate 5.2.x (Spring Boot 2.x) 如果 DB 支持,则更改序列的默认策略。因此,使用 strategy=GenerationType.AUTO
,创建 hibernate_sequence
,但 id
不会自动递增,基于此序列,必须是:
create table users (id integer not null, ...)
而不是
create table table_name(id int default hibernate_sequence.nextval primary key, ...);
(参见 HHH-13268)。有几种解决方法:
- 将
@GeneratedValue
更改为strategy = GenerationType.IDENTITY
- 设置
spring.jpa.properties.hibernate.id.new_generator_mappings=false
(spring-引导别名spring.jpa.hibernate.use-new-id-generator-mappings
)
- 使用 nextval 插入:
INSERT INTO TABLE(ID, ...) VALUES (hibernate_sequence.nextval, ...)
如果您使用的是 H2 依赖版本:“2.0.202”或更高版本,其他 2 个方法可能有效。
1:使用H2版本:“1.4.200”('com.h2database:h2:1.4.200')
2:将“;MODE=LEGACY”附加到 JDBC url (test case -> jdbc:h2:mem:test;MODE=LEGACY
)
这已在 Hibernate 5.6.5 (Spring Boot 2.6.4) 中得到解决,因此 H2 版本 2.0.202(或更高版本)可以再次运行。
我使用 hibernate 的 hbm2ddl 自动生成模式。这是我的域名:
@Entity
public class Reader {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Long id;
@Column(nullable=false,unique=true)
String name;
@Enumerated(EnumType.STRING)
Gender gender;
int age;
Date registeredDate = new Date();
// getter and setter ...
}
当我使用 hibernate 保存 reader
时,它按预期工作正常,因为它为 reader
生成了一个 id。但是当我用jdbcTemplate插入一条纯SQL的记录时,报错:
org.springframework.dao.DataIntegrityViolationException: StatementCallback;
SQL [insert into reader(name,gender,age) values('Lily','FEMALE',21)];
NULL not allowed for column "ID";
SQL statement:insert into reader(name,gender,age) values('Lily','FEMALE',21) [23502-192];
nested exception is org.h2.jdbc.JdbcSQLException: NULL not allowed for column "ID";
SQL statement: insert into reader(name,gender,age) values('Lily','FEMALE',21) [23502-192]
如何解决?
- 我调试发现hb2ddl生成的DDL是
create table Book (id bigint not null, author varchar(255), name varchar(255), price double not null, type varchar(255), primary key (id))
。 hiberate 似乎以自己的方式处理 id 策略,但是如何处理? -
@GeneratedValue(strategy=GenerationType.AUTO)
应该在 DDL 的语句中生成auto increment
但我没有找到。我错过了吗?
尝试使用 strategy=GenerationType.IDENTITY
而不是 strategy=GenerationType.AUTO
也可能是错的hibernate.dialect 试试
hibernate.dialect=org.hibernate.dialect.H2Dialect
Hibernate 5.2.x (Spring Boot 2.x) 如果 DB 支持,则更改序列的默认策略。因此,使用 strategy=GenerationType.AUTO
,创建 hibernate_sequence
,但 id
不会自动递增,基于此序列,必须是:
create table users (id integer not null, ...)
而不是
create table table_name(id int default hibernate_sequence.nextval primary key, ...);
(参见 HHH-13268)。有几种解决方法:
- 将
@GeneratedValue
更改为strategy = GenerationType.IDENTITY
- 设置
spring.jpa.properties.hibernate.id.new_generator_mappings=false
(spring-引导别名spring.jpa.hibernate.use-new-id-generator-mappings
) - 使用 nextval 插入:
INSERT INTO TABLE(ID, ...) VALUES (hibernate_sequence.nextval, ...)
如果您使用的是 H2 依赖版本:“2.0.202”或更高版本,其他 2 个方法可能有效。
1:使用H2版本:“1.4.200”('com.h2database:h2:1.4.200')
2:将“;MODE=LEGACY”附加到 JDBC url (test case -> jdbc:h2:mem:test;MODE=LEGACY
)
这已在 Hibernate 5.6.5 (Spring Boot 2.6.4) 中得到解决,因此 H2 版本 2.0.202(或更高版本)可以再次运行。