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 ?
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
Which itself could then be injected, and yr config add this :