Announcement Announcement Module
Collapse
No announcement yet.
transaction problem updating a standalone Java/Hibernate/MySQL app to Spring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • transaction problem updating a standalone Java/Hibernate/MySQL app to Spring

    So I'm trying to transmorgify a working standalone Java/Hibernate/MySQL app to use Spring.
    I've got this far by cutting and pasting snippets from all over cyberspace and RTFMing a bit:

    ApplicationContext.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-3.0.xsd">
               
      <context:annotation-config/>
                   
      <!-- Database Configurations -->
      <bean id="dataSourceB_C3P0"
         class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
         <property name="driverClass"     value="com.mysql.jdbc.Driver" />
         <property name="jdbcUrl"         value="jdbc:mysql://localhost:3306/dsmo" />
         <property name="user"            value="root" />
         <property name="password"        value="xxxxxxxx" />
         <property name="minPoolSize"     value="5" />
         <property name="maxPoolSize"     value="20" />
         <property name="maxIdleTime"     value="600" />
         <property name="maxStatements"   value="50" />
      </bean>
                   
      <!-- Hibernate session factories -->
      <bean id="sessionFactoryB"
         class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
         <property name="dataSource"        ref="dataSourceB_C3P0" />
         <property name="hibernateProperties">
           <props>
             <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
             <prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
             <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
             <prop key="hibernate.connection.releaseMode">after_transaction</prop>
             <prop key="hibernate.show_sql">false</prop>
             <prop key="hibernate.format_sql">true</prop>
             <prop key="hibernate.hbm2dll.auto">update</prop>
           </props>
         </property>
         <property name="annotatedClasses">
           <set>
             <value>dsmo.model.State</value>
           </set>
         </property>
      </bean>
    
      <!-- transaction manager -->
      <bean id="txManager"
         class="org.springframework.orm.hibernate3.HibernateTransactionManager">
         <property name="sessionFactory"      ref="sessionFactoryB" />
      </bean>
    
      <bean id="stateDAO"
         class="dsmo.dao.hibernate.StateDAOHibernate"
         scope="prototype">
         <property name="sessionFactory"      ref="sessionFactoryB" />
      </bean>
    
    </beans>
    and
    StateDAOHibernate
    Code:
    package dsmo.dao.hibernate;
    
    import org.hibernate.*;
    import org.springframework.transaction.annotation.Transactional;
    
    import dsmo.model.State;
    import dsmo.dao.StateDAO;
    
    import static org.hibernate.criterion.Expression.*;
    
    import java.util.*;
    
    public class StateDAOHibernate implements StateDAO
    {   
        private SessionFactory sessionFactory;
    
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }
        
      @SuppressWarnings("unchecked")
      @Transactional
      public List<State> getAll()
      {
        List<State> results = null;
        State result = null;
        String sqlcmd;
        
        sqlcmd = " FROM State ";
        Query hqlQuery = sessionFactory.getCurrentSession().createQuery( sqlcmd); // <-- barfs here
        results = hqlQuery.list();
        
        return results;
      }
    
      @Transactional
      @SuppressWarnings("unchecked")
      public SortedSet<String> putCodesInSet()
      {
        SortedSet<String> out_sset = new TreeSet<String>();
        List<State> results = null;
        State result = null;
        String sqlcmd;
        
        sqlcmd = " FROM State ";
        Query hqlQuery = sessionFactory.getCurrentSession().createQuery( sqlcmd); // HQL uses CLASS names not TABLE names
        results = hqlQuery.list();
        for( State st : results) {
            out_sset.add( st.getCode());
        }
    
        return out_sset;
      }
    
      @Transactional
      @SuppressWarnings("unchecked")
      public State getUniqueObj( String aa)
      {
        List<State> results = null;
        State result = null;
        String sqlcmd;
        
        sqlcmd = " FROM State WHERE code = :kxa ";
        Query hqlQuery = sessionFactory.getCurrentSession().createQuery( sqlcmd); // HQL uses CLASS names not TABLE names
        hqlQuery.setParameter( "kxa", aa);
        results = hqlQuery.list();
        if( results.size() == 1) {
            result = results.get(0);
        }
        
        return result;
      }
    
    }
    and StateDAO
    Code:
    package dsmo.dao;
    
    import dsmo.model.*;
    
    import java.util.*;
    
    public interface StateDAO
    {
      public List<State> getAll();
      public SortedSet<String> putCodesInSet();
      public State getUniqueObj( String aa);
    }
    and finally my app
    TheNewApp.java
    Code:
    package dsmo.model;
    
    import org.hibernate.*;
    import org.hibernate.Query;
    import org.hibernate.cfg.*;
    import org.hibernate.context.ManagedSessionContext;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import javax.persistence.*;
    
    import java.io.*;
    import java.util.*;
    import java.lang.reflect.*;
    import java.math.BigDecimal;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.text.DecimalFormat;
    import java.net.*;
    import java.security.MessageDigest;
    import java.sql.*;
    
    import dsmo.model.*;
    import dsmo.dao.*;
    import dsmo.dao.hibernate.*;
    
    public class TheNewApp
    {
        ArrayList<String> error_list;
        LinkedList<String> innrec_list, outrec_list;
    
        public static void main( String[] args)
        {
            String inn_str, tmp_str, roww;
            ArrayList<String> error_list;
     
            ApplicationContext ctx = new ClassPathXmlApplicationContext("ApplicationContext.xml");
     
            StateDAO    aStateDAO    = (StateDAO)    ctx.getBean("stateDAO");
            DistrictDAO aDistrictDAO = (DistrictDAO) ctx.getBean("districtDAO");
            SchoolDAO   aSchoolDAO   = (SchoolDAO)   ctx.getBean("schoolDAO");
           
            System.out.println("got to A");
            
            java.util.List<State> list_states = aStateDAO.getAll();   // <-- barfs here
            System.out.println("got to B");
            ListIterator<State> mi = list_states.listIterator();
            while( mi.hasNext()) {
                System.out.println( mi.next().getCode() );
            }
            
            System.out.println("got to C");
                         
        }
        
    }
    but the app barfs on the line indicated with the following stacktrace
    Code:
    Exception in thread "main" org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    	at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
    	at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:544)
    	at dsmo.dao.hibernate.StateDAOHibernate.getAll(StateDAOHibernate.java:37)
    	at dsmo.model.TheNewApp.main(TheNewApp.java:67)
    so something's messed-up or incomplete with my configuration but I can't spot it (hmmm, time to RTM more). Like getting my transaction manager to hand out sessions (or have the sessions handled by transactions?)
    In the meantime can someone tell me what I need to get this working?

    TIA,

    Still-learning Stuart

  • #2
    You have @Transactional but have nothing in your configuration which does something with it. (I suggest a read of the tx chapter, maybe again). Add a tx:annotation-driven to make the @Transactional work.

    Comment


    • #3
      Thanks for your advice, it gave me the hint I needed to get it to work. Just a simple addition to the ApplicationContext.xml
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:util="http://www.springframework.org/schema/util"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                 http://www.springframework.org/schema/context
                 http://www.springframework.org/schema/context/spring-context-2.0.xsd
                 http://www.springframework.org/schema/util
                 http://www.springframework.org/schema/util/spring-util-2.0.xsd
                 http://www.springframework.org/schema/tx
                 http://www.springframework.org/schema/tx/spring-tx-2.0.xsd>
              
        <!-- Database Configurations -->
        <bean id="dataSourceB_C3P0"
           class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
           <property name="driverClass"     value="com.mysql.jdbc.Driver" />
           <property name="jdbcUrl"         value="jdbc:mysql://localhost:3306/dsmo" />
           <property name="user"            value="root" />
           <property name="password"        value="see28saw" />
           <property name="minPoolSize"     value="5" />
           <property name="maxPoolSize"     value="20" />
           <property name="maxIdleTime"     value="600" />
           <property name="maxStatements"   value="50" />
        </bean>
                     
        <!-- Hibernate session factories -->
        <bean id="sessionFactoryB"
           class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
           <property name="dataSource"        ref="dataSourceB_C3P0" />
           <property name="hibernateProperties">
             <props>
               <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
               <prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
               <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
               <prop key="hibernate.connection.releaseMode">after_transaction</prop>
               <prop key="hibernate.show_sql">false</prop>
               <prop key="hibernate.format_sql">true</prop>
               <prop key="hibernate.hbm2dll.auto">update</prop>
             </props>
           </property>
           <property name="annotatedClasses">
             <set>
               <value>dsmo.model.UniqueLongIdGenerator</value>
               <value>dsmo.model.UsedRandomInteger</value>
               <value>dsmo.model.State</value>
               <value>dsmo.model.District</value>
               <value>dsmo.model.School</value>
             </set>
           </property>
        </bean>
      
        <!-- transaction manager -->
        <bean id="txManager"
           class="org.springframework.orm.hibernate3.HibernateTransactionManager">
           <property name="sessionFactory"      ref="sessionFactoryB" />
        </bean>
        
        <tx:annotation-driven transaction-manager="txManager" />   // <-- added this
      
        <bean id="stateDAO"
           class="dsmo.dao.hibernate.StateDAOHibernate"
           scope="prototype">
           <property name="sessionFactory"      ref="sessionFactoryB" />
        </bean>
      
        <bean id="districtDAO"
           class="dsmo.dao.hibernate.DistrictDAOHibernate"
           scope="prototype">
           <property name="sessionFactory"      ref="sessionFactoryB" />
        </bean>
      
        <bean id="schoolDAO"
           class="dsmo.dao.hibernate.SchoolDAOHibernate"
           scope="prototype">
           <property name="sessionFactory"      ref="sessionFactoryB" />
        </bean>
      
      </beans
      WOOHOO, my first Java/Spring/Maven/Hibernate/MySQL app runs!
      Thanks again for your reply.

      CASE CLOSED :-)

      Still-learning Stuart

      Comment

      Working...
      X