在我的 Spring boot 项目(使用 gradle 作为构建工具)中,我使用 SQLite 数据库。数据库文件位于项目根目录
/db/
目录下:
my-project/
- db/
- mydb.db ## This db file is generated by JPA when run the project
- src/
- main
- java/
...
- bitbucket-pipelines.yml
在我的
src/main/resouces/application.yml
我有:
spring:
datasource:
url: jdbc:sqlite:file:./db/mydb.db?cache=shared
driver-class-name: org.sqlite.JDBC
username: foo
password: foo
jpa:
show-sql: true
database-platform: org.hibernate.community.dialect.SQLiteDialect
hibernate:
ddl-auto: update
项目根目录下的文件夹
/db/
最初实际上是空的,当本地运行该项目时,数据库文件mydb.db
是由JPA自动创建的。应用程序在本地也运行良好,数据库连接已建立。
现在我想在 CI/CD 管道中构建项目。在我的简单
bitbucket-pipelines.yml
中,我只有构建项目的步骤:
image: gradle:7.6.0-jdk17
definitions:
steps:
- step: &build-it
name: Build project
caches:
- gradle
script:
- bash ./gradlew build
artifacts:
- 'build/**'
pipelines:
default:
- step: *build-it
将代码推送到bitbucket存储库后,管道被触发,但最终出现错误,提示无法打开数据库文件。由于完整的堆栈跟踪太长,我在下面添加了最有趣的行:
> Task :test
MyApplicationTests > testRestEndpoint() FAILED
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@50b624da testClass = com.foo.MyApplicationTests, locations = [], classes = [com.foo.MyApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@4b3fa0b3, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@6e950bcf, [ImportsContextCustomizer@1764e45e key = [org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration,
...
...
Caused by:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution [No suitable driver found for ${DATASOURCE_URL}] [n/a]
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1770)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598)
...
...
Caused by:
jakarta.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution [No suitable driver found for ${DATASOURCE_URL}] [n/a]
at app//org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)
...
...
Caused by:
org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution [[SQLITE_CANTOPEN] Unable to open the database file (unable to open database file)] [n/a]
at app//org.hibernate.community.dialect.SQLiteDialect.lambda$buildSQLExceptionConversionDelegate$1(SQLiteDialect.java:458)
...
...
Caused by:
org.sqlite.SQLiteException: [SQLITE_CANTOPEN] Unable to open the database file (unable to open database file)
at app//org.sqlite.core.DB.newSQLException(DB.java:1179)
...
...
看起来我的管道无法打开 SQLite 数据库文件。
有人可以指导我如何重构我的
bitbucket-pipelines.yml
以使数据库文件可以通过管道访问吗?
根据堆栈跟踪中的错误消息
No suitable driver found for ${DATASOURCE_URL}
,问题似乎是,至少对于测试而言,您的应用程序正在使用环境变量DATASOURCE_URL
来获取要连接的数据库url,而在您的管道中,您不这样做没有定义它。
定义它的一种方法是添加一个导出到脚本的步骤:
image: gradle:7.6.0-jdk17
definitions:
steps:
- step: &build-it
name: Build project
caches:
- gradle
script:
- export DATASOURCE_URL='jdbc:sqlite:file:./db/mydb.db?cache=shared'
- bash ./gradlew build
artifacts:
- 'build/**'
pipelines:
default:
- step: *build-it