Announcement Announcement Module
Collapse
No announcement yet.
@Transactional doesn't work with HibernateTransactionManager Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • @Transactional doesn't work with HibernateTransactionManager

    Hi there,

    I'm gonna start a new application with Spring + Hibernate Annotation.
    I'm trying to use the @Transactional annotation in a Service layer but it is not work. Probably it's a configuration problem, but I didn't figure out the problem. Below following some pieces of my applicationContext.xml

    DataSource
    Code:
    	<!-- DataSource -->
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    		destroy-method="close">
    		<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
    		<property name="url" value="jdbc:hsqldb:hsql://localhost/XYZ" />
    		<property name="username" value="sa" />
    		<property name="password" value="" />
    	</bean>
    SessionFactory
    Code:
    	<bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect
    				</prop>
    				<prop key="hibernate.show_sql">true</prop>
    			</props>
    		</property>
    		<property name="annotatedClasses">
    			<list>
    				<value>MyAnnotatedClass
    				</value>
    			</list>
    		</property>
    	</bean>
    *Note: I'm using AnnotationSessionFactoryBean instead LocalSessionFactoryBean

    Transaction
    Code:
    	<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    	
    	<tx:annotation-driven transaction-manager="txManager"/>
    Also, within the Service Layer, I've got the @Transaction annotation.


    When I try to call the SAVE() method from Hibernate, nothing happens. If I start/commit the transaction manually (through sessionFactory.session.beginTransaction) it works fine. Hence, I guess the Spring Transaction Manager is not being called.

    Please, does anybody can help me?

    Thanks in advice

  • #2
    How are you calling save and please post a annotated service method. Also beware of the fact by default spring uses JdkDynamicProxies which only use interfaces (so if you don't follow the best practice of programming to interfaces it wont'work and you will either need to program to interfaces or use class proxing.)

    Comment


    • #3
      Hi Marten,

      Thanks for replaying my topic.

      Basically in my architecture I've got two interfaces (one for DAO and another one for SERVICE layer). The SessionFactory (created by Spring) is injected within the DAO, as well as the DAO is injected within SERVICE layer. Below following the code:

      DAO interface
      Code:
      public interface DAO {
        public void save(Person person);
      }
      PersonDAO implements DAO. Also, it has the Service annotation
      Code:
      @Service
      public class PersonDAO implements DAO {
        @AutoWire
        private SessionFactory factory; //object is injected
      
        public void save(Person person) {
          Session session = factory.openSession();
          session.save(person);
        }
      }
      PersonService interface
      Code:
      public interface {
        public void savePerson(Person person);
      }
      PersonServiceImpl. It's Service and Transactional annotations
      Code:
      @Transactional
      @Service
      public class PersonServiceImpl implements PersonService {
        @Autowire
        private DAO dao;
         
        public void savePerson(Person person) {
          dao.save(person);
        }
      }
      In theory, the Spring Transaction Manager would work into PersonServiceImpl, am I right?

      It is a simple example yet, but it is a pilot for the real application.

      Please, let me know if you find something wrong.

      Thanks in advice.

      Comment


      • #4
        I suggest you read the spring documentation.

        Basically don't use openSession that will always open a new hibernate session OUTSIDE of the control of spring. Use getCurrentSession instead.

        Also why is your dao a @Service it should be a @Repository.

        Comment


        • #5
          Thanks again Marten.

          Now it's working pretty well. Spring really lets our life easier

          Honestly I didn't know about the @Repository annotation. Also, I learned about the @Controller annotation, but in my pilot, I'm gonna use only the @Service and @Repository.

          Thanks for letting me know about them.

          Comment


          • #6
            Marten,

            I'm sorry, I made a mistake.
            The code above didn't work. Actually, I tried a "SELECT" and worked, but when I tried to persist the data I got the exception;

            org.springframework.transaction.CannotCreateTransa ctionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Cannot open connection
            Could you help me, please?

            Comment


            • #7
              Problem fixed!!

              Actually, the database wasn't running. We fixed the database server and everything is fine now.

              Thanks

              Comment

              Working...
              X