После переноса 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 года. Он говорит, что Индекс является глобальным и должен иметь уникальное имя, но это не Это не имеет никакого смысла, потому что, как я упоминал ранее, индекс относится к таблице, а не к схеме.
А вот доказательство того, что в БД индекс создается для таблицы
Но если я создам одинаковое имя индекса для обеих таблиц, то индекс будет создан только в первой таблице.