Transaction Management in Spring 3.x and Hibernate

2019-03-22 08:15发布

Hi I have faced a wall while I was trying to do transaction management using Spring 3.x and Hibernate 4.
I've searched on the Internet but there were ways to do this in Hibernate 3, not so many in Hibernate 4.
I'm quite confused and I'm not sure if this setting is working.

Things I'm using...
Spring 3.x
Hibernate 4

I've read these
http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html#transaction-declarative
spring, hibernate and declarative transaction implementation: there is no active transaction
and some more...

Follow up
I've managed to run my classes successfully. I've added proxy-target-class="true" to

<aop:config>


But I'm not sure if this is running in transaction. It says true when I use

TransactionSynchronizationManager.isActualTransactionActive()

but when I intentionally throw an error inside the save method, it would not rollback.

EDIT
As suggested by NimChimpsky, I tried invoking the same method through Spring MVC(dispatcher servlet) and it says

    Cannot convert value of type 
[$Proxy19 implementing kr.co.sgis.services.web.cooingbee.Crudable,org.springframework.aop.SpringProxy,
org.springframework.aop.framework.Advised] to required type
[test.TXTestDAO] for property 'dao': 
no matching editors or conversion strategy found


I hope I'm getting closer.

EDIT
log4j says this.

INFO : org.hibernate.Version - HHH000412: Hibernate Core {4.1.7.Final}
INFO : org.hibernate.cfg.Configuration - HHH000041: Configured SessionFactory: null
INFO : com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1bqomxn8s1l3dkxojzz69x|e4865ce, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1bqomxn8s1l3dkxojzz69x|e4865ce, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://211.115.111.229:3306/yoursmart, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 50, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
INFO : org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
INFO : org.hibernate.engine.jdbc.internal.LobCreatorBuilder - HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
INFO : org.hibernate.engine.transaction.internal.TransactionFactoryInitiator - HHH000399: Using default transaction strategy (direct JDBC transactions)
INFO : org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory - HHH000397: Using ASTQueryTranslatorFactory


It does say ' Configured SessionFactory: null' and 'TransactionFactoryInitiator - HHH000399: Using default transaction strategy (direct JDBC transactions)' but how does c3p0 connection pool initialise without errors?

My spring application context looks like this.

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource"><ref bean="dataSource"/></property>
    <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
    </property>

</bean>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="****"></property>
    <property name="user" value="****"></property>
    <property name="password" value="****"></property>
    <property name="initialPoolSize"><value>3</value></property>
    <property name="minPoolSize"><value>3</value></property>
    <property name="maxPoolSize"><value>50</value></property>
</bean>

<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
</bean>


<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
    <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

<bean id="txDAO" class="test.TXTestDAO">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
<bean id="testTxService" class="test.TXTestService">
        <property name="dao" ref="txDAO"/>
    </bean>


hibernate.cfg.xml

         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
         <property name="connection.url">****</property>
         <property name="connection.username">****</property>
         <property name="connection.password">****</property>
         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
         <property name="connection.pool_size">5</property>
         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
          <property name="hibernate.c3p0.min_size">5</property>
          <property name="hibernate.c3p0.max_size">20</property>
          <property name="hibernate.c3p0.timeout">300</property>
          <property name="hibernate.c3p0.max_statements">50</property>
          <property name="hibernate.c3p0.idle_test_period">3000</property>



TXTestDAO.java
My DAO does not implement HibernateDAOSupport. Do I have to implement it ?

public int save(CooingbeeFetchable bean) {
        // TODO Auto-generated method stub
        try{

            sessionFactory.getCurrentSession().getTransaction().begin();
            //Using sessionFactory is low level
            sessionFactory.getCurrentSession().save(bean);

            sessionFactory.getCurrentSession().getTransaction().commit();
            System.out.println("committed");

        }catch(Exception e){
            e.printStackTrace();
        }
        return 0;
    }


My test class
I just used FileSystemResource for testing.

public class Tester {       
public static void main(String[] args){

            FileSystemResource fSysSrc = new FileSystemResource("C:\\SGI_Project\\eclipseWorkspace\\SPSWeb\\WebContent\\WEB-INF\\SpringDispatcher-servlet.xml");
            BeanFactory xmlBeanFactory = new XmlBeanFactory(fSysSrc);
            TXTestService txDAO= (TXTestService) xmlBeanFactory.getBean("testTxService");

            TXTestBean bean = new TXTestBean();

            bean.setName("bodybody");
            txDAO.save(bean);

        }
    }


public class TXTestService implements Crudable{

    private TXTestDAO dao;

    public void setDao(TXTestDAO nDAO){
        dao = nDAO;
    }
public int save(CooingbeeFetchable bean) {
        // TODO Auto-generated method stub
        return dao.save(bean);
    }
}

So far, I get No session found for current thread exception.
Also I'm trying not to use annotation.
I feel so lost @.@ !
Can you point me to the right direction ?

1条回答
劳资没心,怎么记你
2楼-- · 2019-03-22 08:37

XMLBean factory is deprecated, I'd recommend using annoations and the latest and greatest spring version if you can (the testing features of spring 3.2 are great). It would simplify things a bit for you, the dao/repository could have this

@Resource(name = "sessionFactory")
private SessionFactory sessionFactory;

@Transactional(propagation = Propagation.REQUIRED)
 public T save(final T o) {
        return (T) sessionFactory.getCurrentSession().save(o);
    }

Which itself could then be injected, and yr config add this :

 <tx:annotation-driven transaction-manager="transactionManager"/>
查看更多
登录 后发表回答