Spring - 在应用程序关闭之前执行查询(测试)

Spring - execute query before application shutdown (tests)

我正在 运行宁 Spring使用 Sprind Data JPA/Hibernate 作为持久层启动 2.1。我 运行 在应用程序关闭之前 运行 成功查询 在我的测试 中遇到问题。

详情:

在应用程序上下文启动期间,我正在通过 JPA 执行查询(假设此查询转换为以下 SQL "insert into mytable('mycolumn') values ('abc'))。

现在我需要在关闭应用程序之前执行另一个查询。对于给定的示例,这将是 "update mytable set mycolumn = 'xyz' where mycolumn = 'abc'

我设法通过在我的配置上使用@PreDestroy 来执行查询class

@Configuration
MyConfig {

   @Autowired
   private MyTransactionalService myService;

   @PreDestroy
   public void doQuery() {
      mySerivce.runMyQuery(); 

  }
}

mySerivce.runMyQuery() 委托给 myRepository(即 Spring Data JPA Repository)以调用更新查询:

MyRepository extends JpaRepository(String, Something) {

   @Modifying
   @Query("UPDATE myEntity e SET e.myColumn = 'xyz' WHERE e.myColumn = 'abc")' 
   void runMyQuery();
}

@PreDestroy 注释的方法执行但是当查询由 H2 执行时(在我的 spring 测试中的内存数据库 运行ning 中)它抛出异常说 table 不存在。

问题是 table 之前肯定存在,因为我能够在应用程序启动期间对该 table 执行 INSERT(请参阅 post 的开头)。

我的猜测是 shudtown 进程正在进行中,所以内存数据库被清除了...因此没有 table。

有没有办法确保在与数据库的连接仍然健康并且尚未删除 table 时执行查询(在应用程序上下文关闭时)?

@Predestroy 按预期工作,只需在您的应用程序 class 中的某些方法上添加 @PreDestroy 注释。我在这里创建了一个例子。为了快速测试,我使用 sql 文件来初始化我的数据库,正如 here 所描述的那样,您也可以为其使用服务。当我关闭应用程序时,数据库会根据需要进行更新。请尝试:

依赖于:pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zpavel</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>2.4.3</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
            <version>1.4.199</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
    </dependencies>
</project>

型号:

@Entity
@Data
public class Foo {
    @Id
    private Long id;
    private String bar;
}

存储库:

public interface FooRepository extends JpaRepository<Foo, Long> {
}

src/main/resources/schema.sql :

DROP TABLE IF EXISTS foo;

CREATE TABLE foo (
  id INT AUTO_INCREMENT  PRIMARY KEY,
  bar VARCHAR(250) NOT NULL
);

src/main/resources/data.sql :

INSERT INTO foo (bar) VALUES ('baz');

src/main/resources/application.属性:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.datasource.url=jdbc:mariadb://localhost:3306/test?useSSL=false
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.initialization-mode=always

Application.java

@SpringBootApplication
public class Application {  
    @Autowired
    private FooRepository fooRepository;

    // keep main method here

    @PreDestroy
    private void shutdown() {
        fooRepository.deleteAll();
    }
}

我设法通过使用 DB_CLOSE_ON_EXIT=FALSE"; 初始参数

克服了这个问题
String url = "jdbc:h2:~/test;DB_CLOSE_ON_EXIT=FALSE";

在这种情况下,H2 不会终止数据库并在关闭过程中保持数据库可用。