This week's book giveaway is in the Agile and Other Processes forum.
We're giving away four copies of DevSecOps Adventures: A Game-Changing Approach with Chocolate, LEGO, and Coaching Games and have Dana Pylayeva on-line!
See this thread for details.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Devaka Cooray
  • Tim Cooke
Sheriffs:
  • Rob Spoor
  • Liutauras Vilda
  • paul wheaton
Saloon Keepers:
  • Tim Holloway
  • Tim Moores
  • Mikalai Zaikin
  • Carey Brown
  • Piet Souris
Bartenders:
  • Stephan van Hulst

Hibernate Transactions

 
Ranch Hand
Posts: 59
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

I just have few clarifications in implementing transaction management in hibernate effectively with few specific scenarios in place as mentioned below.

Consider that i have various DAOs which are entity specific for example, i can have a DAO for an Employee called EmployeeDAO and a DAO for Project called ProjectDAO, assume that these entity DAOs does CRUD operation on the Entities and nothing much at the moment for simplicity.
when i perform the CRUD operations on the entity, it should obviously be performed under a transaction, so every method (CRUD operation) should start a transaction at the start of the operation and commit the transaction at the end of the operation.. everything is simple and no problem with it, i can even use AOP to separate out this boilerplate code to clean up things.

Now consider that i have a "business process" which should involve both the Entity DAOs to be used - in which case i would also want both the operation to be performed within a single transaction!, ofcourse i can start a transaction and end it in the business process itself and remove the same from the DAOs, but this would make all the code which uses the DAOs to handle transaction which is wrong as i would expect the DAOs to handle transactions not the client.

So, i think it would be a nice idea to make all DAOs to open and close the transaction (using AOP) provided there is no transaction already in place! which allows the business process to take control of the transaction rather than multiple DAOs to start and end multiple transactions...

I can achieve this as the hibernate Session is bound to the current thread, so if the business process starts the transaction then the DAOs can check if the session bound to the thread is active already in which case it assumes that client is handling the transaction and never starts a new one nor commits the transaction at the end.

Before i start implementing this I just want to find out if Anybody has any better suggestion for the same? I haven't been using spring framework for hibernate, may be it supports a better way to handle it but i dont want to migrate to spring at the moment.

Any ideas/advice is much appreciated.


Thanks,
John
 
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But now your DAOs are actively involved in transaction management--I don't think they should care how they're being used, that's mixing up concerns. Transaction management should be handled a level higher, either through something like Spring (much cleaner) or manually in services etc.
 
John Pradeep.v
Ranch Hand
Posts: 59
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Newton wrote:But now your DAOs are actively involved in transaction management--I don't think they should care how they're being used, that's mixing up concerns. Transaction management should be handled a level higher, either through something like Spring (much cleaner) or manually in services etc.



Actually the DAOs are the Repositories (Repository pattern) and can be used by higher level layers which could be the business/Service or even the View layer (not JSPs etc but service facades which acts as an interface to the business layer) in this case i dont think its a good idea to handle transaction in two different place for the same Repository/DAO i.e., i dont want the facades and the business layer both to handle transaction for the DAO/repository which it is intending to use!

I would rather prefer the DAOs handle transactions which is a clean approach, and i agree as you said i can make use of AOP to point cut the DAO operation as transactional to improve the design/code or even use spring for that matter.

But the only problem with this approach is that the DAO/Repository could be used by both a business layer and by a service facade present in the view layer (which acts as an indirection to the business layer)
The business layer could use the Repository within a transaction of its own!!! but the facade layer or any other client can use the Repository/DAO directly without any transaction in progress so the DAO should support both type of clients isnt it? so the transaction provided by the DAO should be conditional as how it is being used by the client...

Am i right? or am i missing anything? Please Advice.


 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Having the DAOs handle transactions is *not* a clean choice, because the DAOs then have to understand the context in which they're being used. If you're working in an environment that allows nested transactions they don't have to worry about it. If you're not, you're either going to have to add a flag, or have the DAOs understand more than (I believe) is reasonable about the world in which they live.

YMMV.
 
John Pradeep.v
Ranch Hand
Posts: 59
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Newton wrote:Having the DAOs handle transactions is *not* a clean choice, because the DAOs then have to understand the context in which they're being used. If you're working in an environment that allows nested transactions they don't have to worry about it. If you're not, you're either going to have to add a flag, or have the DAOs understand more than (I believe) is reasonable about the world in which they live.

YMMV.



But in the example i mentioned, the client for the Repository/DAO could be even a facade class present in the "View Layer", handling transaction in this layer makes me a bit uncomfortable :(
but i could avoid it by having the facade layer talk to a specific service class within the business layer which will just delegate the call to the actual DAO/Repository and in this case i can handle all transaction at the service layer "alone"!! which is really convincing to me but as a worst case there might end up quite a lot of delegators bloating the code base! what's your take on it?
I feel, as you said having a flag would solve the problem but i should ensure that these conditional code of handling transaction is seperated out using AOP
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Nothing that requires transactions should be in the view, as far as I'm concerned (others may have different opinions). It's too easy to create performance problems this way. The data for the view layer should already be retrieved and available before it gets that far.

Honestly, I have no idea what your class diagram looks like, and it sounds over-architected to me, so I doubt I'll be able to provide much more useful input. I don't understand how many layers you have, how they interact, how they're used, why the exist, and so on.
 
John Pradeep.v
Ranch Hand
Posts: 59
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Newton wrote:
Honestly, I have no idea what your class diagram looks like, and it sounds over-architected to me, so I doubt I'll be able to provide much more useful input. I don't understand how many layers you have, how they interact, how they're used, why the exist, and so on.



I understand David, I will try to give a glimpse of the layers i have used.

The layers are as shown below

1. Persistence
2. Domain
3. Service


4. Facade
5. Controller
6. JSPs



1,2,3 layers together is one single layer so is 4,5,6 together

the first set is the domain layer which is designed based on the domain driven approach and the second set is the view layer.

The Service layer is the business layer which provides business services

The facade layer is like an adapter to decouple the view layer (controllers) from the Service layer, when i say it decouples it actually transforms the classes present int he domain layer into a form used by the JSPs so that JSPs are not coupled with the model classes present in the domain layer
Also the facade layer co-ordinates between multiple services if required after all it is named a facade.

Hope you got the idea now, the facade layer need not always talk to the service layer because there could be a simple CRUD operation on an entity required so the facade layer can directly invoke a Repository (present in the persistent layer) to do the CRUD operation on the entity.
Example: EmployeeRepository.add(Emplyee emp);

Did i make things clear now? :)
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Not really, but that's okay.

I always go through a service, even if it's just a delegation to a DAO. This allows me to put aspects around all my service methods and leave my DAOs alone, which in turn means that I don't need to do anything in particular for services that use multiple DAOs, and the service methods that wrap DAO calls can be generated automatically. There's an interface that defines DAO operations, each related service implements the same interface. Services also implement their *own* interface that defines functionality beyond that provided by its underlying DAO. Some services, of course, aren't tied to a single DAO.

I have yet to see a great reason for a facade between controllers and services; they're already decoupled enough: controllers handle only web-related stuff like data marshalling and service errors, services handle actual work. I'll occasionally use a DTO to handle conversations between JSP <=> controllers <=> services, but it's rarely been worth it to me--everything I work with is a POJO anyway, so I'm not really gaining much, unless I'm aggregating data from wildly disparate sources.
 
John Pradeep.v
Ranch Hand
Posts: 59
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Newton wrote:Not really, but that's okay.

I always go through a service, even if it's just a delegation to a DAO. This allows me to put aspects around all my service methods and leave my DAOs alone, which in turn means that I don't need to do anything in particular for services that use multiple DAOs, and the service methods that wrap DAO calls can be generated automatically. There's an interface that defines DAO operations, each related service implements the same interface. Services also implement their *own* interface that defines functionality beyond that provided by its underlying DAO. Some services, of course, aren't tied to a single DAO.



This was exactly the same approach i followed, but somehow i felt the services to be more process oriented rather than single operation oriented for example i can have a BookingService which can do a booking for an inventory (make payment, update inventory etc etc) but adding a new inventory to the database need not be in the "BookingService" interface right?
even if the service encloses the operation like "addInventory(Inventory inv)" the name of the service cannot be meaningful, but in fact did have such services and named them like "InventoryService", "EmployeeService" which are not business process services but EntityServices.

Having such EntityServices is not harmful, but then i thought having too many delegators (Entity Services) would be lot of noise and then thought of using the Repositories directly in the facade which is when i thought i will find out others opinion and created this entry in javarach :)


I have yet to see a great reason for a facade between controllers and services;



The reason for such a design is that is that it not only seperates the controllers from the business layer but makes the controller look a bit neat and clean by providing a proxy like interface which does various operations like
1. Identifying the service using business layer factory
2. Prepare Input to call the actuall business service (if required)
3. Call the service
4. convert the business layer objects returned by the service into UI layer objects

The controller will just have to call the operation of a facade by passing a view layer input object and obtain back the view layer specific object, but behind the screen the facade does all the above mentioned operations.

I do agree strongly that there is no great benefit i gain out of such an indirection, but its just i dont want the controller to get bloated in the future due to the absence of a facade layer!
However, if the amount of code required to co-ordinate with the business layer is simple, then i dont mind doing it directly in the controllers though.



 
You save more money with a clothesline than dozens of light bulb purchases. Tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic