Announcement Announcement Module
Collapse
No announcement yet.
Plain Hibernate3 API with Spring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Plain Hibernate3 API with Spring

    Hi,

    I use this context.xml :

    <beans>
    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
    <property name="url" value="jdbc:hsqldb:db/test"/>
    <property name="username" value="sa"/>
    <property name="password" value=""/>
    </bean>
    <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSes sionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
    <property name="mappingResources">
    <list>
    <value>events/model.hbm.xml</value>
    </list>
    </property>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.HSQL Dialect</prop>
    <prop key="hibernate.cache.provider_class">org.hibernate .cache.NoCacheProvider</prop>
    </props>
    </property>
    </bean>
    <bean id="testBean" class="TestBean" init-method="init" destroy-method="destroy">
    <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>
    </beans>

    TestBean code is:

    import org.hibernate.SessionFactory;

    public class TestBean {

    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
    }

    void init() {
    System.out.println(
    sessionFactory.getCurrentSession().createQuery("fr om Event").list());
    }

    }

    On running it I got:

    Exception in thread "main" org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'testBean' defined in class path resource [context.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    Caused by: 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.LocalSessionFac toryBean$TransactionAwareInvocationHandler.invoke( LocalSessionFactoryBean.java:1115)
    at $Proxy0.getCurrentSession(Unknown Source)
    at TestBean.init(TestBean.java:13)

    What's wrong?

  • #2
    first of all if you want to use getcurrentSession() method you need to add these properties to HibernateProperties:
    <prop key="hibernate.current_session_context_class">thre ad</prop>
    <prop key="hibernate.transaction.factory_class">org.hibe rnate.transaction.JDBCTransactionFactory</prop>

    second thing is from the exception, Hibernate3 doesn't allow you to run queries without starting a transaction. you have to add this to your init method before running the query:
    sessionFactory.getCurrentSession().beginTransactio n();
    and of course commit it in the end of your unit of work.

    Comment


    • #3
      Now I have this context.xml:

      <beans>
      <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
      <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
      <property name="url" value="jdbc:hsqldb:db/test"/>
      <property name="username" value="sa"/>
      <property name="password" value=""/>
      </bean>
      <bean id="myTxManager" class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
      <property name="sessionFactory" ref="mySessionFactory"/>
      </bean>
      <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSes sionFactoryBean">
      <property name="dataSource" ref="myDataSource"/>
      <property name="mappingResources">
      <list>
      <value>events/model.hbm.xml</value>
      </list>
      </property>
      <property name="hibernateProperties">
      <props>
      <prop key="hibernate.dialect">org.hibernate.dialect.HSQL Dialect</prop>
      <prop key="hibernate.cache.provider_class">org.hibernate .cache.NoCacheProvider</prop>
      <prop key="hibernate.current_session_context_class">thre ad</prop>
      <prop key="hibernate.transaction.factory_class">org.hibe rnate.transaction.JDBCTransactionFactory</prop>
      </props>
      </property>
      </bean>
      <bean id="testBean" class="TestBean" init-method="init">
      <property name="sessionFactory" ref="mySessionFactory"/>
      </bean>
      </beans>


      TestBean.java is:

      import org.hibernate.Session;
      import org.hibernate.SessionFactory;

      public class TestBean {

      private SessionFactory sessionFactory;

      public void setSessionFactory(SessionFactory sessionFactory) {
      this.sessionFactory = sessionFactory;
      }

      void init() {
      Session session = sessionFactory.getCurrentSession();
      session.beginTransaction();
      System.out.println(session.createQuery("from Event").list());
      session.getTransaction().commit();
      }

      }
      The error is the same:

      Exception in thread "main" org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'testBean' defined in class path resource [context.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
      Caused by: 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.LocalSessionFac toryBean$TransactionAwareInvocationHandler.invoke( LocalSessionFactoryBean.java:1115)
      at $Proxy0.getCurrentSession(Unknown Source)
      at TestBean.init(TestBean.java:15)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:585)
      at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.invokeCustomInitMethod( AbstractAutowireCapableBeanFactory.java:943)
      at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.invokeInitMethods(Abstr actAutowireCapableBeanFactory.java:905)
      at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean(Abstract AutowireCapableBeanFactory.java:870)
      at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:393)
      at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:256)
      at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:167)
      at org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons(Defaul tListableBeanFactory.java:253)
      at org.springframework.context.support.AbstractApplic ationContext.refresh(AbstractApplicationContext.ja va:332)
      at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:92)
      at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:77)
      at Server.main(Server.java:9)

      Comment


      • #4
        first of all if you want to use getcurrentSession() method you need to add these properties to HibernateProperties:
        <prop key="hibernate.current_session_context_class">thre ad</prop>
        <prop key="hibernate.transaction.factory_class">org.hibe rnate.transaction.JDBCTransactionFactory</prop>
        That is required if one wants to use the 'naked' Hibernate API without any Spring integration. SessionFactory.getCurrentSession() works if there is an ongoing transaction running; what the Spring error tells you is that there is no such transaction and a new one is not allowed to be started (see HibernateTemplate javadocs for more details on creating a thread-bound transaction when one is not already present).

        Thread-bound sessions have to be started/binded by somebody - and usually the simplest and easiest way is to let the transaction manager do that.
        You have properly declared a transaction manager inside your application context but you also have to specify where transactions are applied. I'd advice you to look in the reference documentation / Spring sample and mark the methods you are using as transactional.
        Once a method is running inside a transaction, a HB session will be bound to the thread before the method executes and getCurrentSession() will return it.

        Comment


        • #5
          Originally posted by Costin Leau
          You have properly declared a transaction manager inside your application context but you also have to specify where transactions are applied. I'd advice you to look in the reference documentation / Spring sample and mark the methods you are using as transactional
          How my context.xml is:


          <beans>
          <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
          <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
          <property name="url" value="jdbc:hsqldb:db/test"/>
          <property name="username" value="sa"/>
          <property name="password" value=""/>
          </bean>
          <bean id="myTxManager" class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
          <property name="sessionFactory" ref="mySessionFactory"/>
          </bean>
          <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
          <property name="transactionManager"><ref bean="myTxManager"/></property>
          <property name="transactionAttributes">
          <props>
          <prop key="init">PROPAGATION_REQUIRED</prop>
          </props>
          </property>
          <property name="target"><ref local="testBean"/></property>
          </bean>
          <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSes sionFactoryBean">
          <property name="dataSource" ref="myDataSource"/>
          <property name="mappingResources">
          <list>
          <value>events/model.hbm.xml</value>
          </list>
          </property>
          <property name="hibernateProperties">
          <props>
          <prop key="hibernate.dialect">org.hibernate.dialect.HSQL Dialect</prop>
          <prop key="hibernate.cache.provider_class">org.hibernate .cache.NoCacheProvider</prop>
          <prop key="hibernate.current_session_context_class">thre ad</prop>
          <prop key="hibernate.transaction.factory_class">org.hibe rnate.transaction.JDBCTransactionFactory</prop>
          </props>
          </property>
          </bean>
          <bean id="testBean" class="TestBean" init-method="init">
          <property name="sessionFactory" ref="mySessionFactory"/>
          </bean>
          </beans>

          TestBean.java is:

          import org.hibernate.Session;

          public class TestBean {

          private SessionFactory sessionFactory;

          public void setSessionFactory(SessionFactory sessionFactory) {
          this.sessionFactory = sessionFactory;
          }

          void init() {
          Session session = sessionFactory.getCurrentSession();
          session.beginTransaction();
          System.out.println(session.createQuery("from Event").list());
          session.getTransaction().commit();
          }

          }

          I run application with this startup class:

          import org.springframework.context.support.AbstractApplic ationContext;

          public class Server {

          public static void main(String[] args) throws InterruptedException {

          AbstractApplicationContext ctx =
          new ClassPathXmlApplicationContext(new String []{"context.xml"});
          ctx.registerShutdownHook();
          Thread.sleep(Long.MAX_VALUE);
          }

          }

          The error is the same:

          Exception in thread "main" org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'baseTransactionProxy' defined in class path resource [context.xml]: Cannot resolve reference to bean 'testBean' while setting bean property 'target'; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'testBean' defined in class path resource [context.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
          Caused by: org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'testBean' defined in class path resource [context.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
          Caused by: 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.LocalSessionFac toryBean$TransactionAwareInvocationHandler.invoke( LocalSessionFactoryBean.java:1115)
          at $Proxy0.getCurrentSession(Unknown Source)
          at TestBean.init(TestBean.java:13)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:585)
          at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.invokeCustomInitMethod( AbstractAutowireCapableBeanFactory.java:943)
          at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.invokeInitMethods(Abstr actAutowireCapableBeanFactory.java:905)
          at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean(Abstract AutowireCapableBeanFactory.java:870)
          at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:393)
          at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:256)
          at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:167)
          at org.springframework.beans.factory.support.BeanDefi nitionValueResolver.resolveReference(BeanDefinitio nValueResolver.java:219)
          at org.springframework.beans.factory.support.BeanDefi nitionValueResolver.resolveValueIfNecessary(BeanDe finitionValueResolver.java:115)
          at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.applyPropertyValues(Abs tractAutowireCapableBeanFactory.java:798)
          at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.populateBean(AbstractAu towireCapableBeanFactory.java:589)
          at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:389)
          at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:256)
          at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:167)
          at org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons(Defaul tListableBeanFactory.java:253)
          at org.springframework.context.support.AbstractApplic ationContext.refresh(AbstractApplicationContext.ja va:332)
          at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:92)
          at org.springframework.context.support.ClassPathXmlAp plicationContext.<init>(ClassPathXmlApplicationCon text.java:77)
          at Server.main(Server.java:9)

          What's wrong in my context.xml?

          Comment


          • #6
            What's wrong in my context.xml?
            A number of things. First you are trying to use Hibernate.getCurrentSession() when no tx is started.
            void init() {
            Session session = sessionFactory.getCurrentSession();
            session.beginTransaction();
            System.out.println(session.createQuery("from Event").list());
            session.getTransaction().commit();
            }
            Even though your are using Spring transaction demarcation you are trying also to use Hibernate transcations by hand - why is that? Your code doesn't handle the case of an exception and you'll never have rollback - basically if an exception is thrown in list() your transaction will never be closed.
            Moreover, assuming that what you do is correct, you are first trying to get a hold of the currentSession and then starting a transaction - you should do the other way around.

            As for the application context you are wrapping the bean inside a proxy but you are not using the proxy but actually the original bean. Do not execute code inside the init method - the init method is used for creating the bean - only after that one should execute methods on the bean.

            Here is a reworked application context:


            Code:
            <beans>
                <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
                    <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
                    <property name="url" value="jdbc:hsqldb:db/test"/>
                    <property name="username" value="sa"/>
                    <property name="password" value=""/>
                </bean>
                <bean id="myTxManager" class="org.springframework.orm.hibernate3.Hibernat  eTransactionManager">
                    <property name="sessionFactory" ref="mySessionFactory"/>
                </bean>
                <bean id="transactionProxy" class="org.springframework.transaction.interceptor  .TransactionProxyFactoryBean">
                    <property name="transactionManager"><ref bean="myTxManager"/></property>
                    <property name="transactionAttributes">
                        <props>
                            <prop key="*">PROPAGATION_REQUIRED</prop>
                        </props>
                    </property>
                    <property name="target">
               <bean  class="TestBean">
                 <property name="sessionFactory" ref="mySessionFactory"/>
               </bean>    
            </property>
                </bean>
                <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSes  sionFactoryBean">
                    <property name="dataSource" ref="myDataSource"/>
                    <property name="mappingResources">
                        <list>
                            <value>events/model.hbm.xml</value>
                        </list>
                    </property>
                    <property name="hibernateProperties">
                        <props>
                            <prop key="hibernate.dialect">org.hibernate.dialect.HSQL  Dialect</prop>
                            <prop key="hibernate.cache.provider_class">org.hibernate  .cache.NoCacheProvider</prop>
            </props>
                    </property>
                </bean>
                
            </beans>
            Note that I've moved the bean definition inside the TransactionalProxy as an inner bean (a good way of preventing access to the unproxied bean).

            As for your code you could do something like this:

            Code:
            public class Server {
            
                public static void main(String[] args) throws Exception {
                    
                    AbstractApplicationContext ctx = 
                        new ClassPathXmlApplicationContext(new String []{"context.xml"});
            
            TestBean bean = (TestBean) ctx.getBean("transactionProxy");
            bean.doSmth();
            ctx.close();
            }
            
            }
            where TestBean is:
            Code:
            import org.hibernate.Session;
            
            public class TestBean extends HibernateDaoSupport {
                
            public void doSmth() {
                    Session session = sessionFactory.getCurrentSession();
            System.out.println(session.createQuery("from Event").list());
            }
                
            }
            You can see that the code is quite smaller and cleaner - this is where Spring power lies. I strongly suggest (again) to take a look at the samples provided with the Spring distribution and to take the time to read the reference documentation. It's a great way to learn how Spring works (makes your life easier). You have also plenty of book and a quick google will give you plenty of tutorials with code included (try springhub.com for example).

            Comment


            • #7
              Great thanks. But now problem is in this code:

              Originally posted by Costin Leau
              Code:
              public class Server {
              
                  public static void main(String[] args) throws Exception {
                      
                      AbstractApplicationContext ctx = 
                          new ClassPathXmlApplicationContext(new String []{"context.xml"});
              
              TestBean bean = (TestBean) ctx.getBean("transactionProxy");
              bean.doSmth();
              ctx.close();
              }
              
              }
              On line with TestBean bean = (TestBean) ... I got:

              15:40:25,713 INFO DefaultAopProxyFactory:59 - CGLIB2 available: proxyTargetClass feature enabled
              Exception in thread "main" java.lang.ClassCastException: $Proxy1
              at Server.main(Server.java:10)

              Comment


              • #8
                add
                <property name="proxyTargetClass" value="true">
                to your bean TransactionProxyFactoryBean definition.

                Comment


                • #9
                  I started by looking at the examples, particularly in the Spring reference around Hibernate, and at the Hibernate Annotations. I set up the following context. At first, I did not have the transaction-related entries, as those were not indicated in the reference manual. But after reading this post, I decided to add them. However, I still get the same result when I call getSession(false): "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here." (BTW, I also tried getSessionFactory().getCurrentSession(); same result).

                  Note: Is there some disconnect between the trailDao bean I create and the transaction manager's view onto the Trail class?

                  What am I still missing? Thanks.

                  Code:
                  	<bean id="primaryDS" class="org.springframework.jndi.JndiObjectFactoryBean"> 
                  		<property name="jndiName" value="java:comp/env/jdbc/myapp"/> 
                  	</bean>
                  
                  	<bean id="primarySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
                  		<property name="dataSource" ref="primaryDS"/>
                  		<property name="annotatedClasses">
                  			<list>
                  				<value>com.mycompany.myapp.bus.Trail</value>
                  			</list>
                  		</property>
                  	</bean>
                   	
                  	<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
                  		<property name="sessionFactory" ref="primarySessionFactory"/>
                  	</bean>
                   	
                  	<bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
                  		<property name="transactionManager" ref="txManager"/>
                  		<property name="transactionAttributes">
                  			<props>
                  				<prop key="*">PROPAGATION_REQUIRED</prop>
                  			</props>
                  		</property>
                  		<property name="target">
                  			<bean class="com.mycompany.myapp.bus.Trail">
                  				<property name="sessionFactory" ref="primarySessionFactory"/>
                  			</bean>    
                  		</property>
                  	</bean>
                  	
                  	<bean id="trailDao" class="com.mycompany.myapp.bus.Trail"> 
                  		<property name="sessionFactory" ref="primarySessionFactory"/> 
                  	</bean>
                  	
                  	<bean id="uploadForm"					class="com.mycompany.myapp.controller.Upload">
                  		<!--property name="sessionForm"><value>true</value></property-->
                  		<property name="commandName"><value>upload</value></property>
                  		<property name="commandClass"><value>com.mycompany.myapp.bus.FileUploadBean</value></property>
                  		<!-- property name="validator"><ref bean="priceIncreaseValidator"/></property -->
                  		<property name="formView"><value>upload</value></property>
                  		<property name="successView"><value>home</value></property>
                  		<property name="trail" ref="trailDao"/>
                  	</bean>

                  The intent is that the Spring container create a bean (my Trail DAO) with a reference to the sessionFactory, pass it to the Upload Form, and then the Trail object can get the session when it executes its save() method. Here's the Trail class (elided):

                  Code:
                  package com.mycompany.myapp.bus;
                  
                  
                  
                  //
                  //	Java Imports
                  //
                  
                  import java.util.ArrayList;
                  import java.util.Calendar;
                  import java.util.List;
                  
                  import javax.persistence.Entity;
                  import javax.persistence.Id;
                  import javax.persistence.Temporal;
                  import javax.persistence.TemporalType;
                  
                  
                  //
                  //	Third-party Imports
                  //
                  
                  import org.apache.log4j.Logger;
                  
                  import org.hibernate.Session;
                  
                  import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
                  
                  
                  
                  
                  
                  
                  @Entity
                  public
                  class
                  Trail extends HibernateDaoSupport
                  {
                  	public
                  	Trail()
                  	{
                  	}
                  	
                  	@Id
                  	public	Integer			getId()							{ return mID; }
                  	public	void			setId(Integer inVal)			{ mID = inVal; }
                  	
                  	@Temporal(TemporalType.TIMESTAMP)
                  	public	Calendar		getUploadTime()					{ return mTime; }
                  	public	void			setUploadTime(Calendar inVal)	{ mTime = inVal; }
                  	
                  	public	String			getName()						{ return mName; }
                  	public	void			setName(String inVal)			{ mName = inVal; }
                  	
                  	
                  	public
                  	void
                  	save()
                  	{
                  		sLogger.debug("SessionFactory: " + getSessionFactory());
                  		Session session = getSession(false);
                  		
                  		session.save(this);
                  	}
                  	
                  	private	Integer			mID;
                  	private	Calendar		mTime;
                  	private	String			mName;
                  	
                  	private	static	Logger	sLogger							=	Logger.getLogger(Trail.class);
                  }
                  Last edited by jetforme; Aug 24th, 2006, 01:44 PM.

                  Comment


                  • #10
                    Inside your configuration you declare two beans of type Trail - one if transactionalProxy (which has a tx proxy around it) and one is trailDao which doesn't have any tx behavior.
                    In order to use getSession() you have to have an ongoing tx (this is the Hibernate contract) - so in your case use the transactionProxy which will start a tx.

                    Comment


                    • #11
                      a similar problem here.

                      ENP:

                      You have to start a transaction before you can use getCurrentSession().

                      If your using spring2, the annotation way of handleing transactions is very cool.

                      I'd help you through it, but I'm having problems of my own with it, I'm having a similar problem with spring2-rc3

                      ok, we have this setup.

                      <!-- enable the configuration of transactional behavior based on annotations -->
                      <tx:annotation-driven transaction-manager="txManager"/>

                      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
                      <property name="driverClassName" value="org.postgresql.Driver"/>
                      <property name="url" value="jdbcostgresql://localhost/equipment" />
                      <property name="username" value="postgres" />
                      <property name="password" value="password" />
                      </bean>

                      <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotati on.AnnotationSessionFactoryBean">
                      <property name="dataSource" ref="dataSource" />
                      <property name="hibernateProperties">
                      <props>
                      <prop key="hibernate.dialect">org.hibernate.dialect.Post greSQLDialect</prop>
                      <prop key="hibernate.hbm2ddl.auto">update</prop>
                      </props>
                      </property>
                      <property name="annotatedClasses">
                      <list>
                      <value>nz.co.nepenthe.brett.equipment.entity.Playe r</value>
                      <value>nz.co.nepenthe.brett.equipment.entity.Conta iner</value>
                      <value>nz.co.nepenthe.brett.equipment.entity.Categ ory</value>
                      <value>nz.co.nepenthe.brett.equipment.entity.ItemT ype</value>
                      <value>nz.co.nepenthe.brett.equipment.entity.Ite m</value>
                      </list>
                      </property>
                      </bean>

                      <!-- add a transaction manager -->
                      <bean id="txManager" class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
                      <property name="sessionFactory" ref="sessionFactory"/>
                      </bean>

                      <bean id="itemManager" class="nz.co.nepenthe.brett.equipment.manager.impl .ItemManagerImpl">
                      <property name="sessionFactory" ref="sessionFactory"/>
                      </bean>



                      which starts the session factory just fine (the database has the tables added without a problem....)

                      we have a ItemManager interface

                      public interface ItemManager {

                      @Transactional(readOnly=false)
                      void saveCategory(Category category);

                      }


                      we have our implementation...

                      public class ItemManagerImpl implements ItemManager {

                      private SessionFactory sessionFactory;

                      public void setSessionFactory(SessionFactory sessionFactory) {
                      this.sessionFactory = sessionFactory;
                      }

                      public void saveCategory(Category category) {
                      Session session = sessionFactory.getCurrentSession();
                      session.save(category);
                      }

                      }



                      the main program is

                      public static void main(String[] args) {
                      ClassPathResource resource = new ClassPathResource("/applicationContext.xml");
                      BeanFactory factory = new XmlBeanFactory(resource);
                      ItemManager itemManager = (ItemManager) factory.getBean("itemManager");

                      Category cat = new Category();
                      cat.setName("Blurgh");

                      itemManager.saveCategory(cat);
                      System.out.println(cat.getId());
                      }


                      but... we are still getting

                      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.LocalSessionFac toryBean$TransactionAwareInvocationHandler.invoke( LocalSessionFactoryBean.java:1175)
                      at $Proxy7.getCurrentSession(Unknown Source)
                      at nz.co.nepenthe.brett.equipment.manager.impl.ItemMa nagerImpl.saveCategory(ItemManagerImpl.java:30)
                      at nz.co.nepenthe.brett.equipment.bin.Main.main(Main. java:36)




                      I've tried adding

                      <prop key="hibernate.current_session_context_class">thre ad</prop>
                      <prop key="hibernate.transaction.factory_class">org.hibe rnate.transaction.JDBCTransactionFactory</prop>

                      to the hibernate properities, but it doesn't seem to make a difference.

                      The wierd part is I've got this sort of thing working a number of times before, so I must be doing something fairly thick. Any suggestions anyone?

                      Comment


                      • #12
                        How in the earth can you make the code you describe earlier works if you cannot use setSessionFactory together with HibernateDaoSupport?

                        import org.hibernate.Session;

                        public class TestBean extends HibernateDaoSupport {

                        public void doSmth() {
                        Session session = sessionFactory.getCurrentSession();
                        System.out.println(session.createQuery("from Event").list());
                        }

                        }
                        In this case sessionFactory is null.

                        Thanks.

                        Comment


                        • #13
                          You don't need to do what that code does since you are extending HibernateDaoSupport. You can simply call getSessionFactory(). You do need to ensure however that you are either injecting in the SessionFactory or a HibernateTemplate.
                          http://www.springframework.org/docs/...ssionFactory()

                          Comment


                          • #14
                            I got it going - but it was long enough ago I can't remember what I was doing wrong.

                            I should have posted back.

                            Comment


                            • #15
                              Oh, NOW I remember....

                              this was a tricky one!

                              XMLBeanFactory DOESN'T do AOP, you need to use ApplicationContext

                              the transaction annotations didn't fire up and thats what caused the error.

                              apart from that it works

                              --- Blair

                              Comment

                              Working...
                              X