Announcement Announcement Module
Collapse
No announcement yet.
Confused on domain objects vs transfert objects and DAO Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Confused on domain objects vs transfert objects and DAO

    Hi,

    After a lot of reading, including Rob's book and some topic on this board including http://forum.springframework.org/showthread.php?t=9818 I am quite confused on how to implement our new system.

    First of all what is or should be the relation between domain objects or transfert objects when dealing with an MVC tier? Do you need both?

    Currently, I have a CRUD type application with few business logic and using JDBC. Should my DAO produce complete domain objects that can be passed to the MVC tier or simple transfert objects assembled by the business layer? Or in other words, should DAO build transfert objects that contain tranfert objects of another class? This is confusing because right now I'm running into a few problems like cross-referencing DAOs.

    Also, should the object passed to the MVC have only properties of simple types? Because otherwise my property editors need a reference the business facade to create its sub-objects.

    What good practices or advices would you suggest to model such a system and adress these problems?

    Thanks
    Last edited by robyn; May 14th, 2006, 05:43 PM.

  • #2
    Generally (this does vary):

    - No need for DTOs initially (start with domain objects alone).
    - Using an ORM solution will mean you can happily have Collections of domain objects within your domain objects, as well as proper references to other domain objects (not merely their identifier property).
    - Using Spring MVC you just write a custom PropertyEditor to display your domain object properties (we typically output the "natural business key" - ie a key that has business meaning like a stock keeping unit - of references held by a domain object to other domain objects).

    One challenge you'll probably run into is you need to sacrifice certain OO benefits if using a "universally acceptable domain object". Such as you must provide default no arg constructors, public getters/setters for each method, no validation at time of construction or property setting (as related properties may not have yet been set). These are the technical constraints of a rich domain model when being shared with frameworks that provide your persistence management or web tier management. Of course, DTOs are free of such limitations as you write everything twice and can target accordingly.

    Comment


    • #3
      AOP to the rescue?

      An idea:

      Why not create an AOP BeanPostProcessor which accepts some sort of mapping between properties and other bean-id's methods, so that when the client calls an uninitialized field, the AOP proxy will generate a call to the server and retrieve them (the mapping will tell the proxy what bean-id and method to call).

      For example, given a dept-emp scenario, we will wrap the DAOs with an interceptor for certain or all methods which returns a proxy. The proxy is given for each method the appropriate service+method to call when needed. This will save us using XDoclet and the likes, and will help us unite the domain and DTO layers.

      This should be a part of the Spring MVC framework, or perhaps the DAO framework.

      What do you think?

      Comment


      • #4
        Re: AOP to the rescue?

        Originally posted by arikkfir
        For example, given a dept-emp scenario, we will wrap the DAOs with an interceptor for certain or all methods which returns a proxy. The proxy is given for each method the appropriate service+method to call when needed. This will save us using XDoclet and the likes, and will help us unite the domain and DTO layers.
        Perhaps I misunderstand your requirements, but it would seem to me far easiler to let Hibernate deal with such things. Intercepting domain object instances is rarely as simple as it sounds, and in my experience will make those instances incompatible with things like Hibernate. I'd suggest you try reviewing the Hibernate documentation, and if you can't find an elegant way to do it with Hibernate, try asking on the Spring Data Access Forums, where many helpful people will be able to guide you. I'd find it odd there's a need for a new interceptor which nobody else has required to date. Probably 90% of all Spring applications are data access oriented, after all.

        Comment


        • #5
          Domain Proxying

          I'm talking about a scenario where a domain object is serlialized to the client tier, where I don't (nor shouldn't I believe) have the Hibernate runtime or access to the database.

          How else would you transfer your domain objects to your client tier? either you create DTOs, or make sure all your associations are NOT lazy. Both these options have upsides and downsides. My suggestion, although not perfect, might remedy that I believe.

          Comment


          • #6
            Re: Domain Proxying

            Arik,

            Originally posted by arikkfir
            I'm talking about a scenario where a domain object is serlialized to the client tier, where I don't (nor shouldn't I believe) have the Hibernate runtime or access to the database.

            How else would you transfer your domain objects to your client tier? either you create DTOs, or make sure all your associations are NOT lazy. Both these options have upsides and downsides. My suggestion, although not perfect, might remedy that I believe.
            Was this ever resolved?

            I'm in the process of migrating the server side of
            an existing application, and would like the Web UI aspect to remain the
            same. For reasons which are not important for this discusison, I need
            to maintain our DTO like communication mechanism.
            While the server undergoes a heart surgery and gets refitted with Hibernate the model
            also gets changed to benefit from the new capabilities. This presents a
            requirement to map the new model to the existing DTOs and I'm looking
            for some automated mechanism to achieve this, rather than needing to
            do this by hand.

            Any info would be appreciated

            Comment


            • #7
              Afraid not..

              AFAIK, this has never been resolved. I believe the Hibernate team focuses on the server and not on the network/client and therefor do not address this, though I might be wrong here.

              What we are exploring now is the ability to generate DTOs in runtime (via dynamic proxies) from hibernate-retrieved objects.

              This can be done by using interfaces (and not pojos) for our entities. When Hibernate retrieves the data, it generates objects that implement these interfaces. Then, when we want to return the objects to the client tier, we will (unfortunately again) generate another set of proxies which contain the data and do not rely on hibernate. Vice versa when they come in from the client.

              Not too clean but it might work ;-)

              Comment


              • #8
                Re: Afraid not..

                Originally posted by arikkfir
                AFAIK, this has never been resolved. I believe the Hibernate team focuses on the server and not on the network/client and therefor do not address this, though I might be wrong here.

                What we are exploring now is the ability to generate DTOs in runtime (via dynamic proxies) from hibernate-retrieved objects.

                This can be done by using interfaces (and not pojos) for our entities. When Hibernate retrieves the data, it generates objects that implement these interfaces. Then, when we want to return the objects to the client tier, we will (unfortunately again) generate another set of proxies which contain the data and do not rely on hibernate. Vice versa when they come in from the client.

                Not too clean but it might work ;-)
                Thanks for the info. I was afraid this would be the answer. Regarding your
                solution, another question (or 2), if I may:
                How are you modeling (or solving the problem of) relations?
                How do you prevent Hibernate from hitting the DB for related objects
                when you follow references?

                Comment


                • #9
                  Re: Afraid not..

                  Originally posted by bonnyr
                  Thanks for the info. I was afraid this would be the answer. Regarding your solution, another question (or 2), if I may:
                  How are you modeling (or solving the problem of) relations?
                  How do you prevent Hibernate from hitting the DB for related objects
                  when you follow references?
                  Regarding relations, well..we don't ;-) If a relation from a model is requested, and the data for that relation was not brought to the client, there are three alternatives:
                  • 1) Throw an exception - this will let the client either handle that and lazily fetch that data (or reference the user to another form)

                    2) Simply return null. This moves the responsibility to match the data brought/fetched to the client to match the needs of the form in question

                    3) Create sophisticated DTOs that "know" where to fetch the missing data from (e.g. annotate the getter methods of the model with the facade and method to call upon when lazy fetch is needed). In my experience this is very hard to do.
                  I prefer the first approach myself, but others might disagree...

                  Of course, this is done in a generated class, and not something the programmer writes, since the DTOs are generated.

                  Regarding the second question - well since the DTOs are not hibernate objects, we don't even bring the hibernate runtime to the client so that's not a danger. While in the server though, we don't mind hibernate to do that of course.

                  cheers,
                  Arik.

                  Comment


                  • #10
                    We have ran into this problem, we are using EJBs hence the objects being sent back to the web-tier are serialized.

                    Originally we returned DTOs (not sure if this is the correct terminology when contains other Objects and Sets) that were in essence the same as the domain Object in that they could contain the whole object graph including referenced objects and collections. We created them as seperate objects so that we could add extra methods useful to the UI but not required at the Hibernate level.

                    This was ok but in most cases we didnt want to fully load the object graph on first creation but we might want more than the bare minimum so the UIClass requesting the DTO had to specify what level they wanted the Object graph to be populated, then the developer had to ensure they did not try and access unitilized Objects and Collections of the DTO later.

                    This was a bit dangerous so now we create multiple instances of the DTO for use in different cirumstances such as one with simple ids and one containing fully loaded Classes. But this is a bit unwieldy and does not seem to sit so well with Hibernate/Spring.


                    What do you think ?
                    has anyone implemented a lazy load mechanism for DTOs so that they can retrieve the data from Hibernate as neccessary.

                    Comment


                    • #11
                      Use annotations?

                      Originally posted by Paul Taylor
                      What do you think ?
                      has anyone implemented a lazy load mechanism for DTOs so that they can retrieve the data from Hibernate as neccessary.
                      Actually - this would make a nice project to write. We could use annotations in the domain objects, and dynamically create DTOs (via cglib/dynamic proxies). These generated DTOs will automatically ask the server for additional data (when needed) and "know" the correct facade or service to call via the annotations.

                      something like:
                      Code:
                      public class PersonDomain {
                        ...
                        @dto(facade="personManagement";method="findAddresses")
                        public Addresses[] getAddresses() {
                          ...
                        }
                      }
                      Now from this domain object, we could somehow generate a DTO which already contains the simple fields, but for arrays/collections it will load them on-demand by turning to the correct server facade (using the annotations).

                      What do you think?

                      Comment


                      • #12
                        Hi I was really asking do you think we were right to start creating addtional DTOs fro the same Domain Object or whether we should have persisted with one DTO per Domain Object.

                        As for your project idea I dont have any knowledge of annotations. Personally Im not sure if we need the DTOs to be created automatically because we may never need some fields in the UI and we may want to manually add in additional methods.

                        But a way of getting these DTO's to lazy load the collection data would be a very useful addition to the Spring framework.

                        Comment


                        • #13
                          Seems right

                          Yes, I believe that is a good approach, though I'm no expert on the subject. Often one creates a customized EJB facade for each form on the UI, which provides the required services for that form. That EJB does not perform any logic, but rather turns to the appropriate EJB (a real service) which does the actual work.

                          This way, if the services-ejbs change, the UI does not change. This is the same approach, but for domain objects, and I do agree with it.

                          The down site, of course, is having to maintain a multitude of classes, which might not fit a very large systems - so I believe this should be decided on a per-system basis, rather than a rule-of-thumb.

                          just my 2 cents though.. ;-)

                          Comment

                          Working...
                          X