问题
Our app is working in 2.0.4 release. After upgrade to 2.2.2.RELEASE we see integration tests failing. I suspect that there is some misconfiguration, and each integration test simply does not clean after itself or there is extra initialization which weren't here before. I really do not know how to fix it properly.
To be specific. Each test works when invoked separately. When executed all of them we do see errors like:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table somewhere.sometable if exists" via JDBC Statement
...
caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Cannot drop "SOME_TABLE" because "FKKJEJC7GUX6OTX5NGANQCMN83R, FK7WLRCFA21PY7CI3R4OL1OWODT, FKQPMY4YOVD3D6HBNT0XX92149P, FK1TG6AMM2NSM6UJTO9EJHPJIXY, FKLPTBKDKFCHE72RJ5RRRIH4ORJ" depends on it; SQL statement:
and
2019-12-16 21:11:00.075 org.apache.tomcat.util.modeler.Registry : The MBean registry cannot be disabled because it has already been initialised
which suggests me, that we're trying to re-initialize something already initialized + there is wrong order of drops in hibernate initialization. But I really cannot see anything wrong on our side. Lets show some excerpts:
annotations of test:
@RunWith(SpringRunner.class)
@ActiveProfiles(...)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SomeIT {
tests are executed via:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
<forkCount>0</forkCount>
<reuseForks>false</reuseForks>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
and application.properties for tests:
spring.jpa.database=H2
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.jdbc.batch_size=5
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true
#this disables option to have opened tx in view IIUC. We don't rely on that, so this just removes warning logging from console.
spring.jpa.open-in-view=false
#used to select db initialization scripts.
spring.datasource.platform=org.hibernate.dialect.H2Dialect
spring.datasource.url=jdbc:h2:mem:somewhere;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;INIT=create schema if not exists somewhere
spring.datasource.driver-class-name = org.h2.Driver
#this is probably needed for @DataJpaTest: I have no idea how to configure @DataJpaTest so that it can run with
#autoconfigured H2 db, probably it's caused by having schema defined in entities. Anyways @DataJpaTest fails to
#create schema. So alternative is to configure one DB for whole app here, and this option forces all @DataJpaTest not to
#replace this configuration with autoconfigured db.
spring.test.database.replace=none
Tested changes:
- I changed create to create-drop if it helps in any way and no, it does not help in any way.
- I tried to @DirtiesContext on class level for every IT test, which is what I'd expect anyways, that context is created/killed with every IT test class, but that did not help either.
- I tried to remove
replace=none
, but that just kills all unit tests(because schema is not created), and does not help in any way to integration tests.
Current workaround: well all I was able to come up with is not to reuse db. Which with replace=none
is possible only via:
spring.datasource.url=jdbc:h2:mem:somewhere${random.uuid};DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;INIT=create schema if not exists somewhere
but I deeply hate this "solution". What can cause incorrect db re-initialization / missing cleanups / or what the cause of all this could be?
(edit: if you know better title to this question, please suggest. Thanks).
回答1:
I wanted to let you know that I found a work-around for this problem. With javax.persistence
properties you can define a drop script which will be executed before the automatic schema creation.
This enables you to specify the order in which the tables have to be dropped (dependend tables first). Maybe playing around with these could help you. Note that they replace the spring.jpa.hibernate.ddl
property.
spring.jpa.properties.javax.persistence.schema-generation.database.action=drop-and-create
spring.jpa.properties.javax.persistence.schema-generation.drop-source=script-then-metadata
spring.jpa.properties.javax.persistence.schema-generation.drop-script-source=drop-tables.sql
来源:https://stackoverflow.com/questions/59364212/integrationtest-isolation-fails-in-springboot-2-2-2-release-error-dopping-table