Announcement Announcement Module
Collapse
No announcement yet.
Architectural Considerations: Spring, Hibernate and the Domain Model Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Originally posted by andrew_m View Post
    Our approach is beginning to take shape:

    - DTO and Web layer. DTOs are serialized and can be a subset of the full Domain objects. There will be a Web layer responsible for talking to clients and dealing with HttpServletReqeust, Cookies, etc. The Web layer will interact with the Service and Domain and assemble DTOs.
    It is not very clear to me what for DTO are needed in this place - unless you plan to have non-http clients.

    - Domain Layer. Rich, non-anemic fully OO Domain which models the problem and implements business logic. We are going to map the Domain to the DB with JPA annotations, or just use XML. This is still under debate.
    Both annotations and XML may be mixed and matched, as well XML may be used to override behavour specified by annotations. So I really do not see any reasons to debate

    But either way, we won't have any generated orm objects and maybe no XML.
    There is nothing wrong with ORM-generated objects as soon as they are generated once and used as starting point for developing full-fledged objects only.

    For transactions, I think we will use @Transactional. So if we go this route our service and domain will be heavily annotated. I don't think I have an opinion on that yet.
    There were discussion "Are annotated POJOs still POJOs?" in this forum not long go, may be it would be interesting to you (name may slightly differ).

    Comment


    • #17
      I myself try to avoid DTOs as far as possible. In your specific case - which kind of control-related code do you plan to add to DTO? May you provide a sample?

      Regards,
      Oleksadr

      Originally posted by andrew_m View Post
      To DTO or not is a tough call. For us, the client does have requirements that are different enough, that I think it is worth the extra work. For example, in Flex you can bind controls like checkboxes to Java object attributes. So we are going to have code in the DTOs for specific thing like ui controls, and I don't think that belongs in the Domain.

      Comment


      • #18
        My Way

        I just had the same problem with one of my projects:

        1. Get the book Patterns of Enterprise App Dev. By Martin Fowler - it goes through most of this stuff pretty thoroughly.

        2. Don't let the web layer access the domain objects much. Since the web layer is basically dealing with converting get/post string parameters into lookup ids, it should basically just pass converted params to the service layer and receive fully initialized domain objects to pass off to the presentation layer. Do NOT let the presentation layer do more than just access getter methods of the objects along with some formatting (of dates, strings, numbers, etc).

        3. The service layer is where transactions are handled and also the business logic (basically calling on the initialized domain objects that are pulled out of the database).

        4. The domain objects (which are persisted using Hibernate should have rich behaviour - i.e. more than just getters and setters). Beware of having your service layer methods doing all the work that should actually be done by the domain objects.

        5. The service layer interacts with a DAO interface, not an implementation. Thus the service layer should never touch the hibernate api, including methods like flush, merge, etc. Imagine you decide that Hibernate is not working out alright, and you want to switch to the next greatest ORM api or even something completely different. If your service layer is using the Hibernate API anywhere, then you now have to change your service layer along with your DAO layer. BAD NEWS.

        6. The dao layer could be controlled by anything - Hibernate, Toplink, or even pure JDBC, stored procedures, etc. Therefore, the service layer should never know about things like lazy initialization. If an Item lazy initialized a bunch of bids, the Dao interface shoudl have a method like getItem(Long itemId) and also getItemAndBids(Long ItemId).

        If the dao were to use JDBC, it would then have to load the Item first, then load each one of the Bid objects and initialize the item's bids into the item. Using Hibernate, it would just be easier for the DAO object to get the item and its bids in one HQL query which is like one line of code versus the many JDBC would require. That is where the Hibernate advantage comes into play, and not in the service layer.

        Basically the service layer should not do more than initialize objects from the database, then call on these domain objects to perform business logic. It is up to the service layer to know what exactly needs to be initialized in the domain model before call domain object methods. If an item does some business logic, and it expects that its bids are to initialized and in memory, it is up to the service layer to initialize an item and its bids. That is as far as the service layer goes into the business logic.

        The domain logic should never know anything about how its associated objects are initialized. Remember - this is basically the whole point of the service layer.

        HTH - I'm only partially through the above referenced book, but I highly recommend it as Fowler has already gone through these problems and does a great job of going through the options in a very easy to understand manner!

        Bill

        Comment


        • #19
          Originally posted by stbill79 View Post
          I just had the same problem with one of my projects:

          1. Get the book Patterns of Enterprise App Dev. By Martin Fowler - it goes through most of this stuff pretty thoroughly.
          Really hate this book (as well as the most of Martin Fowler stuff). "What is true is not new, what is new is not true" But I should agree that to big extent it is matter of personal taste.

          2. Don't let the web layer access the domain objects much. Since the web layer is basically dealing with converting get/post string parameters into lookup ids ...
          This is only one if the possible approachs to Web-layer, depending on used tools/frameworks approaches may radically differ. It may be so (depending on used tools, that web-layer need not to know about get/post parameters (and even about very existence of get/post methods). One such example are ThinWire-based applications.

          5. The service layer interacts with a DAO interface, not an implementation. Thus the service layer should never touch the hibernate api, including methods like flush, merge, etc. Imagine you decide that Hibernate is not working out alright, and you want to switch to the next greatest ORM api or even something completely different. If your service layer is using the Hibernate API anywhere, then you now have to change your service layer along with your DAO layer. BAD NEWS.
          Such methods as flush() and merge() represent concepts with scope that far exceed Hibernate as such. By migration to ORM that need not them DAO implementation may provide empty implementation. And I hardly can imagine ORM that does not support these concepts at all.
          So providing such methods representing such concepts in DAO interface is not so bad.

          6. The dao layer could be controlled by anything - Hibernate, Toplink, or even pure JDBC, stored procedures, etc. Therefore, the service layer should never know about things like lazy initialization. If an Item lazy initialized a bunch of bids, the Dao interface shoudl have a method like getItem(Long itemId) and also getItemAndBids(Long ItemId).
          This way (especially if you have big and complex domain model) you may end up with very fat interface. And this interface would be very unstable against domain model evolution. Such approach is acceptable for small to medim-small application with limited time scope (significant model eveolution is unlikely). For bigger long-living application such approach may be fatal

          If the dao were to use JDBC, it would then have to load the Item first, then load each one of the Bid objects and initialize the item's bids into the item. Using Hibernate, it would just be easier for the DAO object to get the item and its bids in one HQL query which is like one line of code versus the many JDBC would require. That is where the Hibernate advantage comes into play, and not in the service layer.
          To force Hibernate (or other ORM) to work JDBC-style means delibirately loss the best of them. Sure when you ride a car you need start engine - you may to push car forward with pole throw window

          Basically the service layer should not do more than initialize objects from the database, then call on these domain objects to perform business logic. It is up to the service layer to know what exactly needs to be initialized in the domain model before call domain object methods. If an item does some business logic, and it expects that its bids are to initialized and in memory, it is up to the service layer to initialize an item and its bids. That is as far as the service layer goes into the business logic.
          As well serivice layer becomes unprotected against domain model evolution.
          Such approach may be unavoidable when JDBC (plain oir with stored procedures) is used, but compeltely defeats the very ORM purpose.
          I guess hard decision ORM (does not matter which) vs. JDBC have to be done. And only then service layer designed.

          And not forget that now most of the ORMs are available via unified JPA API.

          Regards,
          Oleksandr

          Comment


          • #20
            I must admit i don't really understand what speaks against making services transactional and use simple "required" (default) transaction propagation.

            Service methods are in most cases represent units of work or have to be used as a part of larger unit of work and that's exactly what you can achieve by making them transactional.

            Comment


            • #21
              I guess here is some misunderstanding - I do not see any post here that objects to making service transactional.

              Originally posted by dejanp View Post
              I must admit i don't really understand what speaks against making services transactional and use simple "required" (default) transaction propagation.

              Service methods are in most cases represent units of work or have to be used as a part of larger unit of work and that's exactly what you can achieve by making them transactional.

              Comment


              • #22
                I have started a new system as well. And have started down the road of exposing my Business Model objects which are hibernate persistance objects to my service layer. The problem I see is whe you have lazy initialization. It just does not seem right to me that the service layer has an object which has an attribute called say itemList which is a set of Item objects. However, since the itemList is lazily initialized it can not access it without opening a transaction/session. It seems that your data access layer now creeps into your service layer, and your service layer now has to know that something is lazily initialized or eagerly fetched. I am at a cross roads now as to best implementation.
                Sorry, forgot to quote.

                Comment

                Working...
                X