Announcement Announcement Module
Collapse
No announcement yet.
planning major migration to spring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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.

    Comment


    • #3
      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.

      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.

      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.

      Comment


      • #4
        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.

        Comment


        • #5
          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?

          Comment


          • #6
            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?

            Comment


            • #7
              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.

              Comment


              • #8
                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

                Comment


                • #9
                  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;

                  Comment


                  • #10
                    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.

                    Comment


                    • #11
                      Thanks for all your replies, definitely lots of help.

                      I guess I am going to proceed. I am glad it is "ok" for you domain objects to reference the DAOs. I can't really see how else I would do it:?:

                      I am still questioning the separation of the dao from the domain objects, i am sure implementing spring and hibernate will make my code base cleaner, but I still disagree with this. I don't even really understand the argument that people preach how the big benefit is it allows for independant testing - independant of what? I can just not call the db methods if i want to test without the db. Plus generally testing the db interaction is a very important part , if not one of the biggest points of failure that needs to be tested.

                      It is just so convenient to have your domain objects self aware of their data store. You know I was looking and saw this article:
                      http://www.theserverside.com/news/th...hread_id=33387
                      Which seems to detail a strategy of DAO that leaves the domain objects fully aware of the dao implementation.

                      Comment


                      • #12
                        Originally posted by wexwarez
                        Thanks for all your replies, definitely lots of help.

                        I guess I am going to proceed. I am glad it is "ok" for you domain objects to reference the DAOs. I can't really see how else I would do it:?:
                        My domain objects aren`t aware of dao`s. In the servicelayer I combine the doa`s and domain objects.

                        I don't even really understand the argument that people preach how the big benefit is it allows for independant testing - independant of what?
                        Independant of the dao implementation. I could use a mockdao instead of a hibernate dao. But to be honest I find this not a very strong argument There are so many unwritten semantic rules that differ from OR-mapper to OR-mapper (especially if you make full use of the functionality of the or mapper). I don`t think anyone can switch the dao implementation without breaking something

                        But I like the fact dat my domain logic is seperated from my db logic. This makes working with a lot easier..

                        I can just not call the db methods if i want to test without the db. Plus generally testing the db interaction is a very important part , if not one of the biggest points of failure that needs to be tested.
                        Hmmm.. to be honest I`m a bit dissapointed in the whole 'enterprise application' stuff.. to many questions.. nobody has answers.. everybody is shouting this is bad.. that is good... (especially martin fowler), but you`ll never get your questions answered .. never practical solutions.

                        You can better have a bad but working solution, than no solution at all.

                        Comment


                        • #13
                          I just wanted to add some support to this post, as it's consistent with my experience too....

                          Originally posted by Alarmnummer
                          My domain objects aren`t aware of dao`s. In the servicelayer I combine the doa`s and domain objects.
                          Exactly. Services layer combine DAO layer with your domain objects (DOs). You can certainly inject collaborators like a DAO into your DOs, but you'll run into conceptual issues (which admittedly are all addressable, but you'll have less in the way of support and patterns to fall back on):

                          - You'll need to autowire, so using the new operator is out
                          - You'll need to worry about serialization - big time - if you want to store a DO inside a HttpSession object (extremely likely in a web app) or shoot it across the wire to a remote bean
                          - You'll need to consider performance of all this injecting and autowiring (at least benchmark doing it 10,000 times)
                          - You'll need to think about transaction isolation (and its fetching strategy cousin), as the best practice is undoubtedly to lazy load everything and have use-case specific services layer methods that fetch only what associations you require

                          The recommended way is generally pretty good:

                          - Reusable DOs across services and persistence (DAO) layers
                          - Services layer is wired with the DAO
                          - Services layer is where your web services and/or web tier connect with the backend (no layer aside from the services layer may use persistence layer methods - except for very specialised Validators, but they'll need to ensure they evict loaded objects from the session to avoid Hibernate issues)
                          - Services layer is where you get transaction isolation to take place
                          - Services layer is where you define use-case specific finders and getters that fetch the necessary associations for your use case (this is because the services layer will have transaction scope and the Hibernate session will still be open, which helps you get transparent lazy fetching)
                          - Services layer is where you define your security AOP (ideally using Acegi Security instead of something home-grown or based on the web layer)

                          Originally posted by Alarmnummer
                          I don't even really understand the argument that people preach how the big benefit is it allows for independant testing - independant of what?
                          Independant of the dao implementation. I could use a mockdao instead of a hibernate dao. But to be honest I find this not a very strong argument There are so many unwritten semantic rules that differ from OR-mapper to OR-mapper (especially if you make full use of the functionality of the or mapper). I don`t think anyone can switch the dao implementation without breaking something
                          The OR-specific mapper sematics are *very* real. The time invested in developing MockDao implementations would generally be better spent thinking through database population and regression strategies for your unit tests to operate on a real database (or at least an in-memory database). Using your real database also lets you push the envelope in terms of using its inherint RDBMS capabilities. The J2EE ideology of achieving database independence (and now DAO layer independence) is simply misplaced in 99% of cases. Of course there are exceptions, like for frameworks that need to support just about anything (eg in Acegi Security our AuthenticationDao is designed to work with anything from a HashMap to a RDBMS). But for real-world application developer developed applications (as distinct from frameworks), stick to your preferred RDBMS from the outset and skip the entire pluggable DAO implementation ideal. You'll just waste time, or far more likely, not use extremely desirable persistence layer and/or RDBMS layer optimisations. One aside though: don't needlessly use your persistence layer classes and interfaces outside the DAO layer. An import org.hibernate.* anywhere but in a DAO-related class is a flag that something needs a closer look.

                          Originally posted by Alarmnummer
                          But I like the fact dat my domain logic is seperated from my db logic. This makes working with a lot easier..
                          Not to mention that if you write your DAO interface and DAO base implementation properly, you'll achieve great code reuse and write few methods. Indeed we *only* ever need to write use-case specific finders in the DAO implementation. Check out Acegi Security CVS' "domain" subproject and you can check out the code we use in-house for real projects, which relies on generics to achieve even more reuse.

                          I can just not call the db methods if i want to test without the db. Plus generally testing the db interaction is a very important part , if not one of the biggest points of failure that needs to be tested.
                          Testing generally is about trade-offs. It's rare that real world projects have enough free time + resources to build unit tests for every single layer. So you target the layer that uncovers the most problems and provides the greatest regression identification confidence, which is the services layer. The web layer changes constantly, but is useful if you get free time. I recommend using Grinder 3 for sheer web capacity testing, and jWebUnit for web unit testing. In real world projects I also find that writing a DatasetPopular which implements InitializingBean very useful. You have all your services layers setup as collaborators, and it simply does a getAll() during startup for a central domain class. If it finds no records, it knows to populate the database. It does this via the services layer, so in effect you get a lot of seed data nicely generated (via the services layer = a basic test) without investing time to write a unit test or external SQL script to do it. Your unit tests then focus on creating more test-specific data, modifying it, using finders etc via the services layer.

                          Originally posted by Alarmnummer
                          Hmmm.. to be honest I`m a bit dissapointed in the whole 'enterprise application' stuff.. to many questions.. nobody has answers.. everybody is shouting this is bad.. that is good... (especially martin fowler), but you`ll never get your questions answered .. never practical solutions.
                          At least in Spring land you get real world as *the* top priority. People are quick to get into ideological arguments in the J2EE world. People can feel right at home around here if they stick to what will work with the minimal amount of effort. That actually sounds a lot like true XP.

                          Originally posted by Alarmnummer
                          You can better have a bad but working solution, than no solution at all.
                          At a practical level much of J2EE development is "glorified cut 'n' copy". Many projects get in the experts to build a proof of concept, which just gives the careful structure for the rest of the app to be based on. If you aren't lucky enough to have access to such experts, the next-best-thing is to build a vertical slice as quickly as you can. ie: a persistence DAO implementation and interface, a services layer and implementation, a few web controllers (probably a combined create/edit controller, and a separate search controller), and a view (written in your choice of template engine). Do this for two or three DOs so that you have a couple of associations and can experiment with fetching strategies etc. Once you've got it working, go back and refactor until it has as little code as possible and as much reuse as possible. You then have your vertical slice for the rest of the app to be based on. As I mentioned, if you check out Acegi Security CVS you can save writing the DAO and services layers as it's already done for you in a Hibernate-centric setup.

                          Good luck!

                          Comment


                          • #14
                            First of all I just want to say how much I appreciate you well thought out replies. This discussion is a tremendous help to me.

                            Originally posted by Alarmnummer
                            My domain objects aren`t aware of dao`s. In the servicelayer I combine the doa`s and domain objects.
                            Originally posted by Ben Alex
                            Exactly. Services layer combine DAO layer with your domain objects (DOs). You can certainly inject collaborators like a DAO into your DOs, but you'll run into conceptual issues (which admittedly are all addressable, but you'll have less in the way of support and patterns to fall back on):
                            This brings up the piece of the puzzle I am missing - the Service Layer. I guess this is the place where I would put my HttpInvoker code and such. Is it essentially just a transport layer between the domain layer and the presentation layer? Or is there more too it that that?

                            Currently most of my logic is embedded in my domain objects so my presentation layer calls them for just about everything. It seems that my service layer would repeat a lot of my dao layer methods. A majority of what I do from the presentation layer is get some data, do something with it and then update it to the database. Which in my mind is the DAO layer, are you just repeating this layer while wrapping it in the transport (http invokers)?


                            Originally posted by Ben Alex
                            - Services layer is where you define use-case specific finders and getters that fetch the necessary associations for your use case (this is because the services layer will have transaction scope and the Hibernate session will still be open, which helps you get transparent lazy fetching)
                            Similar to my response above, I am currently working on a vertical slice with a single domain object and I defined all my specific finders in the DAO. You are suggesting that I do this in the service layer, but don't I have define these data access methods in DAO layer? Why define them twice?

                            Originally posted by Ben Alex
                            - Services layer is where you define your security AOP (ideally using Acegi Security instead of something home-grown or based on the web layer)
                            I hope to implement this because I have a complex security system, with role and data based permissions. I was planning to implement the data based permissions at the DAO layer because that seems appropriate. Like some users will not have delete or update privileges so from my limited reading I figure I apply some type of aspect to all the update methods in the DAO layer that check for permission. Is this inappropriate?



                            Originally posted by Alarmnummer
                            Independant of the dao implementation. I could use a mockdao instead of a hibernate dao. But to be honest I find this not a very strong argument There are so many unwritten semantic rules that differ from OR-mapper to OR-mapper (especially if you make full use of the functionality of the or mapper). I don`t think anyone can switch the dao implementation without breaking something
                            Originally posted by Alarmnummer
                            Hmmm.. to be honest I`m a bit dissapointed in the whole 'enterprise application' stuff.. to many questions.. nobody has answers.. everybody is shouting this is bad.. that is good... (especially martin fowler), but you`ll never get your questions answered .. never practical solutions.
                            well you guys are answering lots of my questions.

                            I appreciate your candor. So far I do feel like my code is ballooning rather than getting smaller. I just took one of my data objects and created a domain object, dao interface, dao impl, and now I am trying to figure out a service layer for that. But I am seeing some benefits to the organization. And I think if I get the application springized in a basic sense, then I can start delving into aspects and I hope that will pay off big time. So, I guess I will reform my opinion when this is all said and done.

                            Originally posted by Ben Alex
                            At a practical level much of J2EE development is "glorified cut 'n' copy". Many projects get in the experts to build a proof of concept, which just gives the careful structure for the rest of the app to be based on. If you aren't lucky enough to have access to such experts, the next-best-thing is to build a vertical slice as quickly as you can. ie: a persistence DAO implementation and interface, a services layer and implementation, a few web controllers (probably a combined create/edit controller, and a separate search controller), and a view (written in your choice of template engine). Do this for two or three DOs so that you have a couple of associations and can experiment with fetching strategies etc. Once you've got it working, go back and refactor until it has as little code as possible and as much reuse as possible. You then have your vertical slice for the rest of the app to be based on. As I mentioned, if you check out Acegi Security CVS you can save writing the DAO and services layers as it's already done for you in a Hibernate-centric setup.

                            Good luck!
                            I am currently working on a vertical slice. I took a look at the Acegi code base but I don't understand what exactly it does much less how the code base is organized. Is there another (possible simpler) example of a clear Service Layer that uses HttpInvokers?

                            Comment


                            • #15
                              Originally posted by wexwarez
                              This brings up the piece of the puzzle I am missing - the Service Layer. I guess this is the place where I would put my HttpInvoker code and such. Is it essentially just a transport layer between the domain layer and the presentation layer? Or is there more too it that that?
                              It is a lot more. THe Service layer is 'the' layer of your system where all of your business methods can be found. Methods like, fireEveryone, or transfer(Account from, Acoutn to, Money amount)

                              The service layer is the most important layer of your system, it defines the functions your system can do, it also defines security and transactions. You service layer must be totally unaware of your weblayer (struts, maverick, jsf) etc.

                              It seems that my service layer would repeat a lot of my dao layer methods.
                              Your service layer has more responsibilities than only business methods. It also regulates transactions, security etc.

                              I hope to implement this because I have a complex security system, with role and data based permissions. I was planning to implement the data based permissions at the DAO layer because that seems appropriate.
                              It should be part of the service layer and not part of the dao. The Dao layer is the layer under the service layer and nobody has access to it apart from the service layer.

                              Domain objects are strange things btw. A layer should not have dependencies to the layer above, or to the layers under that layer.

                              A
                              _
                              B
                              _
                              C
                              _
                              D

                              This is a stack of layers. If you look at layer B, it should not depend on Layer A, and it should not depend on Layer D. It only should depend on layer C. Domain objects from the domain layer are strange things because the don`t obey this contract.

                              A:Weblayer
                              -
                              B:Service layer| Domain Objects
                              -
                              Cao

                              Layer C (the DAO layer) depends on domain objects..
                              I just took one of my data objects and created a domain object, dao interface, dao impl
                              Kick the dao-interface

                              and now I am trying to figure out a service layer for that.
                              The service layer does a lot of forwarding to the dao layer, only adding transactions and security.

                              Warning: don`t get stuck on 'the is the way to do it'. Every project is different and some solutions are to heavy. At the company I work for we now have 2 different strategies for building webapplications. If the application doesn`t have much logic, we choose for the simple version (no service layer at all.. and no unused interfaces). If the application has logic we choose the 'this is how it should be done' approach.

                              Comment

                              Working...
                              X