-
Notifications
You must be signed in to change notification settings - Fork 38.5k
Failure to run second script as intended in @SQLGroup with multiple data sources and transaction managers on a JUnit test class [SPR-16153] #20701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Sam Brannen commented
All scripts are supposed to be executed for each test method in such a configuration. That's the expected behavior. |
Sam Brannen commented Did I perhaps misunderstand you? |
Eduardo Beja Martins commented Maybe it is my misunderstanding, but to execute the scripts for each test individually you'd either use something like @DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD) or @RunWith(SpringJUnit4ClassRunner.class)
public class ExampleTest{
@Test
@SqlGroup({
@Sql(scripts = "script1.sql", config = @SqlConfig(dataSource = "dataSource1", transactionManager = "txMgr1")),
@Sql(scripts = "script2.sql", config = @SqlConfig(dataSource = "dataSource2", transactionManager = "txMgr2"))
})
public test1() {
// Some or no code here
}
@Test
@SqlGroup({
@Sql(scripts = "script1.sql", config = @SqlConfig(dataSource = "dataSource1", transactionManager = "txMgr1")),
@Sql(scripts = "script2.sql", config = @SqlConfig(dataSource = "dataSource2", transactionManager = "txMgr2"))
})
public test2() {
// Some or no code here
}
} In the case in the description, is my understanding the the scripts should be loaded once and applied to all tests in the ExampleTest class. Even if I am wrong, howhever, as is my example, what happens to me is that between tests, the database created is not destroyed and it tries to execute the inserts of the second script again over the existing database. Since there are already registers with the same primary key, because they where inserted in the first test, an exception is thrown and the test fails, so as any after that. |
This is the expected behavior. Issue gh-18929 will introduce support for class-level only configuration. |
If you configure SQL scripts or statements that insert data into the database with predefined primary keys -- and if those SQL scripts or statements are executed outside of a test-managed transaction (i.e., if the changes are committed to the database), you will then have to clean up the changes after each test method. Otherwise you run into primary key constraint violations in the database as you have pointed out. Luckily, I documented the available options in detail in this StackOverflow question. Here's an excerpt:
|
In light of the above, I am closing this issue. |
Eduardo Beja Martins opened SPR-16153 and commented
On a JUnit Test configuration, with two data sources of different transaction managers, applied to the test class, the second is rerunned for each test.
Example:
Between test1 and test2, errors will occur because script2.sql has insert statements, that will try to run for each test, and for the second time, registers with the same primary key will aready exist.
If the order of the '
@Sql
' statements is inverted, same problem will occur but for script1.sql.The need for the persistence comes from the heavy load of JUnit tests for code pieces that only read and do not write to database..
No further details from SPR-16153
The text was updated successfully, but these errors were encountered: