Announcement Announcement Module
Collapse
No announcement yet.
Book: "Domain driven design" implemented in Spring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #31
    This is indeed the worst possible thing you can do ... but it happens and people who are just starteing to use hibernate sometimes forget that when they are manipulating their object that is being used in the views they are actually making it 'hibernate dirty'. So you need to be aware that when having a team of juniors these can happen.

    The second problem I have with dealing with lazyinitexception in the view is that the view is suddenly hibernate aware, whereas it should have been transparant which persistence strategy is being used. Not only are you showing your persistence strategy you are probably not returning a clean api, for example when developing a product, the product api has a method .getAccountBalance(). This method looks clean, but what if when using this method and iterating over some objects returned in the acount balance you are suddenly faced with that horrible lazyinitexception??? So in those cases I think it is wise to consider DTO's.

    I think DTO's are NOT domain code duplications, rather views on domain objects that can alse span multiple domain objects returing 1 single simple dto object. I don't see anything wrong with that.

    The use for DTO's should be restricted 'I think' to the service layer, the layer before the view / controller layer. Because this layer mostly represents application use case functionality, a facade for multiple managers. So what these service layers are returning are most of the time client views or a domaon subset for webservices communication, ... . So returning a DTO object that represents the 'needed' data from muliple domain objects can be a good case.

    I always advocate kiss and yagni ... but DTO's ... I guess they have their use

    Comment


    • #32
      You could always initialize exactly what you need in your service layer, to avoid LazyInitExceptions. Then, simply close the session. That way, your Hibernate objects are all set to go AND any changes made won't get flushed to session.

      Comment


      • #33
        For the sake of clarity I wasn't advocating the use of DTO's, at least not unless one is using remote calls to retrieve data. If that's the case a DTO encapsulating one or more domainObjects could be preferred instead of several expensive network calls. Furthermore the DTO's would need to be serializable whereas that may not always be the case with domain objects.

        My question was more centered around the coupling of (hibernate) database objects and the web layer. As (I think) stated earlier I'd prefer to cut the database session earlier and let domain objects go through the layers to be used in the view layer. A downside could be the size of the domain object itself but that could be resolved. Since Objects should have state and behaviour this should work. Is it bad practise to allow the method signatures of the service layer to contain domain objects? I don't think so.

        Another reason why i advocate this is that I am continually having to integrate with other services through remote calls and then I have to map that data into my domain objects, which then have nothing to do with the database (hibernate) objects. I can therefore have a consistent approach throughout by filling the domain Objects with the appropriate data whichever datasource happens to be getting utilised.

        Thoughts?

        Colin

        Comment


        • #34
          Originally posted by colinchalmers
          As (I think) stated earlier I'd prefer to cut the database session earlier and let domain objects go through the layers to be used in the view layer.
          Sounds great, at first. But once your domain model hits any level of complexity you will find yourself descending into the Hell known as OpenSessionInView.

          Also, I like to put a lot of global display logic in my web-tier DTOs. This keeps it out of my domain objects (where it most certainly doesn't belong), and it keeps me from having to cut-and-paste the logic into every page where the corresponding domain object will be rendered.

          Comment


          • #35
            Originally posted by sethladd
            You could always initialize exactly what you need in your service layer, to avoid LazyInitExceptions. Then, simply close the session. That way, your Hibernate objects are all set to go AND any changes made won't get flushed to session.
            And how should the servicelayer know what the UI needs? I have tried this once with a project in .NET (using an OR-mapper). It was terrible, the servicelayer was totally aware of what the UI needed and it made the servicelayer less reusable.

            Personally I don`t have much problems with the idea behind the opensessioninview only the semantics of hibernate sessions and transactions can be quite complicated and very unnatural.

            Comment


            • #36
              Originally posted by Alarmnummer
              And how should the servicelayer know what the UI needs? I have tried this once with a project in .NET (using an OR-mapper). It was terrible, the servicelayer was totally aware of what the UI needed and it made the servicelayer less reusable.
              Maybe you should introduce a business facade layer which contains implementations of use cases and use the service layer for reusable functionality

              Comment


              • #37
                Originally posted by JimmyK
                Maybe you should introduce a business facade layer which contains implementations of use cases and use the service layer for reusable functionality
                I meant that prefetching data (that is needed in the UI) in the servicelayer, isn`t terrible good for the design of the service layer. The service should layer should not depend on the UI and in my situation it was (and well.. that sucks).

                Comment


                • #38
                  What I would like to see are view objects that hold NO business logic, I really don't like the idea that someone can call a business method function on my screen. It reminds me of projects that were making use of jsp tags with soooo muchhhhh business logic in them ... J2EE specs you gotta love them ... first EJB's then uncontrollable jsp tags

                  Well ... need to focus back on the problem before getting angry about J2EE ... view object are perhaps not really OO ... but who cares ... OO is great for domain modelling but I hate to see it in my view layer (except the anemic model ... but that isn't really OO is it).

                  So we have 2 choices:
                  1. make your services that way that you return DTO or view objects or whatever. Problem with that is that you will be returning very specific objects. The problem starts when your second project needs to call that service and there goes the adjustments of the view object... If your service layer needs to return data from multiple DO's, it's easy to put them into view object, otherwise (see option 2) you need somekind of holder object.

                  2. The service layer can return the Domain objects. This has the following problems:
                  - Too much data, does your controller need to have a object with hibernate version, last modification user and date on it?
                  - What if your service actually needs to return multiple Domain objects, let's create a holder for returning multiple domain objects ... what a mess ... you can dump that holder object on your view and the view developer needs to find the correct property on its own (you can have 10 domain objects and only need 1 property / DO ... brrrr ... ). Or you create a view object that is being filled in the controller based upon the DO's in the holder object

                  With both options you need to keep in mind that the service layer data should be able to be used when implementing webservices or (think client) rmi requests.

                  Both options could be used, but none of them really are THE solution
                  Thinking about this SOOO silly problems makes me nuts
                  Strange that still .. after soo many web frameworks ... these kind of problems still exist.

                  Perhaps people would quicker think about these things if they stop making hello world examples to show how powerfull the framework is

                  Grtz!

                  Comment


                  • #39
                    The service should layer should not depend on the UI and in my situation it was (and well.. that sucks).
                    Couldn't agree more ... but ... you still need to keep in mind HOW the service will be used ... so I think things are never fully independent

                    Comment


                    • #40
                      view modes

                      Originally posted by rebornspirit
                      1. make your services that way that you return DTO or view objects or whatever. Problem with that is that you will be returning very specific objects. The problem starts when your second project needs to call that service and there goes the adjustments of the view object...
                      Perhaps you could solve this by introducing view modes which would determine which specific DTO class should be used.

                      Code:
                      class DTOFactory {
                           DTO createDTO(ModelObject modelObject, ViewMode viewMode) {
                                DTO dto = createDTO(viewMode.getDTOClass(modelObject));
                                dto.populateDTO(modelObject);
                           }
                      }
                      A given service would be invoked in the context of a viewMode and would use the factory (or factories) to create any DTO necesary.

                      This way if a different project needs a different view, a new DTO can be created and a new viewMode which would map that modelObject to that new DTO class and the specific population logic would be inside the new DTO so the previous (already working) code doesn't need to be touched. Of course, all this DTOs implementations implements a basic DTO interface, the downside of this is that each client of the service should cast the returned DTO to a specific implementation.

                      Also, if you had a DTO that is created from several model object there should be no problem since you could have an interface whose populateDTO method takes the necesary modelObjects.

                      Comment


                      • #41
                        Sounds like a workable solution!

                        I would not add the ViewMode to the method signature of the service method, rather create specific beans where the correct ViewMode is set using the Spring context files.

                        That we wa can indeed have the advantage of a DTO and have non project specific DTO's as a bonus, I can go with that!

                        I think that the overhead of doing the cast is far from a problem, we are used of casting the Spring mvc command object so one more or less

                        Comment


                        • #42
                          So actually this is just the Assembler pattern by Martin Fowler.
                          So for example we will have an interface that looks something like this:

                          Code:
                          public interface MyService {
                              ViewObject getSomething(Integer id);
                          }
                          We will have a ViewObject assembler interface like:

                          Code:
                          public interface ViewObjectAssembler {
                              ViewObject assemble(Object o);
                          }
                          Code:
                          public interface ViewObject {
                          }
                          Code:
                          public class MyCustomViewObject implements ViewObject {
                          }
                          The MyService interface implementation looks something like

                          Code:
                          public class MyServiceImpl implements MyService {
                           
                              private ViewObjectAssembler assembler;
                          
                              public ViewObject getSomething(Integer id) {
                                  MyDomainObject do = ... retrieve the domain object;
                                  return assembler.assemble(do);
                              }
                          }
                          and a custom assembler being set by Spring:

                          Code:
                          public class MyCustomAssembler implements ViewObjectAssembler  {
                          // handle the conversion 
                          }
                          and this class van for example be called by the controller like this:

                          Code:
                          MyCustomViewObject x = (MyCustomViewObject) myService.getSomething(new Integer(5));
                          The ViewObjectAssembler can then be set in the application context of Spring on a project based approach.

                          Comments are more then welcome

                          Comment


                          • #43
                            I also have a problem with the name DTO. These DTO's are actually always view on domain models, so why not just call them ViewObjects? Then we'll have DomainObjects and ViewObjects.

                            Comment


                            • #44
                              Originally posted by rebornspirit
                              - The domain model should hold as much as possible domain logic as possible. But sometimes to perform this domain logic, the model needs another dao or service and this is for the moment not simple to implement in Spring. I know they are working on it but it is still in the sandbox and I'm going to wait for it until it is in the releases.
                              Could somebody point me in the right direction to find this in the sandbox please.

                              This is a great thread BTW.

                              Martin

                              Comment


                              • #45
                                Checkout DependencyInjectionInterceptorFactoryBean ... nice short name isn't it

                                Comment

                                Working...
                                X