簡體   English   中英

liquibase 中的自定義屬性(遷移到新版本后)導致 Spring 啟動失敗

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM