Database connection does not close using jpaFlowExecutionListener

I am using Spring Web Flow to create an application. I use it Flow Managed Persistence Context, so the entity manager "stays open" during the execution of my thread, and I can access lazy loaded properties (similar to OpenEntityManagerInViewFilteror OpenSessionInViewFilterfor Spring MVC). When I use this, every time I submit the form, the number of active connections to the database increases, if I do not use FMPC, I have no problems with the number of open connections).

I am working with the following setup.

TransactionManager:

@Bean
@Autowired
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    return new JpaTransactionManager(entityManagerFactory);
}

DataSource:

@Bean
public DataSource dataSource() {
    final BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(environment.getRequiredProperty(PROPERTY_DATABASE_DRIVER));
    dataSource.setUrl(environment.getRequiredProperty(PROPERTY_DATABASE_URL));
    dataSource.setUsername(environment.getProperty(PROPERTY_DATABASE_USERNAME, ""));
    dataSource.setPassword(environment.getProperty(PROPERTY_DATABASE_PASSWORD, ""));
    return dataSource;
}

EntityManagerFactory:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    final LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dataSource());
    factoryBean.setPackagesToScan(environment.getRequiredProperty(PROPERTY_ENTITYMANAGER_PACKAGES_TO_SCAN));

    final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter() {
        {
            setDatabase(Database.valueOf(environment.getRequiredProperty(PROPERTY_DATABASE_TYPE)));
            setDatabasePlatform(environment.getRequiredProperty(PROPERTY_HIBERNATE_DIALECT));
        }
    };
    factoryBean.setJpaVendorAdapter(vendorAdapter);

    final Properties jpaProperties = new Properties();
    jpaProperties.put(PROPERTY_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_HIBERNATE_FORMAT_SQL));
    jpaProperties.put(PROPERTY_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_HIBERNATE_NAMING_STRATEGY));
    jpaProperties.put(PROPERTY_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_HIBERNATE_SHOW_SQL));
    jpaProperties.put(PROPERTY_HIBERNATE_HB2DDL_SQL, environment.getRequiredProperty(PROPERTY_HIBERNATE_HB2DDL_SQL));

    factoryBean.setJpaProperties(jpaProperties);

    return factoryBean;
}

JpaFlowExecutionListener:

@Bean
@Autowired
public JpaFlowExecutionListener jpaFlowExecutionListener(EntityManagerFactory entityManagerFactory, JpaTransactionManager transactionManager) {
    return new JpaFlowExecutionListener(entityManagerFactory, transactionManager);
}

BasicDataSource maxActive 8, 8 , . ? Chrome ( ), , AJAX - , (HTTP POST) 301 , HTTP GET 200, .

, , beans, JpaTransactionManager, SWF :

  • . , , . , JPA Transaction Manager. Spring JPA TransactionManager , , Hibernate JPA. Spring FlushMode MANUAL, , , .

spring -web-flow:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:webflow="http://www.springframework.org/schema/webflow-config"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/webflow-config
           http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">

    <!-- Flow executor, repsonsible for creating and executing flows -->
    <webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
        <webflow:flow-execution-listeners>
            <webflow:listener ref="jpaFlowExecutionListener"/>
        </webflow:flow-execution-listeners>
    </webflow:flow-executor>

    <!-- Flow registry, responsible for loading all flows so executor can execute them -->
    <webflow:flow-registry id="flowRegistry" base-path="/WEB-INF/webflow/flows" flow-builder-services="flowBuilderServices">
        <webflow:flow-location-pattern value="/**/*-flow.xml"/>
    </webflow:flow-registry>

    <!-- Flow builder services -->
    <webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator"/>

    <!-- MvcViewFactoryCreator -->
    <bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
        <property name="viewResolvers">
            <list>
                <ref bean="viewResolver"/>
            </list>
        </property>
    </bean>

    <!-- Flow handler adapter, responsible for answering request for a flow -->
    <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
        <property name="flowExecutor" ref="flowExecutor"/>
    </bean>

    <!-- Flow handler mapping, lets Spring MVCs DispatcherServlet know to send flow request to SWF -->
    <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
        <property name="flowRegistry" ref="flowRegistry"/>
        <property name="order" value="0"/>
        <property name="interceptors">
            <list>
                <ref bean="localeChangeInterceptor" />
            </list>
        </property>
    </bean>
</beans>

<persistence-context />, .

( ), , URL e2s1, reset:

<end-state id="restart" commit="true" view="redirect:/main"/>
+4
1

, , hibernate hibernate.connection.release_mode on_close. , EntityManager , .

after_transaction . , . , JpaFlowExecutionListener :

public class AvoidLeakJpaFlowExecutionListener extends JpaFlowExecutionListener {

    public AvoidLeakJpaFlowExecutionListener(EntityManagerFactory entityManagerFactory, PlatformTransactionManager transactionManager) {
        super(entityManagerFactory, transactionManager);
    }

    @Override
    public void paused(RequestContext context) {
        super.paused(context);
        EntityManager entityManager = (EntityManager) context.getFlowScope().get(PERSISTENCE_CONTEXT_ATTRIBUTE);
        if (entityManager != null && entityManager instanceof HibernateEntityManager) {
            HibernateEntityManager hibernateEntityManager = (HibernateEntityManager) entityManager;
            hibernateEntityManager.getSession().disconnect();
        }
    }
}

, , WebFlow, , . ( ).

+2

Source: https://habr.com/ru/post/1540062/


All Articles