Hibernate,liquibase和hsqldb的Id生成问题

时间:2013-05-20 07:39:48

标签: java hibernate hsqldb liquibase

我使用liquibase创建了一个表:

<createTable tableName="employees">
    <column name="id" type="bigint">
        <constraints primaryKey="true" nullable="false"/>
    </column>
    <column name="name" type="varchar(50)">
        <constraints nullable="false"/>
    </column>
</createTable>

生成以下sql ddl查询:

CREATE TABLE employees (id BIGINT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT PK_EMPLOYEES PRIMARY KEY (id));

相应的实体:

@Entity
@Table(name="employees")
public class EmployeeAccessProperty ...
    @Id
    @GeneratedValue
    public long getId() {
        return id;
    }
...

现在,当我尝试通过JPA实现保存它时,会生成sql查询以插入数据:

Hibernate: insert into employees (id, name) values (default, ?)
2013-05-20T14:29:22.525+0700  WARN  SQL Error: -5544, SQLState: 42544
2013-05-20T14:29:22.526+0700  ERROR  DEFAULT keyword cannot be used as column has no DEFAULT

我预计,当我没有指定id生成策略时,Hibernate会根据提供者选择最好的一个。我不明白为什么ID生成尝试使用默认值。我不确定,哪一方负责错误:hibernate,liqubase或hsqldb。

我该怎么做才能解决问题?请帮帮我。

2 个答案:

答案 0 :(得分:4)

您没有告诉数据库必须自动生成主键。以这种方式创建你的表:

CREATE TABLE employees (id BIGINT GENERATED BY DEFAULT AS IDENTITY, name VARCHAR(50) NOT NULL, CONSTRAINT PK_EMPLOYEES PRIMARY KEY (id));

答案 1 :(得分:3)

Hibernate确实根据方言选择最合适的策略。由于HSQLDB支持标识列,因此它使用此策略。此策略假设ID列由数据库自动生成,并且您没有将其定义为此类,因此它不起作用。

将列定义为generated by default as identity,一切都应该没问题。或者使用序列或表格选择另一代策略(您必须在数据库中定义)。