Loading ...
Sorry, an error occurred while loading the content.
 

Re: Partially populated entities --> references

Expand Messages
  • Eben Roux
    Hey Lorenzo, Thanks for the response. We are not using an ORM. All hand-coded. I have actually mentioned this whole object-graph thing. It may be OK to
    Message 1 of 11 , Jul 31, 2008
      Hey Lorenzo,

      Thanks for the response.

      We are not using an ORM. All hand-coded.

      I have actually mentioned this whole object-graph thing. It may be OK
      to hydrate and retrieve the AircraftType object but it is unnecessary.
      I do not require it.

      As far as lazy-loading goes: it is the work of the devil!

      I only want to load what I need. For each use case it is well defined
      and we can work within those givens.

      I have had so many headaches about this. Any other opinions?

      Regards,
      Eben
    • berthooyman
      Hi Eben, I share your opinion on lazy loading. In a use-case driven design you can tell upfront what attributes you re interested in and lazy loading is not
      Message 2 of 11 , Jul 31, 2008
        Hi Eben,

        I share your opinion on lazy loading. In a use-case driven design you
        can tell upfront what attributes you're interested in and lazy loading
        is not adding any value but only slowing you down.

        My approach is to make my interest specific in any repository method. So
        when I do a get() or a find(), I will pass a description of the
        attributes I want to see populated. I call this "projection" which is
        how this is used in relational databases, where a projection is a subset
        of columns over some join. I have refined this with dynamic and static
        projections. The dynamic ones are passed in at run time and they require
        full interpretation and validation. The static ones are pre-configured
        and named, for those you only need to pass a name and the repository
        will have ways to retrieve the actual projection details. Using code
        generation techniques, I do the validation of named projections during
        code generation, so these are slightly more efficient at runtime.

        During early design and development phases, dynamic projections are very
        useful as they can grow with the user interface. Once you are near
        completion, you turn a dynamic projection into a named projection and
        you get the early validation and improved efficiency. Either way, my
        repositories know how to interpret projections.


        --- In domaindrivendesign@yahoogroups.com, "Eben Roux" <eben@...> wrote:
        >
        > Hey Lorenzo,
        >
        > Thanks for the response.
        >
        > We are not using an ORM. All hand-coded.
        >
        > I have actually mentioned this whole object-graph thing. It may be OK
        > to hydrate and retrieve the AircraftType object but it is unnecessary.
        > I do not require it.
        >
        > As far as lazy-loading goes: it is the work of the devil!
        >
        > I only want to load what I need. For each use case it is well defined
        > and we can work within those givens.
        >
        > I have had so many headaches about this. Any other opinions?
        >
        > Regards,
        > Eben
        >
      • Eben Roux
        Hoi Bert, Right, I have come to the conclusion that my brain is too small to remeber everything. I have forgotten about projections. But now, are you saying
        Message 3 of 11 , Jul 31, 2008
          Hoi Bert,

          Right, I have come to the conclusion that my brain is too small to
          remeber everything. I have forgotten about projections. But now, are
          you saying that the projection represents the data returned in some
          generic format in order to simply display it, or does it act as a
          specification for saying which parts of the entity you want hydrated --
          > including the references?

          But I still have this concern about the reference's description. It
          doesn't really belong on the entity.

          In my case an Aircraft is of an AircraftType. I am interested in only
          the AircraftType description for displaying a list of aircraft. But
          placing the AircraftTypeDescription on the Aircraft entity just feels
          plain wrong, but I cannot think of another way -- except maybe
          populating the AircraftType reference with the description and id
          populated (and nothing else). I just do not know... maybe have
          a 'special case' reference that basically represents display data -- so
          only the id and the description -- throwing exceptions when trying to
          access nay other data.

          What say ye?

          Eben
        • Rickard Öberg
          ... Here is what I have done in the past, and which seems to work quite well. Fundamentally I use an object-mapping framework, so no id s are seen in code,
          Message 4 of 11 , Jul 31, 2008
            Eben Roux wrote:
            > What say ye?

            Here is what I have done in the past, and which seems to work quite well.

            Fundamentally I use an object-mapping framework, so no "id"'s are seen
            in code, other than at instantiation. Typically code pass around object
            references, and can traverse their properties and collections when
            necessary.

            All state loading is done lazily, preferably per-property. I.e. when a
            reference is used then only the property which is actually accessed is
            loaded on a framework level (the persistence mechanism may then optimize
            bulk loading if it wants to). At this point you have a system that "just
            works" (i.e. you can use the model in code and don't have to worry about
            anything to use it). The main problem after that is dealing with the
            effects of lazy-loading, i.e. getting state to be loaded on a
            per-usecase basis.

            In the system I did I could create UnitOfWork's which had a
            LoadingPolicy associated with it. The LP contains what
            properties/associations to load, and the graph depth. This allows pretty
            good projection selection.

            After this it is mainly a matter of writing code and getting features
            done, and whenever some piece of code is deemed too slow due to
            lazyloading, add LP's which eagerload precisely what is necessary.

            In the last framework I wrote I also allowed the UnitOfWork to
            introspect what state was being loaded lazily, and bundle that into a LP
            that could be used the next time the UoW was done. I.e.
            self-optimization in a sense.

            All of these features I am now reimplementing in the OpenSource DDD-ish
            framework Qi4j. I know there are others who are considering porting it
            to .Net too for those who are so inclined.

            IMHO and FWIW and so on.

            /Rickard
          • berthooyman
            ... -- ... The latter - and I use it in hydration and in de-hydration alike. So my save() also includes a projection which helps the repository to track
            Message 5 of 11 , Jul 31, 2008


              --- In domaindrivendesign@yahoogroups.com, "Eben Roux" <eben@...> wrote:
              >
              > Hoi Bert,
              >
              > Right, I have come to the conclusion that my brain is too small to
              > remeber everything. I have forgotten about projections. But now, are
              > you saying that the projection represents the data returned in some
              > generic format in order to simply display it, or does it act as a
              > specification for saying which parts of the entity you want hydrated --
              > > including the references?

              The latter - and I use it in hydration and in de-hydration alike. So my save() also includes a projection which helps the repository to track version history on objects etc. As my projections have no limit to how deep they can go in referencing other objects, one save() can persist all changes on a full object tree. That was one of my initial design goals for my repository (since then I have changed my mind on what I'm actually doing and calling it a DAO no longer a repository).
              >
              > But I still have this concern about the reference's description. It
              > doesn't really belong on the entity.

              To me it is a simple matter of composition, your Aircraft has an embedded AircraftType object, and probably a collection AircraftEngine objects and then some...

              Alternatively, both the type code and it' description could be simple attributes on your object, somthing known in the relational database world as denormalization. You can do that too, but your persistence logic will get cluttered by this - I can tell. For aircraft type it's potentially feasible, as for many other siple key/value references, but for engines and other real stuff the composition pattern is much more useful.
              >
              > In my case an Aircraft is of an AircraftType. I am interested in only
              > the AircraftType description for displaying a list of aircraft. But
              > placing the AircraftTypeDescription on the Aircraft entity just feels
              > plain wrong, but I cannot think of another way -- except maybe
              > populating the AircraftType reference with the description and id
              > populated (and nothing else). I just do not know... maybe have
              > a 'special case' reference that basically represents display data -- so
              > only the id and the description -- throwing exceptions when trying to
              > access nay other data.
              >
              > What say ye?

              My projections are originally specified as dotted names, for example type.description would refer to the type property of aircraft, type being an object, and description being a property of the type object. Likewise, you would have "registration" which is a property on the aircraft itself, or "engines.fueltype.price" for the price of the fuel for each of the engines (yes, on a four-engine aircraft all members of your engine collection would have the fueltype object populated with a price, and it would be the same price, quite likely). For a list style display of aircraft, your projection would be using something like "registration, seatCount, type.description".

              Mind you, there are other use cases where you will need to manipulate the type. One that comes to mind is your "New Aircraft" use case. There, you will want to select the type from a list of possible types. My aircraft repository would have a method domain("type.description") that queries the database and comes back with a collection of all AircraftType objects, populated with an ID and a description, only. This you then use for your <select> element on your form. The other one is range("type.description"). This one delivers same sort of collection, but only the types that are referenced by existing aircraft. You use this to poulate a <select> in a form-based search, or to generate some navigation element that let users navigate by aircraft type. There is no use in navigating to a type that has no aircraft, so you use range() rather than domain().

              In conclusion, these projections take away an enormous amount of headache for me, and my repository methods are extremely simple and limited in number (as a matter of fact I don't even have a find(), I only have a getter that accepts both a projection and a query object)
              >
              > Eben
              >

            • Eben Roux
              I think I should become a hobo. So it seems the static nature of our entities is the problem --- trying to have them represent n number of dynamic
              Message 6 of 11 , Jul 31, 2008
                I think I should become a hobo.

                So it seems the static nature of our entities is the problem --- trying
                to have them represent 'n' number of dynamic permutations --- my
                epiphany for the day.

                That is why it is necessary to 'describe' the intended results using a
                projection. This leaves our OO class structure to represent the most
                extensive domain and then we push and prod only the required bits into
                it and see how far we get.

                It actually does feel like herding cats.

                Somewhere deep in this mess is a serious violation of the SRP.

                Thanks for all the input chaps.
                Eben
              • Sebastian Jancke
                Udi Dahan and Oren Eini had the concept of fetching strategies (although with ORMs). It might also work well for you. Search Udi s site for
                Message 7 of 11 , Jul 31, 2008
                  Udi Dahan and Oren Eini had the concept of fetching strategies (although
                  with ORMs). It might also work well for you. Search Udi's site for
                  'IFetchingStrategy'.

                  -Sebastian

                  Eben Roux schrieb:
                  >
                  >
                  > Hey Lorenzo,
                  >
                  > Thanks for the response.
                  >
                  > We are not using an ORM. All hand-coded.
                  >
                  > I have actually mentioned this whole object-graph thing. It may be OK
                  > to hydrate and retrieve the AircraftType object but it is unnecessary.
                  > I do not require it.
                  >
                  > As far as lazy-loading goes: it is the work of the devil!
                  >
                  > I only want to load what I need. For each use case it is well defined
                  > and we can work within those givens.
                  >
                  > I have had so many headaches about this. Any other opinions?
                  >
                  > Regards,
                  > Eben
                  >
                  >
                • moffdub
                  Hi, I think you should model the aircraft type as either an entity or a value object...and which one will depend on your domain (see the post Repositories for
                  Message 8 of 11 , Jul 31, 2008
                    Hi,

                    I think you should model the aircraft type as either an entity or a
                    value object...and which one will depend on your domain (see the post
                    "Repositories for lookups"). Then, the aircraft object maintains an
                    association with this aircraft type object.

                    Now, you have two responsibilities: presentation (display) and domain
                    (retrieval/edit).

                    A classic repository will take care of the first one. As for
                    presentation, you (should) have a separate mechanism for delivering
                    data to and from your UI -- XML, a csv file, DTO, Presentation Model
                    (Fowler), whatever -- and you can simply use this mechanism (or create
                    one) for presentation purposes.

                    Scaling this up to business-type reports that have their own business
                    logic, then you will need to augment the domain layer with some
                    services, and possibly either report objects (like Evans' Itinerary
                    object in the book) or an anti-corruption layer for your reporting engine.

                    --- In domaindrivendesign@yahoogroups.com, "Eben Roux" <eben@...> wrote:
                    >
                    > Hello everyone,
                    >
                    > OK, so I have an aircraft that has a reference to an aircraft type.
                    > When I retrieve a specific aircraft to edit, say, then I have no need
                    > for the aircraft type reference, I only want the foreign key (id).
                    >
                    > When I insert a new entity also --- I care for the foreign key.
                    >
                    > Now I display a list and I want the type displayed. Here I no longer
                    > care for the foreign key but the description of the type.
                    >
                    > So will I then have a TypeID and a TypeName on my aircraft entity? And
                    > only use the relevant proeprties where applicable? Seems strangfe but
                    > it does make sense, unless I have my repository bring back display-only
                    > objects or hash tables or the like.
                    >
                    > Any ideas?
                    >
                    > Eben
                    >
                  • moffdub
                    sorry, that should read a classic repository will take care of the *second* one . And if loading either the foreign key or the description is costly and
                    Message 9 of 11 , Jul 31, 2008
                      sorry, that should read "a classic repository will take care of the
                      *second* one". And if loading either the foreign key or the
                      description is costly and undesirable in either case where one is not
                      needed, then see the "scaling up" paragraph I wrote.

                      --- In domaindrivendesign@yahoogroups.com, "moffdub" <moffdub@...> wrote:
                      >
                      > Hi,
                      >
                      > I think you should model the aircraft type as either an entity or a
                      > value object...and which one will depend on your domain (see the post
                      > "Repositories for lookups"). Then, the aircraft object maintains an
                      > association with this aircraft type object.
                      >
                      > Now, you have two responsibilities: presentation (display) and domain
                      > (retrieval/edit).
                      >
                      > A classic repository will take care of the first one. As for
                      > presentation, you (should) have a separate mechanism for delivering
                      > data to and from your UI -- XML, a csv file, DTO, Presentation Model
                      > (Fowler), whatever -- and you can simply use this mechanism (or create
                      > one) for presentation purposes.
                      >
                      > Scaling this up to business-type reports that have their own business
                      > logic, then you will need to augment the domain layer with some
                      > services, and possibly either report objects (like Evans' Itinerary
                      > object in the book) or an anti-corruption layer for your reporting
                      engine.
                      >
                      > --- In domaindrivendesign@yahoogroups.com, "Eben Roux" <eben@> wrote:
                      > >
                      > > Hello everyone,
                      > >
                      > > OK, so I have an aircraft that has a reference to an aircraft type.
                      > > When I retrieve a specific aircraft to edit, say, then I have no need
                      > > for the aircraft type reference, I only want the foreign key (id).
                      > >
                      > > When I insert a new entity also --- I care for the foreign key.
                      > >
                      > > Now I display a list and I want the type displayed. Here I no longer
                      > > care for the foreign key but the description of the type.
                      > >
                      > > So will I then have a TypeID and a TypeName on my aircraft entity?
                      And
                      > > only use the relevant proeprties where applicable? Seems strangfe
                      but
                      > > it does make sense, unless I have my repository bring back
                      display-only
                      > > objects or hash tables or the like.
                      > >
                      > > Any ideas?
                      > >
                      > > Eben
                      > >
                      >
                    Your message has been successfully submitted and would be delivered to recipients shortly.