title: Tomcat 7+ memory leak on stop/redeploy. Spring Data, JPA, Hibernate, MySQL
body: <p>I have tomcat memory leak issue when stop/redeploy application. It says <strong>The following web applications were stopped (reloaded, undeployed), but their
  classes from previous runs are still loaded in memory, thus causing a memory
  leak (use a profiler to confirm):/test-1.0-SNAPSHOT</strong></p>
  
  <p>MySQL connector driver located in Tomcat/lib folder.
  I can reproduce this issue in both: Tomcat 7/8. Also tried MS SQL database with "net.sourceforge.jtds.*" driver but didn't help.</p>
  
  <p>Please find below project files. Project only creates 1 table in DB.</p>
  
  <p><em>build.gradle</em></p>
  
  <pre><code>group 'com.test'
  version '1.0-SNAPSHOT'
  
  apply plugin: 'java'
  apply plugin: 'war'
  sourceCompatibility = 1.8
  repositories {
      mavenCentral()
  }
  dependencies {
      compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: '5.2.10.Final'
      compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.11.4.RELEASE'
      compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.9.RELEASE'
      providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
      providedCompile group: 'mysql', name: 'mysql-connector-java', version: '5.1.6'
      compile group: 'commons-dbcp', name: 'commons-dbcp', version: '1.4'
  }
  </code></pre>
  
  <p><em>ApplicationConfig.java</em></p>
  
  <pre><code>@Configuration
  @Import({JPAConfiguration.class})
  @EnableWebMvc
  public class ApplicationConfig {}
  </code></pre>
  
  <p><em>JPAConfiguration.java</em></p>
  
  <pre><code>@Configuration
  @EnableJpaRepositories("com.test.dao")
  @EnableTransactionManagement
  public class JPAConfiguration {
  
      @Bean
      public EntityManagerFactory entityManagerFactory() {
          LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
          factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
          factory.setPackagesToScan("com.test.model");
          factory.setDataSource(restDataSource());
          factory.setJpaPropertyMap(getPropertyMap());
          factory.afterPropertiesSet();
          return factory.getObject();
      }
  
      @Bean(destroyMethod = "close")
      public DataSource restDataSource() {
          BasicDataSource dataSource = new BasicDataSource();
          dataSource.setDriverClassName("com.mysql.jdbc.Driver");
          dataSource.setUrl("jdbc:mysql://localhost:3306/test");
          dataSource.setUsername("test");
          dataSource.setPassword("test");
          return dataSource;
      }
  
      private Map&lt;String, String&gt; getPropertyMap() {
          Map&lt;String, String&gt; hibernateProperties = new HashMap&lt;&gt;();
          hibernateProperties.put("hibernate.hbm2ddl.auto", "update");
          hibernateProperties.put("hibernate.show_sql", "true");
          hibernateProperties.put("hibernate.format_sql", "true");
          hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
          return hibernateProperties;
      }
  
      @Bean
      public PlatformTransactionManager transactionManager() {
          JpaTransactionManager txManager = new JpaTransactionManager();
          txManager.setEntityManagerFactory(entityManagerFactory());
          return txManager;
      }
  
  }
  </code></pre>
  
  <p><em>TestRepository.java</em></p>
  
  <pre><code>@Repository
  public interface TestRepository extends JpaRepository&lt;TestEntity, Long&gt; {}
  </code></pre>
  
  <p><em>TestEntity.java</em></p>
  
  <pre><code>@Entity
  @Table(name = "ent")
  public class TestEntity {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;
      private String descript;
      //equals, hashcode, toString, getters, setters
  }
  </code></pre>
  
  <p><em>AppInitializer.java</em></p>
  
  <pre><code>public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
      private WebApplicationContext rootContext;
  
      @Override
      protected Class&lt;?&gt;[] getRootConfigClasses() {
          return new Class[]{ApplicationConfig.class};
      }
  
      @Override
      protected Class&lt;?&gt;[] getServletConfigClasses() {
          return null;
      }
  
      @Override
      protected String[] getServletMappings() {
          return new String[]{"/"};
      }
  
  }
  </code></pre>
  
  <p>Command</p>
  
  <pre><code>jmap -histo &lt;tomcat_pid&gt;
  </code></pre>
  
  <p>shows only 2 items from project structure after tomcat stop:</p>
  
  <pre><code>com.test.config.dao.JPAConfiguration$$EnhancerBySpringCGLIB$$792cb231$$FastClassBySpringCGLIB$$45ff499c
  com.test.config.dao.JPAConfiguration$$FastClassBySpringCGLIB$$10104c1e
  </code></pre>
  
  <p>Anyone have ideas or suggestions to fix this problem?</p>