我有application-test.properties,其中定义了两个数据源
app.datasource.server.url=jdbc:h2:mem:fooserver
app.datasource.server.username=sa
app.datasource.server.password=
app.datasource.server.driverClassName=org.h2.Driver
app.datasource.server.hikari.minimumIdle=5
app.datasource.server.hikari.maximumPoolSize=50
app.datasource.server.hikari.idleTimeout=50000
app.datasource.server.hikari.maxLifetime=55000
app.datasource.manager.url=jdbc:h2:mem:barmanager
app.datasource.manager.username=sa
app.datasource.manager.password=
app.datasource.manager.driverClassName=org.h2.Driver
app.datasource.manager.hikari.minimumIdle=5
app.datasource.manager.hikari.maximumPoolSize=50
app.datasource.manager.hikari.idleTimeout=50000
app.datasource.manager.hikari.maxLifetime=55000
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto=create-drop
#logging
logging.level.root=info
logging.file=foobar-rest-test.log
#required for SpringBootTest does not know why
spring.main.allow-bean-definition-overriding=true
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
每个数据源都要求有可用的名为“ foo”的架构,这将由schema-fooserver.sql和schema-barmanager.sql在这些sql脚本的每个SQL脚本中创建。因此,我定义了一个dataSourceIntializer Bean,可以在其中定义要加载的schema-sql文件。
@Bean(name = "managerDataSourceInitializer")
public DataSourceInitializer dataSourceInitializer1(@Qualifier("managerDataSource") DataSource datasource) {
ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
resourceDatabasePopulator.addScript(new ClassPathResource("schema-barmanager.sql"));
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
dataSourceInitializer.setDataSource(datasource);
dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
return dataSourceInitializer;
}
@Bean(name = "serverDataSourceInitializer")
public DataSourceInitializer dataSourceInitializer1(@Qualifier("serverDataSource") DataSource datasource) {
ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
resourceDatabasePopulator.addScript(new ClassPathResource("schema-fooserver.sql"));
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
dataSourceInitializer.setDataSource(datasource);
dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
return dataSourceInitializer;
}
在测试开始期间,日志显示这些模式文件已被调用并执行。
2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils : Executing SQL script from class path resource [schema-fooserver.sql]
2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils : 0 returned as update count for SQL: CREATE SCHEMA IF NOT EXISTS FOO
2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils : Executed SQL script from class path resource [schema-fooserver.sql] in 0 ms.
2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils : Executing SQL script from class path resource [schema-barserver.sql]
2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils : 0 returned as update count for SQL: CREATE SCHEMA IF NOT EXISTS FOO
2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils : Executed SQL script from class path resource [schema-barserver.sql] in 0 ms.
现在,当我尝试执行测试用例时,它由于以下错误而失败:
28 15:04:36.035 DEBUG 3124 --- [ main] org.hibernate.SQL : insert into foo.Account (uid, password_hash, login) values (null, ?, ?)
Hibernate: insert into foo.Account (uid, password_hash, login) values (null, ?, ?)
2019-03-28 15:04:36.036 DEBUG 3124 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : could not prepare statement [insert into foo.Account (uid, password_hash, login) values (null, ?, ?)]
org.h2.jdbc.JdbcSQLException: Tabelle "ACCOUNT" nicht gefunden
Table "ACCOUNT" not found; SQL statement:
insert into foo.Account (uid, password_hash, login) values (null, ?, ?) [42102-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
目前,我正在尝试在测试用例中创建一个UserAccount
这是定义的UerEntity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
@Table(name = "foo.Account")
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "uid")
private Long id;
@Column(name = "login")
private String username;
@Column(name = "password_hash")
private String password;
....
这是测试用例。在createUser方法期间调用before方法时,会发生错误。
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@AutoConfigureMockMvc
public class UserControllerTest {
private static final Logger LOG = LoggerFactory.getLogger(UserControllerTest.class);
@LocalServerPort
private int port;
TestRestTemplate restTemplate = new TestRestTemplate();
HttpHeaders headers = new HttpHeaders();
@Autowired
private WfcSpringRestApplication controller;
@Autowired
private UserRepository repository;
@Autowired
private MockMvc mvc;
private AuthenticationToken authToken;
@Before
public void before() throws Exception {
headers = new HttpHeaders();
UserEntity user = createTestUser(TEST_ADMIN_USER, TEST_ADMIN_MD5_PW, UserRight.ADMIN);
UserEntity userService = createTestUser(TEST_SERVICE_USER, TEST_ADMIN_MD5_PW, UserRight.SERVICE);
getAuthenticationTokenForTestUser(user);
}
private UserEntity createTestUser(String username, String md5_password, UserRight right) {
UserEntity ue = new UserEntity();
ue.setUsername(username);
ue.setPassword(md5_password);
UserRole roleAdmin = new UserRole();
roleAdmin.setRight(right);
ue.getRoles().put(roleAdmin.getRight(), roleAdmin);
repository.save(ue);
return ue;
}
@Test
public void contextLoads() {
assertThat(controller).isNotNull();
}
在错误消息中,有正确的表名“无法准备语句[插入foo.Account””,为什么会引发未找到表帐户的异常?
答案 0 :(得分:0)
我遇到了类似的错误,我尝试了其他网站上提到的几乎所有解决方案,例如 DATABASE_TO_UPPER=false;DB_CLOSE_DELAY=-1; DB_CLOSE_ON_EXIT=假;忽略情况=真
但对我没有任何作用。
对于 Spring Boot 2.4+,在 application.properties 中使用 spring.jpa.defer-datasource-initialization=true(此处提到 - https://stackoverflow.com/a/68086707/8219358)
我意识到其他解决方案更合乎逻辑,但没有一个对我有用,而这确实有效。