Saurabh Chandra opened SPR-8857 and commented
Data from one test having data-source as H2 (in-memory database) seems to live on for the next test class. This persists even after using @DirtiesContext
at class or method level.
Currently we have to clear any data from H2 before every a test.
@DirtiesContext
should clear all that is bound to the context (including data-source).
If it might help we are using JUnit 4.8.1.
Issue Links: - #10532 Allow for concurrent test execution in the TestContext framework
5 votes, 9 watchers
Comment From: spring-projects-issues
Saurabh Chandra commented
I am using SpringJUnit4ClassRunner for the tests.
Comment From: spring-projects-issues
Torsten Krah commented
Imho @DirtiesContext
should call "close" and "refresh" on the existing context, shouldn't it?
Comment From: spring-projects-issues
Fulop Levente commented
We are in the process to upgrade from Spring 3.0 + Hibernate 3.6 to Spring 3.1.x + Hibernate 4.1.x
We found that our junit tests (running with in-memory HSQLD) generates OutOfMemoryError. After a long digging, we just found, that if a method or class is annotated with @DirtiesContext
, it doesn't clean up all the objects. It seems, that the "old" application context (or part of it) remains in the memory and can not be cleared up by the GC. We created a TestContextListener that display the memory usage before and after each test method I can see the memory increase after a @DirtiesContext
test method executed and the next test method starts.
This is a huge drawback for us, as we are now in the situation that we spent a lot of effort to upgrade to Hibernate 4.1 and now we can not run our unit tests.
Comment From: spring-projects-issues
Sam Brannen commented
Hi guys,
If you have the DirtiesContextTestExecutionListener
enabled (i.e., either implicitly -- which is the default -- or explicitly via @TestExecutionListeners
), the ApplicationContext
managed by the Spring TestContext Framework (TCF) will in fact be closed.
For details, see the source code of DirtiesContextTestExecutionListener, TestContext.markApplicationContextDirty(), and ContextCache.setDirty().
The following is the Javadoc for ConfigurableApplicationContext.close()
:
Close this application context, releasing all resources and locks that the implementation might hold. This includes destroying all cached singleton beans.
Thus all singleton beans should be properly destroyed, assuming they are configured to participate in destruction life cycle callbacks (e.g., via destroy-method
declarations, @PostConstruct
, or DisposableBean
).
If you are experiencing behavior contrary to this, please create a self-contained project on Github that reproduces the issue. See the README for details on how to do that.
Thanks,
Sam
Comment From: spring-projects-issues
Sam Brannen commented
Furthermore, please keep in mind that the issues you're experiencing may be directly related to the implementation or configuration of the component you're using (e.g., an embedded database). In other words, even though the Spring ApplicationContext
is properly closed, Spring cannot guarantee that your components are properly shut down if they do not participate in the ApplicationContext
lifecycle or if they hold references to resources using static fields.
- Sam
Comment From: spring-projects-issues
Fulop Levente commented
Hi,
We indeed have the DirtiesContextTestExecutionListener
and we are using HSQLDB as in-memory database for tests. We have used heavily the @DirtiesContext
annotation in our unit tests and with the latest Spring and Hibernate versions out tests run in OutOfMemoryError.
I created a custom TestExecutionListenet
to display the memory usage and I noticed that the memory are not freed up after DirtiesContextTestExecutionListener
closed the ApplicationContext
.
If it helps, I also found that if I do not define a TransactionManager
in the context.xml
the memory can be free up by GC.
We didn't had problems with Spring 3.0.x and Hibernate 3.6.x.
We noticed this behavior when we updated to Spring 3.1.2 and Hibernate 4.1.4.
I fighting with this issue for 4 days (and nights) and I can confirm right now, that the issue is with Spring 3.1.2
After trying out every crazy solutions I could think about, I downgraded Spring and Hibernate to their minimal version that supports Hibernate 4 and I found that the problem went away (Spring 3.1.0 and Hibernate 4.0.0). In this moment, the working configuration is: - Spring 3.1.1 - Hibernate 4.1.4 (actually, Hibernate can be any 4.x version)
Levi
Comment From: spring-projects-issues
Tadaya Tsuyukubo commented
Hello Fulop,
I created a custom TestExecutionListenet to display the memory usage and I noticed that the memory are not freed up after DirtiesContextTestExecutionListener closed the ApplicationContext.
I just wonder do you have any beans injected to your test instance such as hibernate sessionFactory, and not nullifying them? If so, I assume when application context is closed by test listener, test class instance still holds references to the beans in closed app context. Thus, those referenced beans are not garbage collected.
If it helps, I also found that if I do not define a TransactionManager in the context.xml the memory can be free up by GC. I suggest you could check up the changes in the implementation of your TransactionManager between 3.1.1 and 3.1.2 since those versions made difference in your tests.
Comment From: spring-projects-issues
Fulop Levente commented
Hello Tadaya,
I just wonder do you have any beans injected to your test instance such as hibernate sessionFactory, and not nullifying them? If so, I assume when application context is closed by test listener, test class instance still holds references to the beans in closed app context. Thus, those referenced beans are not garbage collected. The only bean that are injected in my test class is the sessionFactory. I used this test class in order to eliminate any other potential problems that could appear. I have several test methods where some of them are marked with
@DirtiesContext
.I suggest you could check up the changes in the implementation of your TransactionManager between 3.1.1 and 3.1.2 since those versions made difference in your tests. I checked and there is no differences in org.springframework.orm.hibernate4.HibernateTransactionManager between 3.1.1 and 3.1.2 ...
Comment From: spring-projects-issues
Sam Brannen commented
Levi,
Please create a self-contained project on Github that reproduces the issue. See the README for details on how to do that.
Thanks,
Sam
Comment From: spring-projects-issues
Marcel Overdijk commented
I had a similar issue using HSQLDB with Spring 4.1 (using Boot).
Between tests (with @DirtiesContext
(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) enabled) I noticed that the data was cleaned - because I used @Transactional
in my tests) but that HSQLDB autoincrement numbering was not reset.
This had to do that HSQLDB was not shutdown between tests.
After adding ;shutdown=true to my jdbc url everything was working as expected.
Just wanted to share this others who bump against this issue.
Comment From: spring-projects-issues
Bulk closing outdated, unresolved issues. Please, reopen if still relevant.
Comment From: MartaSwierczewska
You can use @AutoConfigureTestDatabase annotation, worked for me