I hope you don't mind but I'd like to post a query of my own on this thread as it's quite similar to Guy's issue.
I have three objects that each map to a different database table via Hibernate. The logic of my application is such that if there is a problem writing one of these objects to the database then none of them should be written. I have a DAOImpl class for each of my objects and each one of these classes has a method that either saves or updates data. Based on what you said to Guy I was planning then to have a Master class that will contain instances of the three different DAOImpl classes and will call the save/update methods within a try-catch block and only commit if there were no problems. My question is this - I am using Hibernate code for the save/update functions eg:
Will there be a problem then if I also use Hibernate in the Master class that will handle the transaction management? I envisaged something like the following
Simon Ritchie wrote:I hope you don't mind but I'd like to post a query of my own on this thread as it's quite similar to Guy's issue.
Although it's very similar to Guy's issue, I have created a new topic for your question. First of all, because it's not nice to hijack someone else's topic. But mainly because it gets very confusing very quickly (also for other ranchers) if replies about/with different code snippets are posted in mingled disorder.
Simon Ritchie wrote:Will there be a problem then if I also use Hibernate in the Master class that will handle the transaction management? I envisaged something like the following
First of all, a very important disclaimer: I am not a Hibernate expert at all. And I have never used transaction management in Hibernate manually, I have always used Hibernate in combination with Spring. Thanks to some configuration and using annotations, Spring takes care of all transaction handling (removing boatloads of boilerplate code).
So a similar Master class (service layer) in Spring would look like this:The annotation @Transactional will make sure that all business logic in this method will be executed as one transaction. If one of the save() methods throw a runtime exception, Spring will make sure that everything is rollbacked. If none of these methods throw a runtime exception, the transaction will be committed. So you don't have to care about the transaction management (no need to reinvent the wheel again) and can focus on the most important, the business logic.
So the underlying implementation of the annotation @Transactional might look like thisAnd that's exactly what you should do in your code as well. But you have to write this code for every unit of work which should be executed as a transaction. So it is pretty obvious that this one single annotation will remove a lot of boilerplate code.
Now back to your application. The writeData() method looks very similar to the above code snippet: you open a session, start a transaction, do some business logic, depending on the result you either commit or rollback the transaction and finally close the session. So that's how it is supposed to be implemented But there is an issue with the createEnvironment() method (and probably with the other methods as well): here are you also opening a (new) session, starting a (new) transaction, executing some business logic, and so on. In these methods you should use the current session and current transaction; otherwise the commit (or rollback) will not work correctly as the data was saved in different transactions.