微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在春季启动时创建H2 + flyway测试数据库?

如何解决如何在春季启动时创建H2 + flyway测试数据库?

我有一个Spring Boot项目,我想在其中测试我的控制器。我使用MysqL数据库进行生产,但想要一个内存数据库来运行测试用例。我使用Flyway进行版本数据库迁移。我希望我的测试数据库使用相同的版本。有人可以帮助我吗?

这是我在src / test / resources文件夹中的application.properties的样子:

# Database Properties
spring.jpa.database=H2
spring.database.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MysqL;INIT=CREATE SCHEMA IF NOT EXISTS public;DATABASE_TO_UPPER=false

spring.h2.console.enabled=true
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
security.basic.enabled:false

spring.datasource.username:sa
spring.datasource.password:

# Flyway Properties
spring.flyway.locations=filesystem:src/main/resources/db/migration
spring.flyway.enabled=true
spring.flyway.baseline-on-migrate=true

这是我的测试文件

import static org.springframework.test.web.servlet.result.mockmvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.mockmvcResultMatchers.status;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfiguremockmvc;
import org.springframework.boot.test.context.SpringBoottest;
import org.springframework.boot.test.context.SpringBoottest.WebEnvironment;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.mockmvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.mockmvcRequestBuilders;

@SpringBoottest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfiguremockmvc
@ContextConfiguration
public class PermissionsControllerTest {

    @Autowired
    private mockmvc mockmvc;

    @Test
    public void existentUserCanGetTokenAndAuthenticationAndAlsoExtractPermissions() throws Exception {
        String username = "Srishti";
        String body = "{" + "\"username\":\"" + username + "\"}";

        MvcResult result = mockmvc.perform(mockmvcRequestBuilders.post("/authenticate")
                .contentType(MediaType.APPLICATION_JSON_VALUE).content(body)).andDo(print()).andExpect(status().isOk())
                .andReturn();

        String response = result.getResponse().getContentAsstring();

        mockmvc.perform(mockmvcRequestBuilders.get("/permission").header("Authorization","Bearer " + response))
                .andExpect(status().isOk()).andDo(print()).andReturn();

        mockmvc.perform(mockmvcRequestBuilders.get("/permission/9").header("Authorization","Bearer " + response))
                .andExpect(status().isOk()).andDo(print()).andReturn();
    }
}

这是我当前得到的输出

2020-09-06 19:30:54.481  INFO 26936 --- [           main] c.t.L.PermissionsControllerTest          : Starting PermissionsControllerTest on DGKDSQ13 with PID 26936 (started by SrishtiChawla in C:\Users\srishtichawla\Desktop\LCTraining\LCTraining)
2020-09-06 19:30:54.483  INFO 26936 --- [           main] c.t.L.PermissionsControllerTest          : No active profile set,falling back to default profiles: default
2020-09-06 19:30:55.599  INFO 26936 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found,entering strict repository configuration mode!
2020-09-06 19:30:55.600  INFO 26936 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2020-09-06 19:30:55.670  INFO 26936 --- [           main] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface com.training.LCtraining.repository.LOBRepository. If you want this repository to be a JDBC repository,consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2020-09-06 19:30:55.672  INFO 26936 --- [           main] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface com.training.LCtraining.repository.PermissionsRepository. If you want this repository to be a JDBC repository,consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2020-09-06 19:30:55.674  INFO 26936 --- [           main] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface com.training.LCtraining.repository.ProductCategoryRepository. If you want this repository to be a JDBC repository,consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2020-09-06 19:30:55.677  INFO 26936 --- [           main] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface com.training.LCtraining.repository.RolesRepository. If you want this repository to be a JDBC repository,consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2020-09-06 19:30:55.679  INFO 26936 --- [           main] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface com.training.LCtraining.repository.ScoringModelSuiteRepository. If you want this repository to be a JDBC repository,consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2020-09-06 19:30:55.681  INFO 26936 --- [           main] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface com.training.LCtraining.repository.UserRepository. If you want this repository to be a JDBC repository,consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2020-09-06 19:30:55.682  INFO 26936 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 74ms. Found 0 JDBC repository interfaces.
2020-09-06 19:30:55.694  INFO 26936 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found,entering strict repository configuration mode!
2020-09-06 19:30:55.695  INFO 26936 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFERRED mode.
2020-09-06 19:30:55.762  INFO 26936 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 63ms. Found 6 JPA repository interfaces.
2020-09-06 19:30:56.308  INFO 26936 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler@1e5eb20a' of type [org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-09-06 19:30:56.325  INFO 26936 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'methodSecurityMetadataSource' of type [org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-09-06 19:30:57.018  INFO 26936 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 0 (http)
2020-09-06 19:30:57.032  INFO 26936 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-09-06 19:30:57.033  INFO 26936 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-09-06 19:30:57.216  INFO 26936 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-09-06 19:30:57.216  INFO 26936 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2708 ms
2020-09-06 19:30:57.353  WARN 26936 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore,database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2020-09-06 19:30:57.509  INFO 26936 --- [           main] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 6.4.4 by Redgate
2020-09-06 19:30:57.515  INFO 26936 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2020-09-06 19:30:57.746  INFO 26936 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2020-09-06 19:30:57.773  INFO 26936 --- [           main] o.f.c.internal.database.DatabaseFactory  : Database: jdbc:h2:mem:testdb (H2 1.4)
2020-09-06 19:30:57.864  INFO 26936 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 9 migrations (execution time 00:00.036s)
2020-09-06 19:30:57.883  INFO 26936 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table "PUBLIC"."flyway_schema_history" ...
2020-09-06 19:30:57.955  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema "PUBLIC": << Empty Schema >>
2020-09-06 19:30:57.970  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.1 - createTables
2020-09-06 19:30:58.100  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.2 - inservalues
2020-09-06 19:30:58.144  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.3 - altertable
2020-09-06 19:30:58.183  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.4 - INSERTVALUES2
2020-09-06 19:30:58.216  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.5 - insertvalues3
2020-09-06 19:30:58.241  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.6 - ALTERTABLE
2020-09-06 19:30:58.264  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.7 - Altertablelob
2020-09-06 19:30:58.293  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.8 - insertvals
2020-09-06 19:30:58.315  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.10 - uniquekey
2020-09-06 19:30:58.330  INFO 26936 --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 9 migrations to schema "PUBLIC" (execution time 00:00.383s)
2020-09-06 19:30:58.541  INFO 26936 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-09-06 19:30:58.639  INFO 26936 --- [         task-1] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2020-09-06 19:30:58.711  INFO 26936 --- [         task-1] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.18.Final
2020-09-06 19:30:58.903  INFO 26936 --- [         task-1] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2020-09-06 19:30:59.060  INFO 26936 --- [         task-1] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2020-09-06 19:30:59.320  INFO 26936 --- [           main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
2020-09-06 19:30:59.970  INFO 26936 --- [         task-1] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2020-09-06 19:30:59.982  INFO 26936 --- [         task-1] j.LocalContainerEntityManagerfactorybean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-09-06 19:31:00.409  INFO 26936 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2020-09-06 19:31:00.489  INFO 26936 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: any request,[org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1c43e84e,org.springframework.security.web.context.SecurityContextPersistenceFilter@5e62ca19,org.springframework.security.web.header.HeaderWriterFilter@493968a9,org.springframework.web.filter.CorsFilter@7bd694a5,org.springframework.security.web.authentication.logout.logoutFilter@322ab6ce,com.training.LCtraining.filter.JwtFilter@af9dd34,org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6528d339,org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@3149409c,org.springframework.security.web.authentication.AnonymousAuthenticationFilter@21ce2e4d,org.springframework.security.web.session.SessionManagementFilter@780c0,org.springframework.security.web.access.ExceptionTranslationFilter@7a8b7e11,org.springframework.security.web.access.intercept.FilterSecurityInterceptor@11ee671f]
2020-09-06 19:31:01.178  INFO 26936 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring TestdispatcherServlet ''
2020-09-06 19:31:01.179  INFO 26936 --- [           main] o.s.t.web.servlet.TestdispatcherServlet  : Initializing Servlet ''
2020-09-06 19:31:01.195  INFO 26936 --- [           main] o.s.t.web.servlet.TestdispatcherServlet  : Completed initialization in 16 ms
2020-09-06 19:31:01.298  INFO 26936 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 51516 (http) with context path ''
2020-09-06 19:31:01.300  INFO 26936 --- [           main] DeferredRepositoryInitializationListener : Triggering deferred initialization of Spring Data repositories…
2020-09-06 19:31:01.785  INFO 26936 --- [           main] DeferredRepositoryInitializationListener : Spring Data repositories initialized!
2020-09-06 19:31:01.801  INFO 26936 --- [           main] c.t.L.PermissionsControllerTest          : Started PermissionsControllerTest in 7.711 seconds (JVM running for 9.214)
Hibernate: select user0_.user_id as user_id1_9_,user0_.lob_id as lob_id4_9_,user0_.enabled as enabled2_9_,user0_.role_id as role_id5_9_,user0_.username as username3_9_ from user user0_ where user0_.username=?
2020-09-06 19:31:02.278  WARN 26936 --- [           main] o.h.engine.jdbc.spi.sqlExceptionHelper   : sql Error: 42102,sqlState: 42S02
2020-09-06 19:31:02.279 ERROR 26936 --- [           main] o.h.engine.jdbc.spi.sqlExceptionHelper   : Table "user" not found; sql statement:
select user0_.user_id as user_id1_9_,user0_.username as username3_9_ from user user0_ where user0_.username=? [42102-200]

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /authenticate
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8",Content-Length:"22"]
             Body = {"username":"Srishti"}
    Session Attrs = {}

Handler:
             Type = com.training.LCtraining.integration.UserRestController
           Method = com.training.LCtraining.integration.UserRestController#generatetoken(AuthRequest)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.dao.InvalidDataAccessResourceUsageException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 401
    Error message = null
          Headers = [vary:"Origin","Access-Control-Request-Method","Access-Control-Request-Headers",Content-Type:"application/json",X-Content-Type-Options:"nosniff",X-XSS-Protection:"1; mode=block",Cache-Control:"no-cache,no-store,max-age=0,must-revalidate",Pragma:"no-cache",Expires:"0",x-frame-options:"DENY"]
     Content type = application/json
             Body = {"timestamp":"2020-09-06","message":"Could not prepare statement; sql [select user0_.user_id as user_id1_9_,user0_.username as username3_9_ from user user0_ where user0_.username=?]; nested exception is org.hibernate.exception.sqlGrammarException: Could not prepare statement","details":"uri=/authenticate"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /authenticate
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8",Content-Length:"22"]
             Body = {"username":"Srishti"}
    Session Attrs = {}

Handler:
             Type = com.training.training.integration.UserRestController
           Method = com.training.training.integration.UserRestController#generatetoken(AuthRequest)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.dao.InvalidDataAccessResourceUsageException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 401
    Error message = null
          Headers = [vary:"Origin","details":"uri=/authenticate"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
2020-09-06 19:31:02.656  INFO 26936 --- [extShutdownHook] j.LocalContainerEntityManagerfactorybean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-09-06 19:31:02.659  INFO 26936 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2020-09-06 19:31:02.659  INFO 26936 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-09-06 19:31:02.664  INFO 26936 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

控制器在生产方面运行良好。

这是我的V1.1__createtable.sql文件

create table permissions(
permissionID int not null auto_increment,permissionTitle varchar(40) not null,permissionDescription varchar(255),PRIMARY KEY (permissionID),UNIQUE (permissionTitle));


insert into permissions(permissionTitle) values('Create Role');
insert into permissions(permissionTitle) values('Edit Role');
insert into permissions(permissionTitle) values('Delete Role');
insert into permissions(permissionTitle) values('Create User');
insert into permissions(permissionTitle) values('Edit User');
insert into permissions(permissionTitle) values('Delete User');
insert into permissions(permissionTitle) values('Create LOB');
insert into permissions(permissionTitle) values('Edit LOB');
insert into permissions(permissionTitle) values('Delete LOB');

解决方法

根据日志,Flyway成功执行:

Flyway Community Edition 6.4.4 by Redgate
HikariPool-1 - Starting...
HikariPool-1 - Start completed.
Database: jdbc:h2:mem:testdb (H2 1.4)
Successfully validated 9 migrations (execution time 00:00.036s)
Creating Schema History table "PUBLIC"."flyway_schema_history" ...
Current version of schema "PUBLIC": << Empty Schema >>
Migrating schema "PUBLIC" to version 1.1 - createTables
Migrating schema "PUBLIC" to version 1.2 - inservalues
Migrating schema "PUBLIC" to version 1.3 - altertable
Migrating schema "PUBLIC" to version 1.4 - INSERTVALUES2
Migrating schema "PUBLIC" to version 1.5 - insertvalues3
Migrating schema "PUBLIC" to version 1.6 - ALTERTABLE
Migrating schema "PUBLIC" to version 1.7 - Altertablelob
Migrating schema "PUBLIC" to version 1.8 - insertvals
Migrating schema "PUBLIC" to version 1.10 - uniquekey
Successfully applied 9 migrations to schema "PUBLIC" (execution time 00:00.383s)

您可以看到应用了9种迁移:createTables,inservalues,altertable,INSERTVALUES2,insertvalues3,ALTERTABLE,Altertablelob,insertvals,uniquekey。

此列表是否完整?或者您希望进行更多迁移?

您稍后在日志中看到的错误来自Hibernate,而不是Flyway。 它说:

Table "user" not found

看迁移名称,我希望user表是由createTables迁移创建的。但是CREATE TABLE 'user'中没有V1.1__createTables.sql语句。

请仔细检查是否在迁移中定义了所有必需的表。您不应该更改旧的迁移。相反,您可以为丢失的表创建新的迁移,并使用CREATE TABLE IF NOT EXISTS语法,使其与现有的生产环境兼容。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。