【问题标题】:H2 database: NULL not allowed for column "ID" when inserting record using jdbcTemplateH2 数据库:使用 jdbcTemplate 插入记录时,列“ID”不允许为 NULL
【发布时间】:2016-12-29 21:31:58
【问题描述】:

我使用 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 ...
}

当我使用休眠来保存 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]

如何解决?

  1. 我调试发现生成的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))。似乎休眠模式以自己的方式处理 id 策略,但如何?
  2. @GeneratedValue(strategy=GenerationType.AUTO) 应该在 DDL 的语句中生成 auto increment,但我没有找到。我错过了吗?

【问题讨论】:

    标签: hibernate h2


    【解决方案1】:

    尝试使用strategy=GenerationType.IDENTITY 而不是strategy=GenerationType.AUTO

    也可能是错误的hibernate.dialect 试试

    hibernate.dialect=org.hibernate.dialect.H2Dialect
    

    【讨论】:

    • 谢谢。当我更改为strategy=GenerationType.IDENTITY 时,它可以工作。 DDL 子句现在更改为create table Reader (id bigint generated by default as identity, age integer not null, gender varchar(255), name varchar(255) not null, registeredDate timestamp, primary key (id))。那么IDENTITYAUTO 这里有什么区别呢?
    • IDENTITY 表示持久性提供程序必须使用数据库标识列为实体分配主键。 AUTO 指示持久性提供程序应该为特定数据库选择适当的策略。 AUTO 生成策略可能期望数据库资源存在,或者它可能会尝试创建一个。如果供应商不支持模式生成或无法在运行时创建模式资源,供应商可能会提供有关如何创建此类资源的文档。
    【解决方案2】:

    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-boot别名spring.jpa.hibernate.use-new-id-generator-mappings
    • 用 nextval 插入:INSERT INTO TABLE(ID, ...) VALUES (hibernate_sequence.nextval, ...)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 1970-01-01
      • 2013-11-15
      • 2013-01-10
      • 1970-01-01
      • 2018-04-16
      相关资源
      最近更新 更多