|
Thanks Jimmi. I found I made a mistake : The "finally" is in fact unnecessary and use "catch" is enough. So I rewrite my code with javassist and upload it as attachment.
My approach is a little different from yours. I didn't create SessionFactoryProxy service but just wrap the SessionFactory in a SessionSource service, whose only method is a getSession() method. The business logic services will depend on this service and their business methods just call the getSession() method at start. The Session is stored in ThreadLocalStorage service and will be closed when the thread is cleaned up. Also I guess it will cause some defect that TransactionInterceptor can only apply to Session.save/update/delete methods. Look at the sample code: List l = session.find("from Foo"); Foo f = (Foo)l.get(0); f.setName( someName ); These codes didn't call any save/update/delete methods. But it really changes the database status and should be put under transaction context. So my TransactionInterceptor can apply to any method. And at last, I know my sourcecode is not a patch since I didn't create any Testcase or document. I just hope these litle codes can be helpful to someone. Good stuff. it certainly is a defect of mine to only be able to use the interceptor on subinterfaces of Session, but I couldn't think of another way to get hold of the session to be able to begin/commit/rollback the transaction. Using the ThreadLocalStorage is something I didn't think of.
I think that you should use the SessionFactoryProxy - this enables you to have multiple SessionFactories and hence produce connections to multiple databases. You can specify a different hibernate config file for each SessionFactory rather than using the default name as you do. Another problem is that by using the ThreadLocalStorage with a single named key, you're limiting the thread to one database connection per thread. By using a threaded model, as I do in the SessionProxy, you're not. But that creates problems in getting the Session in TransactionManagerImpl, as it would mean that the SessionSource wasn't a singleton anymore. I have no experience in multi-database programming. So I never consider how to configure Hibernate with multi-database. You must work on some large project. For my project, one database and one SessionFactory is enough.
Anyway, multi-database can be configured in one XADataSource. But I don't know whether Hibernate supports XADataSource, or how to manage the transaction in Hibernate. Maybe JTA will handle it... Might be easier to discuss this as a Change Proposal on the Wiki.
I just fixed a bug ( I think we need to take a step back and look at a bigger picture. We shouldn't concentrate upon making hibernate-specific services. We should work to provide a general framework for DAOs (a la Spring). In my article, I created a generalized TransactionServices (begin, commit, rollback, rollbackOnly, etc.) which is used by a transaction coordinator (or manager). Now, in a hibernate environment, I'll use a hibernate-specific version of the TransactionServices interface. With JDO, I'll use a JDO-specific version. This is where we should lean, IMHO.
I'm worried about duplication of effort here. Couldn't we leverage what's already in the wild (read: spring)? Things like transaction demarcation, jdbc and orm support are battered subjects and we should try to integrate what's already available with Hivemind.
As Howard is fond of saying, Hivemind is object soup. Can't we just throw in those spring object/classes instead of cooking everything again? I think we could leverage some of the ideas in Spring, but HiveMind does have one interesting feature, service models, which makes implementing this stuff MUCH easier than the way they do it with Spring. We don't NEED thread local variables in HiveMind. We can use pooled/threaded service models!
Hey, guys. Here's a sneak peak of the code that I'm writing for TSS.com about HiveMind. It contains code that I've been working on which integrates Hibernate and HiveMind. I would love to have any suggestions, comments. This zip file contains an Ant build file. You should modify the build.properties file (database settings, deploy location, etc) if you want to actually install and run the example webapp. You'll need to run the "get-dependencies" task first (hopefully you're not behind a proxy server, because I didn't account for that yet). This is an example of what I have in mind with respect to support for Hibernate in HiveMind. Of course, we might want to change the names of some of the interfaces/classes (to protect the innocent). One thing I don't particularly like is the duplication of code between the TransactionInterceptor (a service interceptor) and TransactionFilter (a servlet filter) classes, but I think it's the easiest way to implement what we need without adding new classes/interfaces. I created a class called HibernateSessionWrapper which wraps a Hibernate session and provides many of the common operations you might need WITHOUT the checked exceptions (they throw runtime exceptions instead). Anyway, please check it out and let me know what you think.
Here is the current status of some work I have done to integrate Hibernate in Hivemind in a general way (general Transaction Service).
Hope it can help someone. I'm +1 for closing this issue. Hibernate-specific stuff should go into external helper libraries like hiveutils, or whatever Jean-Francois is calling it now. :-) He's done a lot of cool work in that project that others could leverage.
Hibernate-specific facilities are outside the scope of the HiveMind project. Please see either hivetranse or the hivemind project at JavaForge for Hibernate support.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Works with logging interceptor before of after the TransactionIinterceptor.
Regards,
Jim Dyson