-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Need some help with re-design, Spring/Hibernate/J2EE/POJO!
PostPosted: Sat Dec 20, 2003 11:15 am 
Regular
Regular

Joined: Wed Aug 27, 2003 2:55 am
Posts: 90
Location: Sweden
Hi,

After weeks of trying to design my system to use Spring and Hibernate with not really satisfying result, I start to believe my design isn't to good + lack of understanding Hibernate/Spring properly(?).

Well, here's a brief description of my domain.

My system is based on one, sat it again, one complex object coposed by ~40-50 other objects. Let's say it's a car, a car is build on screws and bults etc. Almost every object have bi-directional associations, seldom any many-to-many relationships.

This system should be design so it can easily adopt to J2EE and EJB's. I'd really like to develop all my dao objects, business object so they easily could be wrapped around a EJB.

The system should be developed in a layered architecture, well a logical 3-tier 'cause well be running the system with POJO's as 2-tier, and J2EE as 3-tiered.
By logical 3-tier I mean that well try to program all of the objects as they really should be distributed in a 3-tiered architectured, even though they are going to be part of the 2-tier architecture with POJO's.

My different layers is:

Code:
* Presentation - Contains all UI related classes

* Middle - Should contain very well defined interfaces towards the business layer, for transaparent access to EJB's
   or POJO's.

* Business - Contains all of our business objects

* Integration - Our DAO objects tec.


One argument for using Spring framework together with Hibernate is the transaction management. There exists a requirement that the system should be able to migrate to using JDO in the future. Spring provides a very nice IoC management for changing from HibernateTransaction to JDOTransactions to JTATransactiosn etc.

Today we've made a very narrow business interface for managing our complex object, the car. It's just contains methods to:
NOTE! All of these methods uses Spring transaction management.

Code:
  public Car createNewCar(Car newCar);

  public Car updateCar(Car carToUpdate);

  public Car loadCarById(Object carId);

  public Car addCarComponent(CarComponent newCarComponent);

  public void deleteCarComponent(Car carComponentToDelete);


Because of the complex object is composed of ~40-50 other objects we don't want to have 40-50 business objects or CRUD method cluttering the interface, this is something I need suggestions on!!!

The methods addCarComponent() and deleteCarComponent() uses reflection to find out what kind of component we'd want to add/delete. By reflection we're locating it's data access object (one dao per entity object) and performs the relevant operation (sessionsave() or session.delete()) in the current dao.

All session management is handled in the integration layer, so there's not possible to flush a session explicitly between two CRUD operations, inside a business method, that is invoked in one transaction (if not the session.flush() is exposed by my dao's).

I'll describe some of my use-cases:

Code:
1. Create a new car; the minimal car components is created and persisted to db. The minimal amount of the car components
    is created and assembled in the UI, the the whole Car object is sent down to the business method createNewCar().
    The persisted Car object is then returned to the UI.

2. Persist updated car. We've made some changes (not added or removed any objects)
    to the Car object in UI and like to persist the changes: updateCar() is invoked

3. We'd like to delete a car component from the Car object.
    The CarComponent we'd like to delete is sent down to the business
    layer.

    The changing of serialnumbers is happening in both delete/add business methods:
    NOTE! These steps is performed inside the business method, in one single transaction.

     3.1 The deleted objects changes some serialnumbers of it's related
        objects. This is possible due to bi-directional associations.
        This object we're deleting fetches it's parent and gets its "siblings",
        changes their serialnumbers etc.

     3.2 Due to the bi-directional associations we can get a reference to the
         topmost Car object. A updateCar() is invoked on this car components
         topmost parent Car object.

     3.3 All of the associations to the object we're deleting is removed.

     3.4 The object is sent to its dao and a sessiondelete() on that object
         is performed. (Normally it's here a "cascade during flush" is issued).

4. We'd like to add a new car component to the Car object.
     The new CarComponent is sent to the business method addCarComponent()

     4.1 Changes to the existing Car objectsa serialnumber is made.

     4.2 Business method updateCar() is invoked.

     4.3 session.save() on my car component is invoked in its dao


Often due to my cascade setting and my complex data modell I get problems like "flush during cascade is dangerous" or "not-null constraint violations".
Maybe there is easier to have sperate methods for saving CarComponents due to the complex cascade hierarchy that otherwised should be managed when only for example updateCar() is available?

I'd like someone to share some comments on the above described approach. Tell me what could be solved a better way, simplier way etc. I'm dying to learn!

Kindest regards, Andreas


Top
 Profile  
 
 Post subject: Re: Need some help with re-design, Spring/Hibernate/J2EE/POJ
PostPosted: Mon Dec 22, 2003 4:15 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
andreas_eriksson wrote:
All session management is handled in the integration layer, so there's not possible to flush a session explicitly between two CRUD operations, inside a business method, that is invoked in one transaction (if not the session.flush() is exposed by my dao's).

I think this is your main issue. I experienced some 3-tier full separation and some framework abstraction (abstraction from the ORM to allow JDBC / Hibernate / Toplink) (not Sping but a similar non OS one), here are my comments on that :
* full abstraction of the ORM (like Toplink and Hibernate) is almost impossible. You'll only get the most basic features and the dumpest mistakes of all your ORM.
* full DAO abstraction of your ORM is stupid too, since you can't access lazy loading and other cool stuffs like that
* Not having useful control of you ORM (like flush, evict, ...) in business part is a mistake, because you can't do what you want. Your business process will always need to know the ORM because of the way it works (cascade is dangerous for hibernate, ...). (this point is kind of fresh thinking to me though)

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 22, 2003 8:15 am 
Regular
Regular

Joined: Wed Aug 27, 2003 2:55 am
Posts: 90
Location: Sweden
Thanks for your respons!

I'd like to hear more comments if anyone have any!? It's very helpful and appreciated!!

Well, my DAO implementation can get hold of an Hibernate Session object (thread bound), and uses for example Hibernate Query etc.

My BO's doesn't know anything 'bout Hibernate, but maybe they should as you say?!

The thing is we'd like to reuse the BO's as much as possible for an migration to JDO, if necassary. Yeah, the BO's impl. (of course) are "hidden" behind an interface... maybe that's enough?

I could make my DAO objects to extend an abstract DAO class which obtains/releases the Hibernate Session, where I define the obtain method as public. The in my BO using the DAO can get hold of a thread bound Hibernate Session object!? Bad solution, eh?

Kind regards, Andreas


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 22, 2003 11:16 am 
Senior
Senior

Joined: Wed Aug 27, 2003 6:04 am
Posts: 161
Location: Linz, Austria
I second Emmanuel that full abstraction of the persistence mechanism is almost impossible. Too many semantics are different at least in the details.

However, if you just target transparent persistence tools (with automatic change detection and implicit updates) like Hibernate and JDO, you can design your DAOs accordingly: Simply assume that any changes made to retrieved objects within the same transaction will be persisted automatically, without explicit update calls.

Regarding flushing in particular: Standard JDO 1.0 does not know the notion of flushing a PersistenceManager, but some implementations do via proprietary API. So it might not be easy to implement this for both Hibernate and DAO via explictly exposed flush methods in DAOs.

In the case of Spring and Hibernate, you can have some data access operations "FLUSH_EAGER" by turning their HibernateTemplate respectively HibernateInterceptor to that flush mode. They will automatically flush the Session at the end of the operation then, no matter whether within a transaction or not.

So might it be possible to use FLUSH_EAGER or specific flush calls within your DAO implementions to get the desired behavior? If necessary, you could make your DAO operations more coarse-grained, to cover the cases where explicit flushing is necessary.

I guess that's in general good advice: Don't make your business objects depend on the persistence tool - rather move logic that requires persistence calls in the course of its execution to more coarse-grained DAO methods.

In the end, the separation between business objects and DAOs is also determined by the level that requires reimplementation for a different persistence tool. Business objects should never have to be reimplemented for a different persistence strategy: It's probably better to accept bits and pieces of business logic in DAOs as a tradeoff.

Juergen


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 22, 2003 12:17 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
jhoeller wrote:
In the case of Spring and Hibernate, you can have some data access operations "FLUSH_EAGER" by turning their HibernateTemplate respectively HibernateInterceptor to that flush mode. They will automatically flush the Session at the end of the operation then, no matter whether within a transaction or not.

Flush eager is a heavy decision since DB roudtrips will be heavily increased.
Quote:
logic that requires persistence calls in the course of its execution to more coarse-grained DAO methods [...] It's probably better to accept bits and pieces of business logic in DAOs as a tradeoff.

Anybody has a real life experiment on that ?
I've always been afraid that all business will be in DAO in such an approch and business process a simple wrapper (wrapped in SLSB ;-)). It's particulary visible when using a *not so expert* time-pressured team.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 23, 2003 7:45 am 
Senior
Senior

Joined: Wed Aug 27, 2003 6:04 am
Posts: 161
Location: Linz, Austria
epbernard wrote:
Flush eager is a heavy decision since DB roudtrips will be heavily increased.


Good point. But flush calls at the of specific DAO methods could still work, without the business objects having to initiate the flushes. Only those operations that actually require eager flushing should use a HibernateTemplate with flushMode FLUSH_EAGER.

epbernard wrote:
I've always been afraid that all business will be in DAO in such an approch and business process a simple wrapper (wrapped in SLSB ;-)). It's particulary visible when using a *not so expert* time-pressured team.


Another good point. It's indeed a challenge to still keep as much business logic as possible in business objects. But sometimes it might simply be the better tradeoff to put more stuff in DAOs instead of working around the limitations of your DAO interfaces. Of course, this is far from trivial to decide.

Juergen


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.