View Full Version : Possible to Combine HibernateTxnManager and DataSourceTxnMan
sethladd
Aug 24th, 2004, 10:29 PM
Hello,
I have a few Hibernate beans, and I'd like to introduce a few JdbcDaoSupport beans. The Hibernate beans are using a HibernateTransactionManager. The JdbcDaoSupport beans will use, I assume, the DataSourceTransactionManager.
Is it possible to mix the two beans with their two different txn managers, that will eventually operate under one transaction?
I had some requirements that just didn't map to Hibernate very well.
Thanks very much!
Seth
sethladd
Aug 24th, 2004, 10:31 PM
I forgot to mention that both the HibernateDaoSupport beans and the JdbcSupportBeans will be using the same DataSource.
Thanks,
Seth
irbouho
Aug 24th, 2004, 11:01 PM
HibernateTransactionManager uses sessionFactory for transaction synchroonization while DataSourceTransactionManager uses the datasource. I assume it is not possible to synchronize, out of the box, two transactions managed by these managers.
If the Hibernate beans always drive the transactions, you can extract the connection from Hibernate Session and provide it to your JdbcSupportBean.
Rod Johnson
Aug 25th, 2004, 04:18 AM
It is possible--and sometimes useful--to have coordinated transactions for both. Your JDBC transactions will be managed by the HibernateTransactionManager if you work with the same JDBC DataSource in the same transaction. That is, create the SessionFactory using Spring's SessionFactoryBean using the same DataSource that your JdbcTemplates use.
The only issue to watch, of course, is that you may be invalidating your Hibernate cache by JDBC changes. Generally I find it best to use JDBC to update only tables that don't have Hibernate mappings.
Juergen Hoeller
Aug 25th, 2004, 06:20 AM
As Rod said, simply keep using HibernateTransactionManager, which auto-detects the DataSource used by Hibernate and seamlessly exposes Hibernate transactions as JDBC transactions for that DataSource. JDBC code that accesses the same DataSource via Spring will automatically participate in such transactions.
Note that you must specify the DataSource for Hibernate via LocalSessionFactoryBean's "dataSource" property to allow HibernateTransactionManager to auto-detect it. Alternatively, you can explicitly pass the DataSource to HibernateTransactionManager's "dataSource" property.
Juergen
irbouho
Aug 25th, 2004, 08:13 AM
Juergen,
do you mean I can use HibernateTransactionManager to manage transactions for both HibernateDAO and JdbcDAO?
Rod Johnson
Aug 25th, 2004, 09:04 AM
do you mean I can use HibernateTransactionManager to manage transactions for both HibernateDAO and JdbcDAO
Yes. HibernateTransactionManager also knows about the JDBC connection bound to the current thread; DataSourceTransactionManager doesn't know anything about Hibernate.
irbouho
Aug 25th, 2004, 09:27 AM
Thank you Rod.
Yes. HibernateTransactionManager also knows about the JDBC connection bound to the current thread; DataSourceTransactionManager doesn't know anything about Hibernate
that means, if I have a use case where a call is made to a JdbcDAO transacted method from my web controller, HibernateTransactionManager will instanciate a Hibernate Session to maintain the transaction even if I do not need to use Hibernate in my use case.
sethladd
Aug 25th, 2004, 01:01 PM
Thanks everyone!
I was running with 1 datasource, and a hibernatetxnmanager and a datasourcetxnmanager. My JdbcDaoSupport beans do work on a separate table, so as not to interfere with any Hibernate work.
I will now dump the datasourcetxnmanager and use only the hibernatetxnmanager for both Hibernate DAOs and JDBC DAOs.
Thanks again!
Seth
Colin Sampaleanu
Aug 25th, 2004, 01:57 PM
Thank you Rod.
Yes. HibernateTransactionManager also knows about the JDBC connection bound to the current thread; DataSourceTransactionManager doesn't know anything about Hibernate
that means, if I have a use case where a call is made to a JdbcDAO transacted method from my web controller, HibernateTransactionManager will instanciate a Hibernate Session to maintain the transaction even if I do not need to use Hibernate in my use case.
Well, that's not quite an accurate description. You are normally wrapping service layer objects, not DAOs, with a transactional proxy. So in this case, the outermost wrapped service layer method that is called (in a call graph) which is wrapped with the HibernateTransactionManager will indeed cause a Hibernate Session to also be created and bound to the thread/and transaction. But that's not a big deal. Hibernate Sessions are very lightweight. Then inside of that, you can mix and match Hibernate based and JDBC-based DAOs....
Regards,
irbouho
Aug 25th, 2004, 02:15 PM
You are normally wrapping service layer objects, not DAOs, with a transactional proxy
I agree on that, however, it does not always make sens to create a service layer. (take a look at Spring samples ;))
All in all, I tried to stick to sethladd vocabulary as he never talked about services.
sethladd
Aug 25th, 2004, 02:55 PM
Well, that's not quite an accurate description. You are normally wrapping service layer objects, not DAOs, with a transactional proxy. So in this case, the outermost wrapped service layer method that is called (in a call graph) which is wrapped with the HibernateTransactionManager will indeed cause a Hibernate Session to also be created and bound to the thread/and transaction. But that's not a big deal. Hibernate Sessions are very lightweight. Then inside of that, you can mix and match Hibernate based and JDBC-based DAOs....
Just to double check... let's say I'm not inside a Hibernate TXN to begin with. It's still safe to use HibernateTXNManager as the TXN Manager for my JdbcDaoSupport beans?
It would be helpful to have only one TXN Manager defined in the system, but if I need to have both DataSourceTXNManager and HibernateTXNManager (which, function almost the same) then that's fine, too.
Sounds like using HibernateTXNManager for everything is OK, as long as I don't care that a Session is created (even when I don't need it).
Colin Sampaleanu
Aug 25th, 2004, 03:53 PM
There's no such thing as a Hibernate transaction, just Spring managed transactions. You do of course have DataSourceTransactionManager and HibernateTransactionManager as two possible (spring) transaction maangers managing these Spring transactions. These TMs are actually almost the same thing anyways (most of the real work is done by the base class AbstractPlatformTransactionManager), but the latter is Hibernate aware and ensures that when a new transaction is started, a Hibernate Session is created if needed, and bound to the thread and synchronized with the tx. You could in fact get pretty well the same net effect by just using DataSourceTransactionManager, and add in HibernateInterceptor as a post interceptor on the transaction proxy definition.
In a JTA environment (JBoss, WebLogic, TomCat with JOTM, etc), you can instead go to using JTATransactionManager, which will coordinate transactions with the JTA transaction manager itself. You can still mix and match jdbc and hibernate DAOs underneath that. To get the same timing on the session creation/binding (i.e. at time of tx creation), you would want to add in HibernateInterceptor in this case, otherwise the Session would only be bound on first creation in a DAO underneath (assuming the DAO's template is even allowed to create new Sessions, aka the allowCreate flag).
Regards,
sethladd
Aug 25th, 2004, 03:57 PM
There's no such thing as a Hibernate transaction
Right, I meant to say a TXN + Hibernate Session.
These TMs are actually almost the same thing anyways (most of the real work is done by the base class AbstractPlatformTransactionManager)
That's what I thought, since ultimately, they are working against JDBC and the DataSource (in my world).
JTA is definitely an option, via JOTM, but not at this time.
We'll stick with only the Hibernate TXN Manager for all TXN management. Thanks for all the help!
irbouho
Aug 25th, 2004, 03:59 PM
There's no such thing as a Hibernate transaction, just Spring managed transactions. You do of course have DataSourceTransactionManager and HibernateTransactionManager as two possible (spring) transaction maangers managing these Spring transactions. These TMs are actually almost the same thing anyways (most of the real work is done by the base class AbstractPlatformTransactionManager), but the latter is Hibernate aware and ensures that when a new transaction is started, a Hibernate Session is created if needed, and bound to the thread and synchronized with the tx. You could in fact get pretty well the same net effect by just using DataSourceTransactionManager, and add in HibernateInterceptor as a post interceptor on the transaction proxy definition.
Thank you Colin, this makes things very clear to me.
Juergen Hoeller
Aug 26th, 2004, 02:24 AM
You could in fact get pretty well the same net effect by just using DataSourceTransactionManager, and add in HibernateInterceptor as a post interceptor on the transaction proxy definition.
Well, it's important to note that HibernateInterceptor will normally *not* participate in the Spring-managed JDBC transaction then, but rather fetch a new Session from the SessionFactory - with its own non-transactional JDBC Connection!
Just if you proxy your JDBC DataSource with a TransactionAwareDataSourceProxy (available since Spring 1.1 RC1) and pass that proxy to your LocalSessionFactoryBean, you could use DataSourceTransactionManager in combination with Hibernate.
When using HibernateTransactionManager, you'll get a thread-bound transactional JDBC Connection that's been taken from the transactional Hibernate Session - thus, both Hibernate and JDBC data access operations will participate in the same database transaction without issues.
Juergen
Colin Sampaleanu
Aug 26th, 2004, 08:43 AM
Hmm, Right you are, my bad... DataSourceTransactionManager+HibernateInterceptor will still end up synchronizing the Hibernate Session with the transaction, but that is not enough as the connection used will be different (and non-transactional). There's not a similar issue when using JTATransactionManager+HibernateInterceptor, since JTA will be coordingating real transactions (multiple connections off the same DataSource will still be in same tx).
So when mixing and matching Hibernate and JDBC code, people should be using HIbernateTransactionManager, or JTATransactionManager+HibernateInterceptor (if in a JTA environment), or as Juergen said it would work to use DataSourceTransactionManager+HibernateInterceptor, if the datasource was wrapped with TransactionAwareDataSourceProxy. Note for anybody still awake at this point that w/regards to JTATransactionManager+HibernateInterceptor, things will still work without the interceptor tacked on, as long as the HibernateTemplate has the allowCreate flag set to true, the default. This will just result in on-demand creation of the session, and binding, which I'm not quite a fan off, since people can run out of transaction without realizing it...
Regards,
trisberg
Aug 26th, 2004, 09:45 AM
We should try to put together a matrix of suggested configuration options to make it easier to figure out what options work well together for a specific purpose.
Colin Sampaleanu
Aug 26th, 2004, 09:47 AM
We should try to put together a matrix of suggested configuration options to make it easier to figure out what options work well together for a specific purpose.
Yes, I've been thinking the same thing for a few days. Some description which describes how the transaction/data-handling classes interact together, and when and why you'd one to use one setup vs. another.
sethladd
Aug 26th, 2004, 01:09 PM
Thanks for all this great feedback. I think a list of possible configurations would really help things.
Just knowing that we're able to mix JDBC DaoSupport beans and Hibernate DAO Support beans w/ one single TXN manager is very powerful!
vBulletin® v3.8.2, Copyright ©2000-2009, Jelsoft Enterprises Ltd.