Liquibase 导致 "could not prepare statement; SQL" 仅与 H2
Liquibase causes "could not prepare statement; SQL" only with H2
我在 Spring 引导应用程序中集成了 Liquibase。将它与 MariaDB 一起使用效果很好。
对于单元和集成测试,我使用 H2 内存数据库。 运行 测试时会导致以下异常:
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [select user0_.id as id1_19_0_, user0_.created_at as created_2_19_0_, user0_.updated_at as updated_3_19_0_, user0_.version as version4_19_0_, user0_.activated as activate5_19_0_, user0_.birthday as birthday6_19_0_, user0_.email as email7_19_0_, user0_.firstname as firstnam8_19_0_, user0_.force_password_change as force_pa9_19_0_, user0_.password_hash as passwor10_19_0_, user0_.role as role11_19_0_, user0_.surname as surname12_19_0_ from users user0_ where user0_.id=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259) ~[spring-orm-5.3.19.jar:5.3.19]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233) ~[spring-orm-5.3.19.jar:5.3.19]
我的产品配置(工作):
spring:
main:
allow-bean-definition-overriding: true
datasource:
url: jdbc:mariadb://localhost:3307/testdb
username: user
password: psw
jpa:
generate-ddl: false
database-platform: org.hibernate.dialect.MariaDB103Dialect
sql:
init:
mode: never
liquibase:
enabled: true
change-log: classpath:db/db.changelog-master.yaml
我的测试配置(不工作):
spring:
main:
allow-bean-definition-overriding: true
datasource:
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;NON_KEYWORDS=user
username: sa
driver-class-name: org.h2.Driver
password: password
jpa:
database-platform: org.hibernate.dialect.H2Dialect
generate-ddl: false
sql:
init:
mode: never
liquibase:
change-log: classpath:db/db.changelog-master.yaml
enabled: true
test:
database:
replace: none
我尝试了什么:
- 多个 url 配置,包括 H2 中的
NON_KEYWORDS
选项,以排除用户问题,因为它可能被解释为关键字。
因为它正在与 MariaDB 一起工作,所以我认为这是与 H2 相关的问题。
感谢任何帮助、文档,link 任何 :)
您将 h2 url 设置为此字符串:
datasource:
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;NON_KEYWORDS=user
username: sa
driver-class-name: org.h2.Driver
password: password
在 documentation linked here 中,您可以看到他们的设置与 spring boot 和 h2:
的设置略有不同
By default, Spring Boot configures the application to connect to an in-memory store with the username sa and an empty password.
However, we can change those parameters by adding the following properties to the application.properties file:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
由于错误在最后引用了 hibernate URL,并且所做的唯一更改是添加了 h2 数据集,因此我搜索了 spring boot 和 h2 以查找文档。
实际上,问题出在我的架构上。由于 H2 不支持 MariaDB 的某些功能,它没有启动,因此 jpa 无法准备 SQL 语句,因为表不存在。
我在 Spring 引导应用程序中集成了 Liquibase。将它与 MariaDB 一起使用效果很好。
对于单元和集成测试,我使用 H2 内存数据库。 运行 测试时会导致以下异常:
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [select user0_.id as id1_19_0_, user0_.created_at as created_2_19_0_, user0_.updated_at as updated_3_19_0_, user0_.version as version4_19_0_, user0_.activated as activate5_19_0_, user0_.birthday as birthday6_19_0_, user0_.email as email7_19_0_, user0_.firstname as firstnam8_19_0_, user0_.force_password_change as force_pa9_19_0_, user0_.password_hash as passwor10_19_0_, user0_.role as role11_19_0_, user0_.surname as surname12_19_0_ from users user0_ where user0_.id=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259) ~[spring-orm-5.3.19.jar:5.3.19]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233) ~[spring-orm-5.3.19.jar:5.3.19]
我的产品配置(工作):
spring:
main:
allow-bean-definition-overriding: true
datasource:
url: jdbc:mariadb://localhost:3307/testdb
username: user
password: psw
jpa:
generate-ddl: false
database-platform: org.hibernate.dialect.MariaDB103Dialect
sql:
init:
mode: never
liquibase:
enabled: true
change-log: classpath:db/db.changelog-master.yaml
我的测试配置(不工作):
spring:
main:
allow-bean-definition-overriding: true
datasource:
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;NON_KEYWORDS=user
username: sa
driver-class-name: org.h2.Driver
password: password
jpa:
database-platform: org.hibernate.dialect.H2Dialect
generate-ddl: false
sql:
init:
mode: never
liquibase:
change-log: classpath:db/db.changelog-master.yaml
enabled: true
test:
database:
replace: none
我尝试了什么:
- 多个 url 配置,包括 H2 中的
NON_KEYWORDS
选项,以排除用户问题,因为它可能被解释为关键字。
因为它正在与 MariaDB 一起工作,所以我认为这是与 H2 相关的问题。
感谢任何帮助、文档,link 任何 :)
您将 h2 url 设置为此字符串:
datasource:
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;NON_KEYWORDS=user
username: sa
driver-class-name: org.h2.Driver
password: password
在 documentation linked here 中,您可以看到他们的设置与 spring boot 和 h2:
的设置略有不同By default, Spring Boot configures the application to connect to an in-memory store with the username sa and an empty password.
However, we can change those parameters by adding the following properties to the application.properties file:
spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
由于错误在最后引用了 hibernate URL,并且所做的唯一更改是添加了 h2 数据集,因此我搜索了 spring boot 和 h2 以查找文档。
实际上,问题出在我的架构上。由于 H2 不支持 MariaDB 的某些功能,它没有启动,因此 jpa 无法准备 SQL 语句,因为表不存在。