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

Thread: planning major migration to spring

  1. #1

    Default planning major migration to spring

    Before I get into the details let me give you some background. I have no real experience with spring/hibernate whatsoever, I am mostly done reading Rod Johnson's J2EE Development without EJB. I ordered Pro Spring and have the rod johnsons new book on backorder. I have been reading docs on this website and the hibernate website. I have been coding java for a long time but have somehow delightfully managed to completely avoid ejb. Many moons ago I did some ejb examples and read through the spec and then realized i wanted to avoid it at all cost. And then reconfirmed that when the 2.0 spec came out.
    However, because I have not done ejb I am struggling to catch up with some of the lingo and design patterns. It seems that one very valuable thing about working in EJB, which I wish I had now, is it got programmers on the same page in terms of design patterns and common implementations.

    So anyways, I am planning to migrate a large application to hibernate spring. The application now has a Swing front end that operates on monolithic data objects. There is a networked database involved which currently is wide open on the network and is connected to directly through jdbc. I plan to go to spring on jetty or tomcat with http invokers to hit the networked db. Additionally, this system has a very complex user, role/data groups security system that I am really excited to hopefully make less complex by implementing the Acegi Security or some kind of AOP security.

    To make a long story short I already did one migration on this code, it was originally spaghetti code with sql and business logic scattered throughout the swing code. I migrated to what i call monolithic data objects. They contain the basic CRUD implementation along with static searching/finder methods and all the object specific business logic code.

    So, I am trying to plan my migration path to spring/hibernate. I am thinking that it would be best if I first get hibernate going and then once that is working move to spring. Then finally strip out my security code and re do with Acegi. Does that sound right?

    However the way I see it, before I can do anything I should first fix(seperate) my monolithic data objects. But I am not sure what the best way to do this is or should I say what the ideal end result should be. I guess I am asking for some basic best practices recommendations, in terms of the architecture to appropriately layer your data access code,global finder/search code, and business logic code.

    From what I am reading it sounds like I should strip them down to bear bones properties and the dao(CRUD) impllementation. At that point they will be very hibernate friendly and generally true DAOs. This seems to be fairly standard, why do you not want any business logic in there?

    But I am unsure as to what then to do with all my static search methods:
    public static Collection getSomeDataObjects(int filter1, int filter2, etc)
    {
    return all matching objects in db;
    }

    And what do I do with all this business code? I am not even sure if I am envisioning business code correctly. Like is this business code:
    public void calulateObjectValue(Object someParameter, Object someOtherObject)
    {
    this.someValue = result of some caclulation based on someParameter and somOtherObject;
    }


    Should I create corresponding factory objects that handle instantiation and the searching and the business logic? Or is there a 3rd tier I should go with and should the factory objects only be for instantiation and search method? Or am I way off?

    I realize some of these questions maybe rudimentary, but I would appreciate some help on the data object separation. And I would really be interested into some insight/recommendations to the best path for me to get on spring/hibernate?

    thanks a ton
    -ryan

  2. #2
    Join Date
    Aug 2004
    Location
    Melbourne, Australia
    Posts
    1,104

    Default

    I ordered Pro Spring and have the rod johnsons new book on backorder
    I believe the orignal book, J2EE Design and Development is still very relevant and useful.

    It seems that one very valuable thing about working in EJB, which I wish I had now, is it got programmers on the same page in terms of design patterns and common implementations.
    I wouldn't bestow that compliment on EJB. Useful design patterns are independent of EJB, and many EJB specific design patterns are basically EJB workarounds.

    I am thinking that it would be best if I first get hibernate going and then once that is working move to spring
    I'd recommend implementing the DAO with Spring/Hibernate from the start. Spring reduces your Hibernate code, and doing this later just adds an extra step. You can also setup integration tests using AbstractTransactionalSpringContextTests from the beginning.

    However the way I see it, before I can do anything I should first fix(seperate) my monolithic data objects. But I am not sure what the best way to do this is or should I say what the ideal end result should be.
    This is hard to answer - basically you have to make the data objects into domain objects. Move as much business logic as possible into them. Validation logic can be kept in a validator. Persisence logic is usually best separated into a persistence layer. You'll also want to put some thought into your associations so they are used efficiently (e.g. efficient DB access). You'll probably want to read up on Hibernate (Hibernate In Action is good).

    ...true DAOs. This seems to be fairly standard, why do you not want any business logic in there?
    To make the business layer independent of persistence - this has design benefits including more testable and portable code.

    But I am unsure as to what then to do with all my static search methods
    They can become non-static - Spring can wire the DAOs as singletons.

    And what do I do with all this business code? I am not even sure if I am envisioning business code correctly.
    Keep it in a separate layer. It contains as much logic specific to the business as possible. The business layer is also typically where you apply transactions - for example a businness method may call several DAOs in one transaction.

  3. #3

    Default

    Quote Originally Posted by katentim
    I believe the orignal book, J2EE Design and Development is still very relevant and useful.
    Thanks for the reply I will look into that book as well.

    Quote Originally Posted by katentim
    I'd recommend implementing the DAO with Spring/Hibernate from the start. Spring reduces your Hibernate code, and doing this later just adds an extra step. You can also setup integration tests using AbstractTransactionalSpringContextTests from the beginning.
    I could see the value when you put it that way. I am hoping I can at least take a first step by reorganizing my data object code.

    Quote Originally Posted by katentim
    This is hard to answer - basically you have to make the data objects into domain objects. Move as much business logic as possible into them. Validation logic can be kept in a validator. Persisence logic is usually best separated into a persistence layer. You'll also want to put some thought into your associations so they are used efficiently (e.g. efficient DB access). You'll probably want to read up on Hibernate (Hibernate In Action is good).
    .
    .
    To make the business layer independent of persistence - this has design benefits including more testable and portable code.
    Well If create domain objects with a separate persistence layer for every object I have, I assume I am not going to be duplicating the bean properties. But am I rather creating a persitable object and then creating a parent domain object which performs operations on it?

    What confuses me is in the JPetstore example it appears as if the domain objects are simple bean properties. This is sort of what I imagined the persistence layer to be with the addition of a crud interface.

  4. #4
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    Well If create domain objects with a separate persistence layer for every object I have, I assume I am not going to be duplicating the bean properties. But am I rather creating a persitable object and then creating a parent domain object which performs operations on it?
    No, that is not correct. You give the domain object (bike for example) to the DAO (Data Access Object). The Dao`s have methods like save(bike), delete(bike), findAllBikes() etc, but they work on domain objects. Your DAO objects won`t have any properties like the domain objects have.. and the domain object, helped by the DAO (the DAO does all translations from domainobject to db and db to domainobject), is the object that is persisted.

  5. #5

    Default

    Quote Originally Posted by Alarmnummer
    No, that is not correct. You give the domain object (bike for example) to the DAO (Data Access Object). The Dao`s have methods like save(bike), delete(bike), findAllBikes() etc, but they work on domain objects. Your DAO objects won`t have any properties like the domain objects have.. and the domain object, helped by the DAO (the DAO does all translations from domainobject to db and db to domainobject), is the object that is persisted.
    Ahhhh that seems more consistent with the examples. So if I want to take a step towards realigning these objects before I do the full spring/hibernate implementation, I should just pull all the sql code out of my data objects and create a dao object per domain object which will just do my CRUD implementation and my finders?

    Then I will use the DAO object as a singleton?? which my domain object can get access to along with the rest of my model code to do any persistence or loading from my db?

  6. #6

    Default

    Ok here is my issue with the DAO pattern please correct my viewpoint. Currently I have a CRUD interface:
    Code:
    public interface CRUD
      {
      /**
       *@throws java.sql.SQLException exception handled by calling class   *
       * @param id the id of the record to be loaded
       * @return true  if the load was successful otherwise false
       */
      public boolean load(int id) throws java.sql.SQLException;
      /**
       * creates a record
       * @return the id generated from the insert a value <0 indicates an error
       *@throws java.sql.SQLException exception handled by calling class
       */
      public int create&#40;&#41; throws java.sql.SQLException;
      /**
       * updates the database row
       * @return true if the update was successfule otherwise false
       *@throws java.sql.SQLException exception handled by calling class   
       */
      public boolean update&#40;&#41; throws java.sql.SQLException;
      /**
       * deletes the database row
       * @return true if the delete was successful or false otherwise
       *@throws java.sql.SQLException exception handled by calling class
       */
      public boolean delete&#40;&#41;throws java.sql.SQLException;
      &#125;
    I apply this crud interface to all my domain objects. I do this by having an abstract DataObject class which implements this interface partially. All my objects fully implement the DataObject class. In this manner i can reference all these objects using their CRUD interface and they function the same, i find this pretty darn handy. Plus it is all self contained.
    So currently I have a Widget DataObject. I can perform actions on the widget like so:
    Code:
    Widget widget = new Widget&#40;widgetId&#41;;
    widget.setName&#40;"New Name"&#41;;
    widget.update&#40;&#41;;

    Now, the DAO pattern requires me to create a DAO interface and implementation for every object I have. So:
    Code:
    public interface WidgetDAO
    &#123;
      public Widget getWidget&#40;int id&#41; throws java.sql.SQLException;
      public int createWidget&#40;Widget widget&#41; throws java.sql.SQLException;
      public boolean updateWidget&#40;Widget widget&#41; throws java.sql.SQLException;
      public boolean deleteWidget&#40;Widget widget&#41;throws java.sql.SQLException;
    &#125;
    public WidgetDAOImpl implements WIdgetDAO
    &#123;
    .
    .
    &#125;
    There is no common thread then in this manner. I will have a different interface for all my objects gadgets, widgets, items, products, etc.

    To perform the same actions i demonstrated above I have to do this which WidgetDAO
    Code:
    widgetDao = WidgetDAOImpl.getInstance&#40;&#41;;
    Widget widget = widgetDao.getWidget&#40;widgetId&#41;;
    widget.setName&#40;"New Name"&#41;;
    widgetDao.update&#40;widget&#41;;
    This seems to be a regression in some ways to me. Am I missing something here?

  7. #7
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    Quote Originally Posted by wexwarez
    Ahhhh that seems more consistent with the examples. So if I want to take a step towards realigning these objects before I do the full spring/hibernate implementation, I should just pull all the sql code out of my data objects
    Sql code belongs to the DAO`s... The DAO`s is the gateway between the database and your domain model.

    and create a dao object per domain object which will just do my CRUD implementation and my finders?
    That is correct.

    Then I will use the DAO object as a singleton??
    This could be a solution for the moment, just like a 'service locator'. But Spring does a beautifull job at that. With Spring you don`t have to worry how the get references to dao`s for example. You can inject those references in the services that need those doa`s.

  8. #8
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    To perform the same actions i demonstrated above I have to do this which WidgetDAO
    Code:
    widgetDao = WidgetDAOImpl.getInstance&#40;&#41;;
    Widget widget = widgetDao.getWidget&#40;widgetId&#41;;
    widget.setName&#40;"New Name"&#41;;
    widgetDao.update&#40;widget&#41;;
    This looks reasonable.

    This seems to be a regression in some ways to me. Am I missing something here?
    It feels less object oriented But persistance is only an aspect of your system, just like logging, security etc. If you mix all those aspects of your system in a single class, your class will get bloated. Sometimes it is better not to rely in inheritance but on other techniques to seperate those aspects (concerns).

    The advantage of separation:
    -single place where all the db code is (this makes it a cleaner design)
    -easier to replace the whole dao implementation with something else.
    -less long classes.
    -you are limited to the functionality with your approach the classes have to offer. If you seperate those aspects and only let them depend on the domain model, it is easy to add new peaces of functionality (new aspects) to your system.

    And there have to be more

  9. #9

    Default

    It feels less object oriented Smile But persistance is only an aspect of your system, just like logging, security etc. If you mix all those aspects of your system in a single class, your class will get bloated. Sometimes it is better not to rely in inheritance but on other techniques to seperate those aspects (concerns).

    The advantage of separation:
    -single place where all the db code is (this makes it a cleaner design)
    -easier to replace the whole dao implementation with something else.
    -less long classes.
    -you are limited to the functionality with your approach the classes have to offer. If you seperate those aspects and only let them depend on the domain model, it is easy to add new peaces of functionality (new aspects) to your system. [/code]
    Alright I guess the separation makes a lot of sense conceptually. My thing though is from a practical perspective when persisting to a db is such an obvious and central requiirement of an application it seems you are separating the inevitable.

    But If I may- I have one more question about this whole separation dao thing. Undoubtable an application will have domain objects which contain other domain objects, For instance if you have a Customer object it might contain a list of Order objects. Now in this case your db would have a customer table and an order table with a joiner linking them. When you work with the Customer Object you would want to be able to get all the customer orders. I would want to have a method getOrders in the Customer object like so:
    Code:
     customer.getOrders&#40;&#41;;
    public class Customer
    &#123;
    private int id;
    Collection getOrders&#40;&#41;
    &#123;
    OrderDAO orderDAO = OrderDAO.getInstance&#40;&#41;;
    return orderDAO.getOrdersByCustomerId&#40;this.id&#41;;
    &#125;
    Is this appropriate? I ask because it would entail the customer having access to the OrderDAO object.

    Or take another case - a Customer has an Address. Where in the db you have a Customer table that has an address_id on it and then an Address table.
    Code:
    public class Customer
    &#123;
    private int id;
    private Address address;
    
    private Address getAddress&#40;&#41;
      &#123;
      returnaddress;
      &#125;
    private setAddress&#40;Address address&#41;
      &#123;
      returnaddress;
      &#125;
    
    &#125;
    In this case the customer would have to load the address in the CustomerDAO:
    Code:
    public class CustomerDAOImpl implements CustomerDAO
    &#123;
    Customer getCustomer&#40;int id&#41;
      &#123;
      Customer returnValue = new Customer&#40;&#41;;
      int customerAddressId ;
      //some kind of sql to get the customer values and the address id from the customer table
      AddressDAO addressDAO = AddressDAOImpl.getInstance&#40;&#41;;
      returnValue.setAddress&#40;addressDAO.getAddress&#40;customerAddressId&#41;;
      return returnValue;
      &#125;
    &#125;
    So in this case the CustomerDAO has to have access to the AddressDAO is that the right way to do this? Or do you get access to the AddressDAO in the actual customer class like so:

    Code:
    public class Customer
    &#123;
    private int id;
    private int addressId;
    
    private Address getAddress&#40;&#41;
      &#123;
      AddressDAO addressDAO = AddressDAOImpl.getInstance&#40;&#41;;
      return addressDAO.getAddress&#40;addressId&#41;;  
      &#125;
    private setAddress&#40;Address address&#41;
      &#123;
      addressId = address.getId&#40;&#41;;
      &#125;
    &#125;

  10. #10
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    Quote Originally Posted by wexwarez
    My thing though is from a practical perspective when persisting to a db is such an obvious and central requiirement of an application it seems you are separating the inevitable.
    You have a point there. I have no problem with the seperation domain objects and the dao`s.. domain objects can be complicated enough...

    For instance if you have a Customer object it might contain a list of Order objects. Now in this case your db would have a customer table and an order table with a joiner linking them. When you work with the Customer Object you would want to be able to get all the customer orders. I would want to have a method getOrders in the Customer object like so:
    Code:
     customer.getOrders&#40;&#41;;
    public class Customer
    &#123;
    private int id;
    Collection getOrders&#40;&#41;
    &#123;
    OrderDAO orderDAO = OrderDAO.getInstance&#40;&#41;;
    return orderDAO.getOrdersByCustomerId&#40;this.id&#41;;
    &#125;
    Is this appropriate?
    The method call itself is valid and that is how I model some relations in my system. Sometimes it is better to call the domain object to get the related objects, but sometimes I don`t model the relations in Java and retrieve the related objects from a Dao:

    eg:
    List childeren = personDao.getChildren(peter);

    I don`t have good guidelines when to choose one or the other.

    I ask because it would entail the customer having access to the OrderDAO object.
    Hmm you are partially right. Hibernate solves this problem by using a proxy around collections (if those collections are made lazy). If you access the list, the objects are retrieved from the database but this is totally transparent to the programmer.

    eg:
    Code:
    class Persoon&#123;
    
         private List _childList; 
    
         void setChildList&#40;List childList&#41;&#123;_childList = childList;&#125;
    
         List getChildList&#40;&#41;&#123;return _childList;&#125;
    &#125;
    Do you see any db access code here? No.. that is because Hibernate wraps lazy-proxies around the childlist.

    So in this case the CustomerDAO has to have access to the AddressDAO is that the right way to do this? Or do you get access to the AddressDAO in the actual customer class like so:
    I have only experience with Hibernate. Hibernate doesn`t depend on my dao`s to get objects from the db. Hibernate knows how my domain objects are mapped and he has enough information to retrieve the adres if that is required.

    You have some valid points, but I think as soon as you move to a OR-mapper like Hibernate a lot of your questions will disapear.

Similar Threads

  1. Spring MVC Web Framework versus Struts
    By biguniverse in forum Web Flow
    Replies: 27
    Last Post: Aug 29th, 2012, 03:57 AM
  2. Replies: 5
    Last Post: Aug 9th, 2008, 05:30 AM
  3. Gaijin Studio for Spring MVC 0.9.2 Released
    By dadams in forum Announcements
    Replies: 8
    Last Post: May 30th, 2007, 10:48 PM
  4. A Spring Class Loader?
    By azzoti in forum Architecture
    Replies: 8
    Last Post: May 7th, 2005, 04:02 AM
  5. Replies: 14
    Last Post: Feb 21st, 2005, 05:41 PM

Posting Permissions

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