Expected database doesn't work with transactional and delete
See original GitHub issueWhen using @Transactional, TransactionDbUnitTestExecutionListener.class and @ExpectedDatabase, updating a row makes the expected database to always fail.
Here is a exemple :
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = MvcUnitTestConfiguration.class)
@DatabaseSetup("uuidtest.xml")
@DatabaseTearDown(value = "uuidtest.xml", type = DatabaseOperation.DELETE)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionDbUnitTestExecutionListener.class })
@Transactional
@TransactionConfiguration(defaultRollback = true)
public class TestDUITransactional {
@Autowired
private WebApplicationContext wac;
@Autowired
TempUuidDaoI tempUuidDaoI;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
@ExpectedDatabase(value = "testDelete.xml", assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED)
public void testDeleteUuid() throws Exception {
Integer nb = tempUuidDaoI.getAll().size();
tempUuidDaoI.delete(tempUuidDaoI.get(1));
assertEquals(nb-1, tempUuidDaoI.getAll().size());
}
@Test
@ExpectedDatabase(value = "testUpdate.xml", assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED)
public void testUpdateUuid() throws Exception {
TempUuid tu = tempUuidDaoI.get(1);
tu.setUuid("4b2f02ca-d857-4c95-b7fa-ee6283ce0d66");
tempUuidDaoI.update(tu);
tu = tempUuidDaoI.get(1);
assertEquals("4b2f02ca-d857-4c95-b7fa-ee6283ce0d66", tu.getUuid());
}
@Test
@ExpectedDatabase(value = "testInsert.xml", assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED)
public void testInsertUuid() throws Exception {
Integer nb = tempUuidDaoI.getAll().size();
TempUuid tu = new TempUuid();
tu.setUuid("4b2f02ca-d857-4c95-b7fa-ee6283ce0d67");
tempUuidDaoI.insert(tu);
assertEquals(nb+1, tempUuidDaoI.getAll().size());
}
}
In this code, only the update doesn’t work.
The original db :
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<PDI.TEMP_UUIDS tuu_id="1" uuid="4b2f02ca-d857-4c95-b7fa-ee6283ce0d64" />
<PDI.TEMP_UUIDS tuu_id="2" uuid="4b2f02ca-d857-4c95-b7fa-ee6283ce0d65" />
</dataset>
testDelete.xml :
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<PDI.TEMP_UUIDS tuu_id="2" uuid="4b2f02ca-d857-4c95-b7fa-ee6283ce0d65" />
</dataset>
testUpdate.xml :
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<PDI.TEMP_UUIDS tuu_id="1" uuid="4b2f02ca-d857-4c95-b7fa-ee6283ce0d66" />
<PDI.TEMP_UUIDS tuu_id="2" uuid="4b2f02ca-d857-4c95-b7fa-ee6283ce0d65" />
</dataset>
testInsert.xml :
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<PDI.TEMP_UUIDS tuu_id="1" uuid="4b2f02ca-d857-4c95-b7fa-ee6283ce0d64" />
<PDI.TEMP_UUIDS tuu_id="2" uuid="4b2f02ca-d857-4c95-b7fa-ee6283ce0d65" />
<PDI.TEMP_UUIDS tuu_id="3" uuid="4b2f02ca-d857-4c95-b7fa-ee6283ce0d67" />
</dataset>
I’ve checked that the methods to update/delete/insert work, as does the dao. I use postgresql for anything else than unit testing for the project. I use hibernate H2 for testing.
Any idea on where does this come from ?
Issue Analytics
- State:
- Created 9 years ago
- Comments:6
Top Results From Across the Web
Spring Data problem - derived delete doesn't work
The two methods do two different things: Long deleteBySystemId(String systemId); loads the entity by the given constraints and ends up issuing ...
Read more >Spring Transaction Management: @Transactional In-Depth
Spring constructs a dynamic CGLib proxy of your UserService class here that can open and close database transactions for you. You or any...
Read more >Spring Transactional – 5 Common Pitfalls | Codete Blog
It looks okay, but it won't work as someone expected. Since this is a transactional method, the user entity is in managed state...
Read more >Page Data Is Inconsistent Error Message When Deleting My ...
When trying to save your page data, the system found that the information currently in the database did not match what was expected....
Read more >Spring Data JPA - Reference Documentation
As the name suggests, the latter method issues a single JPQL query (the one defined in the annotation) against the database. This means...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Hi nyddogghr,
The issue that you described is very interesting. I created a sample application that shows this problem: https://github.com/ekravchenko/testingzone/tree/master/spring-dbunit-issue75
In the sample application I’m using same entity and dataset files that you provided in the example. Instead of DAO I’m using spring-data-jpa CrudRepository but that shouldn’t matter cause I could reproduce the issue you described.
If I understand you right
testInsert
andtestDelete
work buttestUpdate
fails. The root of the problem is the @Transactional annotation which causes the tests to be wrapped in the transaction. DBUnit checks the expected dataset however data is not inserted/updated cause it only happens at the end of transaction. If this statement is correct then none of your tests should work.The reasonable questions is ‘why testInsert and testDelete work then’? They work because you have the following line in tests:
If you don’t configure FlushMode then the default value of AUTO will be used. So when you fire
tempUuidDaoI.getAll()
at the end of the test it makes hibernate flush before transaction ends, thus making changes visible for DBUnit checks.Re-write testUpdateUuid in the following way and you will be surprised to find it working:
The last line will force the flush.
As a workaround I would suggest flushing manually at the end of the test.
session.flush()
orentityManager.flush()
. I wouldn’t rely on AUTO flush cause that’s not intuitive.However it would be awesome if this problem could be fixed on the tesing framework level so that users wouldn’t have to worry about it.
Hi, with the help of flush I was able to make an integration test work on service-level, e.g., see: service integration test
However, it does not work on Mvc-level, when testing the controller, e.g., see: controller integration test
Do you have any idea what is the issue with the MockMvc? Can you advice?
Thanks in advance!