ConfigurationHelper leaks SessionFactories
Closed this issue · 3 comments
phaas commented
The ConfigurationHelper stores each SessionFactory in a HashMap to track the "JDBC42" compatibility. Entries are not removed from this map when the SessionFactory is shut down. This causes memory to leak.
This is problematic when running unit/integration tests and setting up a new Hibernate instance per test case. A test suite can quickly create dozens or hundreds of Hibernate instances, which will never be reclaimed.
phaas commented
Fixing this should be as simple as changing the map to a WeakHashMap, which will allow for garbage collection to proceed.
phaas commented
A manual workaround (e.g. using a @PreDestroy
spring hook):
import java.lang.reflect.Field;
import java.util.HashMap;
import javax.annotation.PreDestroy;
import org.jadira.usertype.spi.shared.ConfigurationHelper;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HibernateConfiguration {
/**
* Jadira's shared configuration helper records the "JDBC 4.2" compatibility for each
* session manager that it's registered with.
* <p>
* Unfortunately, the configuration stores the SessionManager as the key in a static hash map,
* which retains it indefinitely.
* <p>
* This is generally not a huge issue when running a web app, but during unit tests where context
* are often created and destroyed, we leak a significant amount of memory (approx. 20mb/test execution),
* resulting in the JVM running out of memory and slowly grinding to a hold
*/
@PreDestroy
public void clearOutJadiraConfigurationMap() {
try {
final Field map = ConfigurationHelper.class.getDeclaredField("DEFAULT_USEJDBC42");
map.setAccessible(true);
Object value = map.get(null);
((HashMap) value).clear();
} catch (Exception e) {
e.printStackTrace();
}
}
}