借助使用MySQL的DataJpaTest存储库测试,Hibernate不会将用户设置为在H2 DB中自动递增

时间:2019-07-12 18:52:28

标签: java mysql hibernate jpa h2

我正在尝试使用DataJpaTest测试我的Spring Boot存储库。我正在使用MySQL,所以我所有的模型都使用IDENTITY来生成ID:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

但是从下面的屏幕快照中可以看到,当我运行测试时,Hibernate会为除用户和属性外的所有模型的ID设置“默认情况下作为身份生成”:

screenshot of table generation

这使得我无法在测试中创建用户(或属性),因为GenerationType.IDENTITY设置始终将id设置为null,然后再将其发送到db,这会导致以下错误:

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

有人知道为什么会这样吗?而且,当然,比为什么更重要的是我该怎么做才能解决它? :)

更新 为了简化问题并针对我尝试过的不同事情提供不同的错误...

我的DataJpaTests使用的是H2,我猜它是根据代码自动生成db结构的。我真正的数据库是MYSQL,它是在一个单独的项目中生成的。

场景1: 当我将GenerationType设置为IDENTITY时,实时数据库可以工作,但测试数据库却给了我could not execute statement; SQL [n/a]; constraint [null]

方案2: 当我将GenerationType设置为AUTO时,测试数据库可以工作,但实时数据库却给了我Table 'tablename.hibernate_sequence' doesn't exist

方案3: 试图使MYSQL与GenerationType AUTO一起使用。在关于如何告诉Hibernate默认MYSQL标识而不是表的大量搜索中,我没有发现任何东西。我发现有很多说法是永远不要使用表,并且不更改Hibernate源代码就无法覆盖它。这是一堆BS,使我想知道Hibernate开发人员正在吸烟。

方案4: 试图使H2与GenerationType IDENTITY一起使用。我在以下方面很幸运:

  1. spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MYSQL放入test.properties文件中。
  2. @TestPropertySource(locations= "classpath:test.properties")@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)注释我的Test类

这摆脱了空约束错误,但是我现在得到了The database returned no natively generated identity value。据推测,这是因为,尽管实际的SQL代码具有id的auto_increment值,但是用于生成H2表的任何魔术手段都无法达到目的。

附录:令所有这些感到沮丧的是,它对于大多数表来说都可以正常工作。在我的数据库中的20多个表中,除了两个以外的所有表都可以使用IDENTITY自动生成并递增其ID。它们中的一些会起作用,而有些则不会起作用,这根本没有道理。

2 个答案:

答案 0 :(得分:1)

问题是另一个带有@Table(name = "user")作为注释的模型。该模型还定义了Id列,但没有生成值。由于冲突,Hibernate选择了那个来定义ID。

答案 1 :(得分:-1)

MySql与

搭配使用效果更好
@GeneratedValue(strategy = GenerationType.AUTO) 

它也更好,因为它在大多数RDBMS中都会产生自动递增的主键