Announcement Announcement Module
Collapse
No announcement yet.
Design issue (POJO and DTO/VO) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Design issue (POJO and DTO/VO)

    I am using struts -> Java Object (business Tier, e.g. Spring) -> Hibernate.

    General practice for sendnig data to DAO is through DTO/VO for coarse grain data transfer. With hibernate we have POJO which is same as DTO. Is it good practice to use POJO for data transfer from presentation tier to Hibernate DAO, that means web tier will instantiate the POJO class, populate the POJO object and send it to DAO for persistence.
    Or, shall we create separate DTO and separate POJO class ???

  • #2
    Use Domain Objects

    Hi Manjusingh,

    Here is a quote from Rob Harrop's and Jan Machacek's awesome Pro Spring (Chapter 11) about creating data transfer objects and using them to transfer data from the business tier to the data access tier (instead of just using the domain objects themselves):

    "Honestly, we cannot think of a reason you would want to do this; in our eyes, it seems that this practice has sprung up out of confusion on how certain J2EE patterns should be used."

    In addition, Christian Bauer and Gavin King explore the issue in Chapter 8 of their Hibernate in Action. They note that the data transfer pattern was invented because fine-grained remote access to entity beans was too slow and entity beans were not serializable.

    In the sample applications I have seen, it looks like people have avoided creating data transfer objects. You didn't really give any application-specific reasons for wanting to use data transfer objects, so I would default to using the domain objects directly and saving yourself from the code duplication and all the work to convert to and from the domain objects.

    Hope this helps!

    -Arthur Loder

    Comment


    • #3
      Different object graphs.

      I have a related question. I have a distributed architecture where the presentation tier makes remote service calls. I have a coarse grained interface where the methods can return more than one type of domain object and the domain objects are from unrelated object graphs. That means I have to "wrap" these objects in an outer object which I term a DTO. Just wondered if forum members think this is good design.

      Comment


      • #4
        I would argue that your case is a perfectly legitimate use of DTO - a wrapper to carry multiple data elements across a tier.

        Comment


        • #5
          Originally posted by kelly walker
          I have a related question. I have a distributed architecture where the presentation tier makes remote service calls. I have a coarse grained interface where the methods can return more than one type of domain object and the domain objects are from unrelated object graphs. That means I have to "wrap" these objects in an outer object which I term a DTO. Just wondered if forum members think this is good design.
          I think you use your DTOs as containers and so it is a very valid use case. The only problem is you need to code them manually so if you need a lot of them, it can be a lot of work. SDOs might offer a solution to this problem in the future (being able to pass any graph of objects and save/check changes made on them).

          Comment


          • #6
            The use case of Kelly Walker is a good example of using DTOs. Even in the normal use case of Manju Singh, I have seen some people recommend DTOs just to enable a loose coupling between the Web layer and the domain model. Using POJOs directly in the Web tier *will* couple the domain model with the Web model - hence any change in domain model is likely to have an impact on the Web tier as well.

            I would like to have the thoughts of the community on this aspect.

            Cheers.

            Comment


            • #7
              Originally posted by debasishg
              The use case of Kelly Walker is a good example of using DTOs. Even in the normal use case of Manju Singh, I have seen some people recommend DTOs just to enable a loose coupling between the Web layer and the domain model. Using POJOs directly in the Web tier *will* couple the domain model with the Web model - hence any change in domain model is likely to have an impact on the Web tier as well.

              I would like to have the thoughts of the community on this aspect.

              Cheers.
              Well you do have an added abstraction in the web tier, which is the view itself.

              If the domain model changed, then it is highly likely that the web tier would have to change anyway

              I think there *are* good reasons and situations in which that loose coupling is beneficial, but they are the exception, rather than the rule. After all, the purpose of most web apps is to interrogate the middle tier; they *are* coupled by definition.

              If you need to introduce an adapter between the web tier and the middle tier, then you can always do that as and when you need it, but until then just use the POJOs in the domain model.

              Comment


              • #8
                Originally posted by yatesco
                If you need to introduce an adapter between the web tier and the middle tier, then you can always do that as and when you need it, but until then just use the POJOs in the domain model.
                Just for my clarification and understanding, if I am designing a Struts based application, within my Action class, I will use the form data to construct my domain object (POJO) and kick in the validator to get things validated before submission. Is this the model that u r recommending ?

                Of course this gets rid of an entire layer of DTOs (which has no purpose in life but to transfer data across layers) and hence makes the codebase leaner .

                Cheers.

                Comment


                • #9
                  Originally posted by debasishg
                  Just for my clarification and understanding, if I am designing a Struts based application, within my Action class, I will use the form data to construct my domain object (POJO) and kick in the validator to get things validated before submission. Is this the model that u r recommending ?

                  Of course this gets rid of an entire layer of DTOs (which has no purpose in life but to transfer data across layers) and hence makes the codebase leaner .

                  Cheers.
                  Yes. This would be better IMO than constructing an ActionFormUser which constructed a UserVO (or UserDTO) which was passed to the middle tier which then persisted a User

                  I think you have it exactly right. ActionForm -> POJO.

                  Comment


                  • #10
                    Originally posted by debasishg
                    and hence makes the codebase leaner .
                    If you are serious about 'lean and mean' scenario, then drop the Struts altogether with its duplication of command beans (action forms AND domain objects). Use Spring MVC instead with its 'domain objects only' approach.

                    Comment


                    • #11
                      Struts and Spring MVC

                      Originally posted by Arno Werr
                      If you are serious about 'lean and mean' scenario, then drop the Struts altogether with its duplication of command beans (action forms AND domain objects). Use Spring MVC instead with its 'domain objects only' approach.
                      I agree. I just cited Struts as an example of an MVC implementation. I really like the architecture of Spring MVC - the combination of Spring data binder and domain objects really rock . And validators are wired extremely elegantly in the whole scheme of things.

                      Comment


                      • #12
                        I initially tried to use my domain POJO's as the command (form backing) objects in my web layer but quickly ran into a problem. I have a class called Alarm which contains a few basic fields, e.g. name, description etc, plus some others which are references to other classes e.g. AlarmSeverity and a couple of collections. So the class might look like

                        class Alarm{
                        Long id;
                        String name;
                        String description;
                        AlarmSeverity alarmSeverity;
                        Set<Action> actions;
                        }

                        I am using OpenLaszlo for the front end - not JSP of which I know nothing - and in OpenLaszlo when the user selects a severity level from a drop down list the form field simply records the 'id' of the severity. I believe this is the same with any html select box. The select box itself is contructed by reading all the AlarmSeverity objects and constructing a list of id's and related AlarmSeverity names.

                        Anyway, when the user edits some basic alarm details (e.g. changes the name or severity*) and submits the form I get the Alarm id, name and description and the id of the selected severity.

                        When I use the POJO as the backing bean this creates a problem since it doesn't contain a field for the severityId and the 'actions' collection is set to null.

                        To get around this I currently use the following architecture:

                        In the web 'controller' layer I have a DTO called AlarmDTO which looks like:

                        class AlarmDTO{
                        Long id;
                        String name;
                        String description;
                        Long alarmSeverityId;
                        }

                        As you can see the AlarmSeverity property has been replaced with a Long to record the id and the collection has been removed. This DTO is populated and validated by the controller and is then passed along to the service layer for persistence. The service layer has the following jobs:

                        1: Use the id in the alarmDTO to retrieve the original Alarm object - assuming it still exists.
                        2: Copy the properties from the alarmDTO onto the Alarm POJO.
                        3: For each reference id (e.g. alarmSeverityId) retrieve the actual POJO to which this refers and if this is not the same as the one referred to by the original Alarm then put this new alarmSeverity object into the Alarm object.
                        4: Finally save the Alarm object.

                        A similar situation arises because the Alarm is a child of another object and all the form sends me is the id of the parent not a parent object. You can imagine the service layer routine to resolve that.

                        At one point I had tried to get around this by adding extra id fields to the Alarm POJO so that in addition to the AlarmSeverity property I also had an alarmSeverityId Long property. This stopped me having a separate DTO but I still had the same service layer job to do to resolve the id's passed from the form plus an extra job since the controller was setting the collection to null so I still had to reread the original Alarm and copy the collections across to the Alarm object returned from the controller. I thought doing a merge rather than save would resolve this but it didn't seem to.

                        From the discussions I have seen on this thread I am clearly missing something and making my life way too difficult so I would appreciate someone showing me the error of my ways and putting me on the right path.

                        Many thanks and sorry for the long post.

                        Comment


                        • #13
                          When selecting an "AlarmSeverity" you should register a PropertyEditor to convert from the id to the actual AlarmSeverity, thus resulting in an alarm.setSeverity(theseverity) call.

                          Check out propertyEditors and do a search on here.

                          They are very powerful.

                          Comment


                          • #14
                            Thanks Colin,

                            Like all good answers it's obvious when pointed out :-) I've already been using custom PropertyEditors in a number of places but hadn't thought of using them in this way. I can see how this solves the AlarmSeverity problem. Thanks for the pointer.

                            However that still leaves the collections problem and I'm still unsure what to do about it. My understanding now is as follows:

                            I will now use the Alarm object as my form command object. When the form data is received a new Alarm object will be created by the controller and populated from the request parameters (using a PropertyEditor as you suggest to translate id's to object references .. that sounds great).

                            However there will be no 'child' objects (alarm actions in this case) nor even a list of child id's in the http request object so the 'actions' collection will be empty. So at the moment I am still left with some code in the business layer to read the original object from hibernate and then repopulate the collection on the new command object before the command object is saved over the top of the original.

                            Is there a standard way to resolve this issue as well ?.

                            Many thanks.

                            Comment


                            • #15
                              You can also bind straight onto a collection using http://www.springframework.org/docs/...ionEditor.html.

                              BTW; I find things get a lot simpler if you always initialise collections, i.e. private Set alarmActions = new HashSet();

                              The other thing to say is that you can override formBackingObject to return the domain object fully populated from the middle tier.

                              Comment

                              Working...
                              X