使用带有H2的序列导致无法找到要检索的行

时间:2017-05-26 01:18:09

标签: spring postgresql hibernate jpa spring-boot

我们的生产数据库是Postgres。对于表,我们使用序列为其中一个非id列生成数据。此序列的定义如下,并从Flyway迁移执行:

create sequence check_number_seq minvalue 1000 maxvalue 9999 cycle;
alter table guest_check alter column check_number set default nextval('check_number_seq'::regclass);

实体的列定义为:

@Generated(GenerationTime.INSERT)
@Column(nullable = false, insertable=false, updatable=false)
private Integer checkNumber;

当对阵Postgres时,这一切都很有效。不幸的是,它在对H2运行时不起作用,这是我们用于测试的。我添加了一个@Sql脚本来运行测试,并使用稍微修改的序列创建版本来处理H2:

create sequence IF NOT EXISTS check_number_seq minvalue 1000 maxvalue 9999 cycle;
alter table guest_check alter column check_number set default nextval('check_number_seq');

但是当测试针对表运行时,它们都会以相同的错误失败:

org.springframework.orm.jpa.JpaSystemException: Unable to locate row for retrieval of generated properties: [com.foo.entity.thing.GuestCheck#1000]; 

我尝试将H2模式和方言更改为Postgres,但它无法解决问题。我们正在使用 Spring Boot 1.5.1

现在的工作是我们正在对Postgres DB进行测试,但我真的想回到H2以便于使用。

1 个答案:

答案 0 :(得分:0)

我为非id列(http://peter.risko.hu/java_incubator/h2_sequence_for_non_id_jpa.zip)使用序列构建了一个最小测试。

但是,我无法用它重现问题。

这是我的DAO:

@Entity
@Table(name = "guest_check")
public class GuestCheck {

    @Id
    @Column(nullable = false)
    private String id;

    @Generated(GenerationTime.INSERT)
    @Column(nullable = false, insertable = false, updatable = false, name = "check_number")
    private Integer checkNumber;

    public Integer getCheckNumber() {
        return checkNumber;
    }

    public void setCheckNumber(Integer checkNumber) {
        this.checkNumber = checkNumber;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "guestCheck, id: " + id + ", checkNo.:" + checkNumber;
    }
}

这是我的考验:

@Test
public void test() {
    for (int i = 0; i < 10; i++) {
        GuestCheck guestCheck = new GuestCheck();
        guestCheck.setId("id " + i);
        guestCheckRepository.save(guestCheck);
    }

    List<GuestCheck> guestChecks = guestCheckRepository.findAll();
    for (GuestCheck guestCheck : guestChecks) {
        System.out.println("guestCheck: " + guestCheck);
    }
}

这是输出:

guestCheck: guestCheck, id: id 0, checkNo.:1000
guestCheck: guestCheck, id: id 1, checkNo.:1001
guestCheck: guestCheck, id: id 2, checkNo.:1002
guestCheck: guestCheck, id: id 3, checkNo.:1003
guestCheck: guestCheck, id: id 4, checkNo.:1004
guestCheck: guestCheck, id: id 5, checkNo.:1005
guestCheck: guestCheck, id: id 6, checkNo.:1006
guestCheck: guestCheck, id: id 7, checkNo.:1007
guestCheck: guestCheck, id: id 8, checkNo.:1008
guestCheck: guestCheck, id: id 9, checkNo.:1009

也许我误会了什么?