Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: performance-problem with loading applicationContext

  1. #1
    Join Date
    Dec 2006
    Posts
    29

    Default performance-problem with loading applicationContext

    Hi,
    i have the following applicationContext.xml:

    Code:
    <beans  ... >
    		
    	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    		<property name="location">
    			<value>/config.ini</value>
    		</property>
    	</bean>
    	
    	<util:list id="mappingClasses">
    		<value>de.gebitms.geplan.datastructures.data.BenutzerDOM</value>
    	</util:list>
    
    	<util:list id="mappingPackages">
    		<value>de.gebitms.geplan.datastructures.data</value>
    	</util:list>
    
    	<bean id="hibernatePropertiesSQL" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    		<property name="properties">
    	  		<props>
    				<prop key="hibernate.dialect">${hbn.dialect.sql}</prop>
    				<prop key="hibernate.connection.isolation">${hbn.isolation}</prop>
    				<prop key="hibernate.jdbc.batch_size">${hbn.jdbc.batch_size}</prop>
    				<prop key="hibernate.order_updates">${hbn.order_updates}</prop>
    				<prop key="hibernate.show_sql">${hbn.show_sql}</prop>
    				<prop key="hibernate.transaction.factory_class">${hbn.transaction.factory_class}</prop>
    				<prop key="hibernate.c3p0.initial_pool_size">${hbn.c3p0.initial_pool_size}</prop>
    				<prop key="hibernate.c3p0.min_size">${hbn.c3p0.min_size}</prop>
    				<prop key="hibernate.c3p0.max_size">${hbn.c3p0.max_size}</prop>
    				<prop key="hibernate.c3p0.timeout">${hbn.c3p0.timeout}</prop>
    				<prop key="hibernate.c3p0.max_statements">${hbn.c3p0.max_statements}</prop>
    				<prop key="hibernate.c3po.idle_test_period">${hbn.c3po.idle_test_period}</prop>
    				<prop key="hibernate.c3po.max_idle_time">${hbn.c3po.max_idle_time}</prop>
    				<prop key="hibernate.c3po.acquire_increment">${hbn.c3po.acquire_increment}</prop>
    				<prop key="hibernate.c3po.auto_commit_on_close">${hbn.c3po.auto_commit_on_close}</prop>
    				<prop key="hibernate.c3po.num_helper_threads">${hbn.c3po.num_helper_threads}</prop>
    				<prop key="hibernate.connection.use_compression">${hbn.connection.use_compression}</prop>
    				<prop key="hibernate.connection.cache_result_set_metadata">${hbn.connection.cache_result_set_metadata}</prop>
    				<prop key="hibernate.connection.dont_track_open_resources">${hbn.connection.dont_track_open_resources}</prop>
    				<prop key="hibernate.connection.dynamic_calendars">${hbn.connection.dynamic_calendars}</prop>
    				<prop key="hibernate.connection.zero_date_time_behavior">${hbn.connection.zero_date_time_behavior}</prop>
    				<prop key="hibernate.connection.rollback_on_pooled_close">%{hbn.connection.rollback_on_pooled_close}</prop>
    				<prop key="hibernate.cache.provider_class">${hbn.cache.provider_class}</prop>
    				<prop key="hibernate.query.factory_class">${hbn.query.factory_class}</prop>
    		  	</props>
    	 	</property>
    	</bean>
    	<bean id="hibernatePropertiesOracle" parent="hibernatePropertiesSQL">
    		<property name="properties">
    			<props merge="true">
    				<prop key="hibernate.dialect">${hbn.dialect.oracle}</prop>
    			</props>
    		</property>
    	</bean>
    
    	<bean id="abstractDataSourceSQL" abstract="true" class="org.apache.commons.dbcp.BasicDataSource">
    		<property name="driverClassName" value="${database.sql.driverclass}"/>
    		<property name="url" value="${database.sql.url}"/>
    		<property name="username" value="${database.user}"/>
    		<property name="password" value="${database.password}"/>
    	</bean>
    	<bean id="abstractDataSourceOracle" abstract="true" class="org.apache.commons.dbcp.BasicDataSource">
    		<property name="driverClassName" value="${database.oracle.driverclass}"/>
    		<property name="url" value="${database.oracle.url}"/>
    		<property name="username" value="${database.user}"/>
    		<property name="password" value="${database.password}"/>
    	</bean>
    	<bean id="dataSourceSQL" parent="abstractDataSourceSQL"/>
    	<bean id="dataSourceSQLTest" parent="abstractDataSourceSQL">
    		<property name="url" value="${database.sql.url.test}"/>
    		<property name="username" value="${database.user.test}"/>
    	</bean>
    	<bean id="dataSourceOracle" parent="abstractDataSourceOracle"/>
    	<bean id="dataSourceOracleTest" parent="abstractDataSourceOracle">
    		<property name="username" value="${database.user.test}"/>
    	</bean>
    
    	<bean id="abstractSessionFactorySQL" abstract="true" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" scope="singleton">
    		<property name="dataSource" ref="dataSourceSQL"/>
    		<property name="hibernateProperties" ref="hibernatePropertiesSQL"/>
     	    <property name="annotatedPackages" ref="mappingPackages"/>
     	    <property name="annotatedClasses" ref="mappingClasses"/>
    		<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>
    	</bean>
    	<bean id="abstractSessionFactoryOracle" abstract="true" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" scope="singleton">
    		<property name="dataSource" ref="dataSourceOracle"/>
    		<property name="hibernateProperties" ref="hibernatePropertiesOracle"/>
     	    <property name="annotatedPackages" ref="mappingPackages"/>
     	    <property name="annotatedClasses" ref="mappingClasses"/>
    		<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>
    	</bean>
    	<bean id="sessionFactorySQL" parent="abstractSessionFactorySQL"/>
    	<bean id="sessionFactorySQLTest" parent="abstractSessionFactorySQL">
    		<property name="dataSource" ref="dataSourceSQLTest"/>
    	</bean>
    	<bean id="sessionFactoryOracle" parent="abstractSessionFactoryOracle"/>
    	<bean id="sessionFactoryOracleTest" parent="abstractSessionFactoryOracle">
    		<property name="dataSource" ref="dataSourceOracleTest"/>
    	</bean>
    
    	<bean id="abstractHibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    		<property name="sessionFactory" ref="sessionFactorySQL"/>
    		<property name="allowCreate" value="true"/>
    		<property name="cacheQueries" value="true"/>
    	</bean>
    	<bean id="hibernateTemplateSQL" parent="abstractHibernateTemplate"/>
    	<bean id="hibernateTemplateSQLTest" parent="abstractHibernateTemplate">
    		<property name="sessionFactory" ref="sessionFactorySQLTest"/>
    	</bean>
    	<bean id="hibernateTemplateOracle" parent="abstractHibernateTemplate">
    		<property name="sessionFactory" ref="sessionFactoryOracle"/>
    	</bean>
    	<bean id="hibernateTemplateOracleTest" parent="abstractHibernateTemplate">
    		<property name="sessionFactory" ref="sessionFactoryOracleTest"/>
    	</bean>
    
    	<bean id="multipleHibernateTemplate" class="de.gebitms.geplan.springwrapper.MultipleHibernateTemplate"
    		scope="prototype">
    		<constructor-arg>
    			<map>
    				<entry key="sql" value-ref="hibernateTemplateSQL"/>
    				<entry key="sqlTest" value-ref="hibernateTemplateSQLTest"/>
    				<entry key="oracle" value-ref="hibernateTemplateOracle"/>
    				<entry key="oracleTest" value-ref="hibernateTemplateOracleTest"/>
    			</map>
    		</constructor-arg>
    	</bean>
    
    	<bean id="dataAccessExceptionInterceptor" class="de.gebitms.geplan.springwrapper.advices.DataAccessExceptionAdvice"/>
    	<bean id="dataAccessExceptionAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    		<property name="pattern" value="de.gebitms.geplan.+"/>
    		<property name="advice">
    			<ref bean="dataAccessExceptionInterceptor"/>
    		</property>
    	</bean>
    	
    	<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
    		<property name="proxyTargetClass" value="true"/>
    	</bean>
    
    	<bean id="txManagerSQL" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactorySQL"></property>
    	</bean>
    	<bean id="txManagerSQLTest" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactorySQLTest"></property>
    	</bean>
    	<bean id="txManagerOracle" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactoryOracle"></property>
    	</bean>
    	<bean id="txManagerOracleTest" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactoryOracleTest"></property>
    	</bean>
    
    	<bean id="multipleTxManager" class="de.gebitms.geplan.springwrapper.MultipleTransactionManager"
    		scope="prototype">
    		<constructor-arg>
    			<map>
    				<entry key="sql" value-ref="txManagerSQL"/>
    				<entry key="sqlTest" value-ref="txManagerSQLTest"/>
    				<entry key="oracle" value-ref="txManagerOracle"/>
    				<entry key="oracleTest" value-ref="txManagerOracleTest"/>
    			</map>
    		</constructor-arg>
    	</bean>
    
    	<tx:annotation-driven transaction-manager="multipleTxManager" proxy-target-class="true"/>
    Here i define 4 database-connections. 2 of the databases are on the same computer, the other 2 are on another computer in the network.
    As far as i understand spring, the configuration is loaded lazy. So i assume that he is not trying to connect to the databases while loading the context. BUT: when i load it with the following line:

    Code:
    appContext = new ClassPathXmlApplicationContext("/de/gebitms/geplan/springwrapper/applicationContext.xml");
    this takes more then 30 seconds. And my computer isnīt that slow. Why does it take so long to load my context. What can i do to get a better performance. Can you help me out with this?

    Thanks very much for any help.
    Christoph

    PS: I had to shorten this post to get below the 10000 characters, so i omitted my own beans from the context (there are only 5 of them and they are not very spectacular)

    Spring 2.0.1
    Windows 2000
    SQL-Server 7.0
    Oracle 9i
    Eclipse 3.2.1
    Hibernate 3.2

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    As far as i understand spring, the configuration is loaded lazy. So i assume that he is not trying to connect to the databases while loading the context.
    Your assumption is wrong. The configuration is loaded eagerly, instantiating all the beans, connections etc unless you specify otherwise.

    However there are at least a few things which take time to create:
    * remote database connections (depending on speed of remote computer, network speeds)
    * creating one or more hibernate session factories, hibernate factories take a relative long time to instantiate and it also has some database activity so if one of the other databases is slow, hibernate startsup even slower.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Dec 2006
    Posts
    29

    Default

    Hi Marten,

    thanks for your answer. That clears thinks up. Now i know why it takes so long. My problem is, that i have to develop for SQL-Server and Oracle, and that i start my application either to test it or to work with it. So i have a production database and a test database for sql-server as well as for oracle. That are 4 databases, 4 database connections, 4 sessionFactories :-(

    Is there a way to decide at runtime which beans to load? So that i can connect to the two production databases only while i start the application for working and connect to the test databases only for testing? Or can i load the connections and sessionFactories lazy? And how can i do that?

    Your help is much appreciated. Thanks.
    Christoph

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    Search the forum for PropertyPlaceHolderConfigurer. This lets you provide property files which include the settings. So either load the production one or load the testing one.

    That way your configuration would also be cut in half...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    PropertyPlaceHolderConfigurer is a great way of cutting down on config as Marten said. If you do really want to lazy init beans though, you can do this.
    http://www.springframework.org/docs/...tory-lazy-init

  6. #6
    Join Date
    Dec 2006
    Posts
    29

    Default

    thanks guys. I see that i have to cut my configuration in half. Setting default-lazy-init="true" doesnīt help, because all my beans depend upon each other, so by the time i load one eagerly, all other beans are loaded eagerly as well.

    I allready load all my connection parameters from a file called config.ini (iīm developing a rcp-application). So now i write two config.ini files one with the connection-properties for the production databases and the other one with the connection-properties for the test database. But what comes then? Do i have to rename the files each time i switch between production and testing? Or can i somehow set a condition in the applicationContext.xml loading the correct context.ini depending (for example) on a environment variable which i could set via my eclipse-launch-configuration.

    Is that possible?
    Thanks
    Christoph

  7. #7
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

  8. #8

    Default

    A short example:

    Code:
    <bean id="propertyConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:/${runtime_environment}.properties" />
    </bean>
    
    <bean id="batchContainerDataSource"
      class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
      scope="singleton" depends-on="propertyConfigurer">
    
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        ...
    </bean>
    then you can pass -Druntime_environment=TEST to your JVM and spring will look for the file TEST.properties

    -Patrick

  9. #9
    Join Date
    Dec 2006
    Posts
    29

    Default

    thanks for the link. I understand now, that i could reduce the number of datasources i define to 1 or 2 and decide via a property-file to which databases my programm should connect. But actually that is not what i want.

    For me it would be better to keep all 4 datasoures (and sessionFactories) defined in the applicationContext.xml file and decide at runtime which of these should be initialized and which should not.

    So i assume that i have to write my own custom BeanFactoryPostProcessor and edit the configuration after it has been loaded but before the beans are initialized. Right? Is it possible to delete certain bean definitions manually from the configuration and with that preventing them from being initialized? Or did i get this all wrong? Do you know where i can find an example of how this is done (if it is possible at all)?

    Thanks
    Christoph

  10. #10

    Default

    You may have a look at HotSwappableTargetSource (http://static.springframework.org/sp...getSource.html)
    or at LazyInitTargetSource (http://static.springframework.org/sp...getSource.html)



    -Patrick

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •