Announcement Announcement Module
Collapse
No announcement yet.
Spring 3 - Jboss 7 - Hibernate 4 (JPA) - SQL SERVER - Reconnect when DB is down Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring 3 - Jboss 7 - Hibernate 4 (JPA) - SQL SERVER - Reconnect when DB is down

    Hello everybody,

    First, sorry for my english, I'm not a native speaker, i'll do my best though.

    I'm facing a problem since a few days that I 'm really not able to solve even after loads of researchs.

    My aim is quite simple : make my Spring/hibernate (running under JBOSS AS7) application able to automatically reconnect to its database when the connection is lost (server or network down ...). The only thing is that I wanna keep database credentials outside the EAR, to wit pointing on a JNDI datasource configured in JBOSS (because I have several components using the same DB in the whole application, I don't wanna have to recompile the project each time I publish the thing on my client's servers).

    The database is running under SQL Server 2008 and I'm using the sqljdbc4 driver from Microsoft.

    I did the trick using c3p0 but the solution didn't fit my needs because I was obliged to define DB credentials inside the applicationContext.xml.

    Therefore I tried to configure a connection pool under JBOSS like this :

    Code:
     
     
    <datasource jndi-name="java:jboss/datasources/MyDataSource" pool-name="MyPoolName" enabled="true" use-java-context="true">
                        <connection-url>jdbc:sqlserver://******</connection-url>
                        <driver>sqljdbc4.jar</driver>
                        <pool>
                            <min-pool-size>10</min-pool-size>
                            <max-pool-size>100</max-pool-size>
                            <prefill>true</prefill>
                        </pool>
                        <security>
                            <user-name>***</user-name>
                            <password>****</password>
                        </security>
                        <validation>
                            <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker"/>
                        </validation>
                    </datasource>
    My applicationContext.xml is configured this way, with a transaction manager being passed a entityManagerFactory previously initialized with my JNDI datasource :

    Code:
     
     
    <beans 
    	xmlns="http://www.springframework.org/schema/beans" 
    	xmlns:context="http://www.springframework.org/schema/context" 
    	xmlns:tx="http://www.springframework.org/schema/tx" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns:jee="http://www.springframework.org/schema/jee"
    	xsi:schemaLocation="
    		http://www.springframework.org/schema/beans       
    		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd       
    		http://www.springframework.org/schema/tx       
    		http://www.springframework.org/schema/tx/spring-tx-3.0.xsd       
    		http://www.springframework.org/schema/context      
    		http://www.springframework.org/schema/context/spring-context-3.0.xsd
    		http://www.springframework.org/schema/jee
    		http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
    		">
     
    		<jee:jndi-lookup id="myDataSource" jndi-name="jboss/datasources/MyDataSource"/>
     
     
     
        <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
          <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
          </property>
        	<property name="persistenceUnitName" value="MyPersistenceUnit"/>
        	<property name="dataSource" ref="myDataSource"/>
        </bean>
     
        <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory"/>
        </bean>
     
        <!--bean post-processor for JPA annotations-->
        <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
     
        <!--Exception translation bean post processor-->
        <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
     
         <!-- enable the configuration of transactional behavior based on annotations -->
        <tx:annotation-driven transaction-manager="transactionManager"/>   
     
    </beans>
    Besides, I use an OpenEntityManagerInViewFilter, I tried to disable it with no success.

    I configured my persistence unit this way :

    Code:
     
     
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence 
    	version="2.0" 
    	xmlns="http://java.sun.com/xml/ns/persistence" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
     
    	<persistence-unit name="MyPersistenceUnit" transaction-type="RESOURCE_LOCAL">
     
    		<provider>org.hibernate.ejb.HibernatePersistence</provider>
     
    <class>...mes entit�s...</class>		
     
    		<properties>
     
     
    			<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
    			<property name="hibernate.show_sql" value="false" />
    			<property name="hibernate.format_sql" value="false" />
     
    		</properties>
    	</persistence-unit>
    </persistence>
    Here is the way I inject the persistence context in my DAOs :

    Code:
     @PersistenceContext( type = PersistenceContextType.EXTENDED )
      protected EntityManager em;
    Here is the way I annotate my services :

    Code:
     
     
    @Service( "userCredentialService" )
    @Scope(value="session")
    @Transactional( propagation = Propagation.REQUIRED )
    public class UserCredentialSpringService {
     
    (...)
     
    @Transactional( propagation = Propagation.NEVER )
      public Utilisateur tryLogUser(String loggin, String password) throws Exception {
     
        Utilisateur u = getDao().findUtilisateurByLogginAndPassword(loggin, password);
     
        if ( u == null ) {
          throw new UserCredentialsIncorrectException(loggin, password);
        }
     
        if(!u.getNeutralise()){
          throw new UserNotActiveException(loggin);
        }
     
        return u;
      }
     
    }
    Here it is, then when the connection is lost, an Exception is thrown (that's ok) but when I do reconnect the network, I still have the same Exception and I'm obliged to restart JBOSS (in client's production environment this is not really convenient...)

    Thank you for your help guys.
Working...
X