Миграция Spring Boot 2 вызывает проблему индекса на H2 с HikariCP - PullRequest
1 голос
/ 27 января 2020

После переноса Spring Boot в нашем приложении с 1.5.13.RELEASE на 2.1.8.RELEASE мы заметили, что наши тесты выдают ошибки о создании индекса, но все еще проходят,

В нашем производстве мы используем PostgresSQL и в наших тестах мы используем H2 DB version: 1.4.200

После изучения ошибки мы заметили следующее поведение:

Предположим, что это наши сущности внутри приложения:

@Entity
@Table(indexes = @Index(columnList = "name", name = "name"))
public class Cat {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    private String name;
}

@Entity
@Table(indexes = @Index(columnList = "name", name = "name"))
public class Dog {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    private String name;
}

Тогда, если мы запускаем тесты с h2, возникает исключение:

Caused by: org.h2.jdbc.JdbcSQLException: Index "NAME" already exists; SQL statement:
create index name on dog (name) [42111-196]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.message.DbException.get(DbException.java:179) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.message.DbException.get(DbException.java:155) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.ddl.CreateIndex.update(CreateIndex.java:76) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.CommandContainer.update(CommandContainer.java:101) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.command.Command.executeUpdate(Command.java:260) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:192) ~[h2-1.4.196.jar:1.4.196]
    at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:164) ~[h2-1.4.196.jar:1.4.196]
    at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95) ~[HikariCP-3.2.0.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-3.2.0.jar:na]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
    ... 34 common frames omitted

Это наши application.properties:

server.port=9090

########## DATABASE CONFIGURATION ##############
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=test
spring.datasource.password=test

spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

Даже это Index в базе данных должно создаваться для каждой таблицы, а не для схемы, поэтому индекс не должен существовать, если мы запускаем одни и те же сущности с Postgres, то ошибка не возникает,

I'm интересно, это ошибка в H2 driver? или что мы делаем что-то не так?

Изучив немного больше, я нашел этот вопрос от 2010 года. Он говорит, что Индекс является глобальным и должен иметь уникальное имя, но это не Это не имеет никакого смысла, потому что, как я упоминал ранее, индекс относится к таблице, а не к схеме.

А вот доказательство того, что в БД индекс создается для таблицы enter image description here

Но если я создам одинаковое имя индекса для обеих таблиц, то индекс будет создан только в первой таблице.

...