[英]Custom property in liquibase (after migration to newer version) causes failure in Spring boot
我不得不在 Spring-boot maven 項目中遷移到更新版本的 Liquibase 核心,之后,我收到了一個 ArrayIndexOutOfBoundsException。
屬性定義:
<property dbms="db2,derby,mysql,h2,mssql" name="autoid" value="BIGINT"/>
<property dbms="oracle" name="autoid" value="BIGINT" />
<property dbms="postgresql" name="autoid" value="SERIAL"/>
拋出異常
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [com/unymira/kfirst/application/config/DatabaseManagementConfig.class]: Invocation of init method failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1694)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:881)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230)
at com.unymira.kfirst.application.ApplicationLauncher.main(ApplicationLauncher.java:55)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at liquibase.datatype.DataTypeFactory.fromDescription(DataTypeFactory.java:251)
at liquibase.change.core.CreateTableChange.generateStatements(CreateTableChange.java:70)
at liquibase.change.AbstractChange.generateStatementsVolatile(AbstractChange.java:287)
at liquibase.change.AbstractChange.warn(AbstractChange.java:358)
at liquibase.changelog.visitor.ValidatingVisitor.visit(ValidatingVisitor.java:110)
at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:83)
at liquibase.changelog.DatabaseChangeLog.validate(DatabaseChangeLog.java:284)
at liquibase.Liquibase.update(Liquibase.java:198)
at liquibase.Liquibase.update(Liquibase.java:179)
at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:366)
at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:314)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1753)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1690)
... 21 common frames omitted
財產使用示例
<column autoIncrement="true" name="id" type="${autoid}">
<constraints nullable="false" primaryKey="true" primaryKeyName="${db_prefix}instancepk" />
</column>
我不得不提一下,這段代碼來自以前的時代,並且與較舊的 liquibase 沒有任何問題。
有人對我做錯了什么有什么建議嗎?
當此錯誤處於打開狀態時,這是一個不太優雅的解決方法。
免責聲明:這會給您的測試增加一點開銷,並且可能並不適合所有人。 您需要手動將測試架構保持為最新。
鑒於您在 liquibase 遷移步驟中有以下數據庫:
CREATE TABLE foo(
id text PRIMARY KEY,
name text not null,
hobbies text[] not null,
locals jsonb,
status boolean not null default false,
date_time_updated timestamp,
date_time_created timestamp NOT NULL
);
在 SpringBoot 其余資源中的測試/資源上,您可以使用以下內容創建一個 testschema.sql:
CREATE TABLE foo(
id character varying(255) DEFAULT RANDOM_UUID() NOT NULL,
name character varying(255) NOT NULL,
hobbies ARRAY NOT NULL,
locals json NOT NULL,
status boolean,
date_time_updated timestamp without time zone,
date_time_created timestamp without time zone NOT NULL
);
愛好是:
<property name="json_type" value="json" dbms="postgresql"/>
我在我的實體中有
@Table(name = "foo")
@TypeDef(name = "json", typeClass = JsonBinaryType.class)
@TypeDef(
name = "string-array",
typeClass = StringArrayType.class
)
public class Foo {
...
@Type(type = "string-array")
@Column(name = "hobbies", columnDefinition = "text[]")
private String[] hobbies;
@Type(type = "json")
@Column(name = "locals", columnDefinition = "json")
private JsonNode locals;
然后你可以簡單地為你的 repo 編寫一個 @DataJpaTest ,如:
@ExtendWith(SpringExtension.class)
@DataJpaTest
@TestPropertySource(properties = {
"spring.jpa.hibernate.ddl-auto=validate"
})
public class TestFooRepository {
@Autowired
private DataSource dataSource;
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private EntityManager entityManager;
@Autowired
private FooRepository fooRepository;
@Test
void injectedComponentsAreNotNull() {
assertThat(dataSource).isNotNull();
assertThat(jdbcTemplate).isNotNull();
assertThat(entityManager).isNotNull();
assertThat(notificationRepository).isNotNull();
}
@Test
public void testShouldSaveTheCorrectObject() throws JsonProcessingException {
Foo expected = buildTestFoo();
fooRepository.save(expected);
final Optional<Foo> actual = notificationRepository.findById("<foo_id>");
Assert.assertNotNull(actual);
Assert.assertTrue(actual.isPresent());
Assert.assertEquals(expected.getId(), actual.get().getId());
}
}
希望這可以幫助。
就我而言,發生這種情況是因為從 3.6.0 開始,我在 MariaDB 上運行時必須使用dbms="mariadb"
,而在以前的版本中它曾經被標識為"mysql"
。
由此更改引起: https : //github.com/liquibase/liquibase/commit/7fb10ed7ae599cab585d4a6a4ec891ad7b91ecf1#diff-a07fbaf7b19fd286fef2e684648d5159
我在使用 Open JDK 11 時遇到了類似的問題。切換到 Oracle JDK 11 后,liquibase:diff 運行正常。 奇怪的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.