Page 1 of 3 123 LastLast
Results 1 to 10 of 22

Thread: Architectural Considerations: Spring, Hibernate and the Domain Model

  1. #1
    Join Date
    Mar 2008
    Posts
    19

    Default Architectural Considerations: Spring, Hibernate and the Domain Model

    Hello,

    I am working on the overall design of a brand new system, so no legacy issues are relevant, and we have decided on Spring and Hibernate. I have found lots of useful information here and elsewhere, but what I am missing is the notion of what the best practices are for this type of system in 2008, based on everyone’s experience.

    So looking top down I am guessing we would have something like this:

    Web Layer
    API / Service Layer / Domain Objects
    DAO Layer
    ORM objects
    Hibernate

    Here is my take at what these layers do, along with some questions...

    Web Layer - Does web stuff. Duh.

    API / Service Layer - Implements business logic. This is what is exposed to all external consumers of the system (there will be others besides the web layer).

    Domain layer - Models the business problem. These interfaces, along with the API layer will also be exposed to the outside word (web, etc), but nothing else will be.

    DAO Layer and ORM objects - Interacts with the DB via hibernate.

    ?? OK so here is where things get fuzzy. The API layer will use the DAO layer to get info from the DB (Spring can inject DAO impls), but what should the DAO layer return to the API layer…. full domain objects (which I consider part of the API), or the ORM objects that Hibernate generates with its DB mapping?

    I think the way the ORM objects are created has a big effect on all this. If we assume that we manage hibernate mappings in an XML file (one per table/ORM object), then hibernate will GENERATE the ORM objects for us. This is fine, but then we are not going to add any intelligence to these ORM objects, they are going to be simple getter/setter bean things just for talking to hibernate. So are we going to have all this code creating meaningful Domain objects (which may be a bit less anemic) out of the ORM objects?

    ?? If we were able to auto-generate the hibernate XML (and SQL) from annotated ORM objects, then since we are building the ORM objects, maybe we can put some more intelligence into them? But then can the annotated ORM objects become something more, like a Domain object (or an implementation of one)? Or do we just annotate the Domain objects and not have an ORM layer at all?

    I guess it all comes down to this…. how to the hibernate ORM objects fit into this architecture? Are they totally hidden from the API via the DAO? Can we forgo these objects an use annotations on our Domain objects?

    The OO purest in me feels that everything should be totally separate. The Domain / API is the model of our problem. That should be developed independently from Hibernate or Spring. This is what we used to do 10 years ago right? My only problem with all this is it seems like object/class bloat. We could have DTOs converting ORM objects backed by XML into Domain/API objects. Then Service/API objects performing business logic on them. Then Web layer code converting Domain/API objects into View/Value type data objects for the GUI (json for example). Add in the fact that you have interfaces and impl classes everywhere at it seems like you need ten million classes for a simple round trip from the UI to the DB (Web VO / Domain / Service-API / DTO / ORM object). And if these things are somewhat similar we have all this code setting and getting stuff from one layer to another. Can’t there be just one thing we pass around?

    Is there some way to make the Domain/API objects both smart enough for business logic, but dumb enough (or maybe smart enough depending on your point of view) to be used by the Hibernate APIs / DTOs for persistence?
    And if we are only using Hibernate, and will be for the foreseeable future, do I really need the DTO layer? Can my API just talk to hibernate via the ORM classes? I mean common… I am stating to see why people like ruby these days

    This whole discussion also bleeds to the anemic domain model anti-pattern battle as well. I think I want a somewhat smart Domain model that uses inheritance and all that OO stuff. But if these domain model objects also double as hibernate mapper things maybe that breaks down?

  2. #2

    Default

    Quote Originally Posted by andrew_m View Post
    but what should the DAO layer return to the API layer…. full domain objects (which I consider part of the API), or the ORM objects that Hibernate generates with its DB mapping?
    I wouldn't couple DAO layer with API service layer by using Hibernate objects. If you use Hibernate generated objects in API service layer, it will be difficult to switch to other ORM model later like iBatis. Also for any change in your database schema, likely you have to change your code all the way up to service layer. Ok, there are some pros to use Hibernate objects end to end, like memory space, or around trip persistance etc, but more cons..

    but then we are not going to add any intelligence to these ORM objects, they are going to be simple getter/setter bean things just for talking to hibernate. So are we going to have all this code creating meaningful Domain objects (which may be a bit less anemic) out of the ORM objects?
    Usually we don't touch generated ORM objects. I believe the domain objects like these generted hibernate objects are for containing data. If you really want more intelligence with domain obejcts, you can consider to creat your domain objects (non hibernate generated ) for your api service layer with some levels of intelligence.


    I guess it all comes down to this…. how to the hibernate ORM objects fit into this architecture? Are they totally hidden from the API via the DAO?
    again, contain or hide your hibernate implementations within the DAL layer. Your api or service layer will use domain objects (may constructed from hiberbate generated objects)

    And if we are only using Hibernate, and will be for the foreseeable future, do I really need the DTO layer? Can my API just talk to hibernate via the ORM classes?
    I would use DTO(or non hinbernate domain objects). It seems object bloat as you said but you get great benefit of decoupling unless your system is short team project, or memory and code size sensitive..

  3. #3
    Join Date
    Mar 2008
    Posts
    19

    Default

    Thanks. I agree with everything said. Just wondering what other teams do.

    I am a little scared that the team here is going to freak out about the number of classes involved in a round trip...

    Web Service / Servlet / Other "web type thing"
    DTOs for giving info to the UI
    API / Domain object & API / Service objects
    DAO for accessing the DB
    Hibernate generate ORM objects

    .... but that's the beauty of abstraction I guess. It will pay off in the long run I am sure.

  4. #4
    Join Date
    Jun 2005
    Location
    London, uk
    Posts
    25

    Smile keep it real

    For what its worth I disagree.

    If you have choosen Hibernate then make your Hibernate real domain objects (with state and behaviour). Keep your persistance 'actions' within a service layer. For example this might be in your BusinessService:

    private DataService service;

    public void scoreGame(Long gameId) {
    Game game = service.getGame(gameId);
    game.score();
    service.saveGame(game);
    }

    Expose your domain object (detached) state to your web layer and allow the web layer to retrieve objects via their id.

    In my opinion you will end up with a much cleaner design and much less code to deal with making it easier to underdstand and therefore easier to change in the future.

  5. #5
    Join Date
    Mar 2008
    Posts
    19

    Default

    In service.saveGame(game) in the example above, would this be implemented by the service object interacting with hibernate directly or with the ORM objects?

    I am pretty sure we need a separate DTO layer to send to the client which is Flex. The client has specific needs and all sorts of UI controls bind directly to the objects we send it. Also the objects are serialized into a Flex/ActionScript version of the Java objects so they are pretty UI specific -- meaning that the domain objects which are intended to model the business process/problem aren't exactly what the UI would need.

    Some people are kicking around something which I would call the "grand unified domain object theory" which means the the domain objects are both the ORM objects via annotations to hiberate and DTO's. It seems clean but I just feel like it won't work in practice.

  6. #6
    Join Date
    Jun 2005
    Location
    London, uk
    Posts
    25

    Default

    In the example the DataService has a dataStore (hibernateDaoImpl) member variable and alot of the DataServices methods simply call methods on the datastore such as:

    public Long saveGame(Game game) {
    return (Long)dataStore.saveGame(game);
    }

    public List<Game> getGames() {
    return new ArrayList<Game>(dataStore.loadGames());
    }

    The DataService also retrieves data from other sources.

    It sounds like you do want to have some type of view object though. However I would still think your hibernate entities should be considered your domain objects with behaviour and then it is a case of formulating some strategy to produce and deliver your view objects (the view model can often be quite different from the domain model). The value in the system lies in the business logic of your domain model and not in the views of that model. If you are using Hibernate, to me it makes sense to use it to the benefit of the core system (i.e: use it to generate your domain model that carries state and implements behaviour).

  7. #7
    Join Date
    Mar 2008
    Posts
    19

    Default

    I am pretty new to hibernate so I am still not getting something...

    From what I can tell, hibernate has these low level ORM objects that are auto-generated from XML mapping files. Since these are auto generated, I don't think we can give them that much behavior, so they won't likely be "smart enough" to be a true domain model. Am I missing something?

    Are you saying you maintain domain objects and annotate them for the DB mapping?

  8. #8
    Join Date
    Jun 2005
    Location
    London, uk
    Posts
    25

    Default

    I wouldn't call myself an expert on Hibernate either but while you can autogenerate the hibernate objects (I have read!), you can also construct your domain objects and then map them so their state is persisted through hibernate. So you can treat them as normal Java objects and implement behaviour in those objects.

    In the system I am quoting from the Game has associations with Event, Pool (betting pool), Entry (with association to User) and Player. A settle() method on Game causes the game to check the Entrys for all its Pools and update the Accounts of Users who have made Entrys. In this domain model it makes sense to me to implement this as a method on Game because the game object has access to all the information it needs to complete the settlement process.

    As an add on to this design, the Game object is the parent class with child classes for different types of games. So the score() method will process differently depending on the game type.

    I am not using annotations... yet!

  9. #9
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Default

    Autogeneration is used relatively rarely and only early in the development phase to create object skeleton, to which you then can add any desired behavior.

    More typical approach is to create Java objects and only then mapping XML files or even avoid XML mapping completely and use annotations on your Java objects instead (note, it is possible to mix and match annotation and XML mappings if some Hibernate features are not available via annotations).



    Quote Originally Posted by andrew_m View Post
    I am pretty new to hibernate so I am still not getting something...

    From what I can tell, hibernate has these low level ORM objects that are auto-generated from XML mapping files. Since these are auto generated, I don't think we can give them that much behavior, so they won't likely be "smart enough" to be a true domain model. Am I missing something?

    Are you saying you maintain domain objects and annotate them for the DB mapping?

  10. #10

    Default

    I have started a new system as well. And have started down the road of exposing my Business Model objects which are hibernate persistance objects to my service layer. The problem I see is whe you have lazy initialization. It just does not seem right to me that the service layer has an object which has an attribute called say itemList which is a set of Item objects. However, since the itemList is lazily initialized it can not access it without opening a transaction/session. It seems that your data access layer now creeps into your service layer, and your service layer now has to know that something is lazily initialized or eagerly fetched. I am at a cross roads now as to best implementation.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •