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

@DirtiesContext does not destroy all cached singleton beans [SPR-8857] #13499

Closed
spring-issuemaster opened this Issue Nov 17, 2011 · 11 comments

Comments

Projects
None yet
3 participants
@spring-issuemaster
Copy link
Collaborator

spring-issuemaster commented Nov 17, 2011

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

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Nov 17, 2011

Saurabh Chandra commented

I am using SpringJUnit4ClassRunner for the tests.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Jul 2, 2012

Torsten Krah commented

Imho @DirtiesContext should call "close" and "refresh" on the existing context, shouldn't it?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Jul 13, 2012

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.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Jul 13, 2012

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

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Jul 13, 2012

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

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Jul 14, 2012

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

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Jul 15, 2012

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.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Jul 16, 2012

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 ...

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Jul 16, 2012

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

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Oct 7, 2014

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.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented Jan 12, 2019

Bulk closing outdated, unresolved issues. Please, reopen if still relevant.

@sbrannen sbrannen self-assigned this Jan 15, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment