Announcement Announcement Module
Collapse
No announcement yet.
HibernateTemplate and transactions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • HibernateTemplate and transactions

    I'm having trouble with my HibernateTemplate derived class - it isn't committing transactions. The data changes appear to have been made until I restart my application server, but when I do that, they are gone. I'm pretty sure that the problem is that transactions are not being committed - but I was under the impression that HibernateTemplate took care if that sort of thing for you.

    I set up my template as so:

    Code:
        <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
            <property name="mappingDirectoryLocations">
                <list>
                    <value>classpath&#58;/uk/co/foobar/morph/dto</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">net.sf.hibernate.dialect.DB2400Dialect</prop>
                    <!-- etc... -->
                </props>
            </property>
        </bean>
    
        <bean id="hibernateTemplate" class="org.springframework.orm.hibernate.HibernateTemplate">
            <property name="sessionFactory">
                <ref bean="sessionFactory" />
            </property>
        </bean>
        
        <!-- Hibernate data transfer objects -->
    
        <bean class="uk.co.foobar.morph.dao.CompanyHibernateDAO" id="companyDAO">
            <property name="hibernateTemplate">
                <ref bean="hibernateTemplate"/>
            </property>
        </bean>
    My first cut Java looked like this:

    Code:
    public class CompanyHibernateDAO extends HibernateDaoSupport implements
            CompanyDAO &#123;
        public void saveCompany&#40;final Company company&#41; throws DAOException &#123;
            this.logger.debug&#40;"Saving company " + String.valueOf&#40;company&#41;&#41;;
            getHibernateTemplate&#40;&#41;.save&#40;company&#41;;
        &#125;
    &#125;
    As I said, this isn't committing. My next try was:

    Code:
        public void saveCompany&#40;final Company company&#41; throws DAOException &#123;
            this.logger.debug&#40;"Saving company " + String.valueOf&#40;company&#41;&#41;;
            getHibernateTemplate&#40;&#41;.save&#40;company&#41;;
            getSession&#40;&#41;.connection&#40;&#41;.commit&#40;&#41;;
        &#125;
    This seems to work fine. Unfortunately, getSession()'s JavaDoc specifically warns you off using it from HibernateTemplate. It advises you to use a HibernateCallback, which gives you a connection, so I tried:

    Code:
        public void saveCompany&#40;final Company company&#41; throws DAOException &#123;
            this.logger.debug&#40;"Saving company " + String.valueOf&#40;company&#41;&#41;;
            getHibernateTemplate&#40;&#41;.execute&#40;new HibernateCallback&#40;&#41; &#123;
                public Object doInHibernate&#40;Session session&#41;
                        throws HibernateException, SQLException &#123;
                    session.save&#40;company&#41;;
                    session.connection&#40;&#41;.commit&#40;&#41;;
                    return null;
                &#125;
            &#125;&#41;;
        &#125;
    This doesn't commit. :-(

    I also looked at HibernateTransactionManager, but I didn't see any way of using this with HibernateTemplate. It appears to be needed for more complex situations that mine, where you need more control over transactions, and don't use HibernateTemplate.

    BTW, I will need real transactions at some point, so I don't want to just use auto-commit and flush().

    What am I doing wrong? Is there a way of getting HibernateTemplate's convenience methods to commit transactions? If not, what are they for - and what should I do instead?

  • #2
    Re: HibernateTemplate and transactions

    Originally posted by Simon Brunning
    I also looked at HibernateTransactionManager, but I didn't see any way of using this with HibernateTemplate. It appears to be needed for more complex situations that mine, where you need more control over transactions, and don't use HibernateTemplate.
    You need to use HibernateTransactionManager in conjunction with HibernateTemplate to enable declarative transaction management. Take a look at this section of the Spring reference for more information.

    Comment


    • #3
      Fixed

      Fixed this with heml from jbalint and others on #spring. I just had to use a transaction manager and a transaction DAO proxy as follows:

      Code:
          <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
              <property name="mappingDirectoryLocations">
                  <list>
                      <value>classpath&#58;/uk/co/foobar/morph/dto</value>
                  </list>
              </property>
              <property name="hibernateProperties">
                  <props>
                      <prop key="hibernate.dialect">net.sf.hibernate.dialect.DB2400Dialect</prop>
                      <!-- etc... -->
                  </props>
              </property>
          </bean>
      
          <bean id="hibernateTemplate" class="org.springframework.orm.hibernate.HibernateTemplate">
              <property name="sessionFactory">
                  <ref bean="sessionFactory" />
              </property>
          </bean>
      
          <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
              <property name="sessionFactory">
                  <ref bean="sessionFactory"/>
              </property>
          </bean>
         
          <!-- Hibernate data transfer objects -->
      
          <bean class="uk.co.trisystems.morph.dao.CompanyHibernateDAO" id="wrappedCompanyDAO">
              <property name="hibernateTemplate">
                  <ref bean="hibernateTemplate"/>
              </property>
          </bean>
      
          <bean id="companyDAO" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
              <property name="transactionManager">
                  <ref bean="transactionManager"/>
              </property>
              <property name="target">
                  <ref bean="wrappedCompanyDAO"/>
              </property>
              <property name="transactionAttributes">
                  <props>
                      <prop key="saveCompany">PROPAGATION_REQUIRED</prop>
              </property>
          </bean>
      With this config, my original code worked fine. Thanks to all!

      Comment


      • #4
        Thanks for your prompt solution.

        Thanks for your prompt solution.

        Comment


        • #5
          ...

          my hibernate DAO structure is as

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
          <hibernate-configuration>
          <session-factory>
          <property name="hibernate.dialect">org.hibernate.dialect.Ora cleDialect</property>
          <property name="hibernate.connection.driver_class">oracle.jd bc.OracleDriver</property>
          <property name="hibernate.connection.url">jdbc:oracle:thin:@ 192.1.200.32:1521:orcl</property>
          <property name="hibernate.connection.username">****</property>
          <property name="hibernate.connection.password">****</property>
          <property name="current_session_context_class">thread</property>
          <mapping class="javaapplication42.Employee"/>
          </session-factory>
          </hibernate-configuration>


          Employee.java
          package javaapplication42;

          import java.io.Serializable;

          import javax.persistence.Column;
          import javax.persistence.Entity;
          import javax.persistence.Id;
          import javax.persistence.Table;

          @Entity
          @Table(name = "EMPLOYEE")
          public class Employee implements Serializable {
          public Employee() {

          }
          @Id
          @Column(name = "id")
          Integer id;

          public Employee(Integer id, String name) {
          this.id = id;
          this.name = name;
          }

          @Column(name = "name")
          String name;

          public Integer getId() {
          return id;
          }

          public void setId(Integer id) {
          this.id = id;
          }

          public String getName() {
          return name;
          }

          public void setName(String name) {
          this.name = name;
          }

          }


          EmployeeImpl.java
          package javaapplication42;

          public class EmployeeImpl extends BaseAbstractDao<Employee> implements EmployeeDao{

          /**
          * @param args the command line arguments
          */
          @Override
          public void saveEmployee(Employee employee) {
          System.out.println("in saveEmployee");
          super.saveOrUpdateEntity(employee);
          }
          public EmployeeImpl(){
          System.out.println("in EmployeeImpl");
          saveEmployee(new Employee(new Integer(1),"abc"));
          }
          }

          GenericDao.java
          package javaapplication42;

          public interface GenericDao <T> {
          public void saveOrUpdateEntity(T entity);

          }

          EmployeeDao.java
          package javaapplication42;

          /*
          * To change this template, choose Tools | Templates
          * and open the template in the editor.
          */



          /**
          *
          * @author jjoshi
          */
          public interface EmployeeDao extends GenericDao<Employee> {
          public void saveEmployee(Employee employee);

          }

          BaseAbstractDao.java
          package javaapplication42;




          import java.lang.reflect.ParameterizedType;
          import org.springframework.orm.hibernate3.HibernateTempla te;
          import org.springframework.orm.hibernate3.support.Hiberna teDaoSupport;

          public abstract class BaseAbstractDao<EntityType> extends HibernateDaoSupport implements GenericDao<EntityType> {
          private Class<EntityType> persistentClass;
          @SuppressWarnings("unchecked")
          public BaseAbstractDao() {
          super();
          this.persistentClass = (Class<EntityType>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeAr guments()[0];
          System.out.println("in BAseAbstractDao");
          }
          @Override
          public void saveOrUpdateEntity(EntityType entity) {

          System.out.println("output = "+getHibernateTemplate());
          System.out.println("in saveOrUpdate");
          }
          }

          HibernateUtil.java
          package javaapplication42;



          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.ResultSet;
          import java.sql.Statement;
          import org.hibernate.SessionFactory;
          import org.hibernate.cfg.AnnotationConfiguration;

          public class HibernateUtil {

          private Statement st;
          private static final SessionFactory sessionFactory;


          static {

          try {
          // Create the SessionFactory from hibernate.cfg.xml
          sessionFactory = new AnnotationConfiguration().configure().buildSession Factory();

          } catch (Throwable ex) {
          // Make sure you log the exception, as it might be swallowed
          System.err.println("Initial SessionFactory creation failed." + ex);
          throw new ExceptionInInitializerError(ex);
          }
          }

          public HibernateUtil() {
          try {
          Class.forName("oracle.jdbc.driver.OracleDriver");
          Connection con = DriverManager.getConnection("jdbc:oracle:thin:@192 .1.200.32:1521:orcl", "student", "student");
          st = con.createStatement();
          } catch (Exception e) {
          System.out.println(e);
          }
          }

          public static SessionFactory getSessionFactory() {
          return sessionFactory;
          }

          public ResultSet executeSQLCommand(String sql) throws Exception {


          return (st.executeQuery(sql));
          }
          }


          Main.java

          package javaapplication42;


          import org.hibernate.Session;
          import org.hibernate.SessionFactory;
          import org.hibernate.Transaction;
          public class main {
          public static void main(String[] args) {
          SessionFactory session = HibernateUtil.getSessionFactory();
          Session sess = session.getCurrentSession();
          /** Starting the Transaction */
          Transaction tx = sess.beginTransaction();
          System.out.println("Transaction is " +tx );
          System.out.println("Session is " +sess );
          EmployeeImpl ob= new EmployeeImpl();

          }

          }

          now i want to call methods from Spring bean instead of main...

          and i am going to make this a different project and need to inject this project in Spring's project what configuration i need to make ????

          Comment

          Working...
          X