Saving Object Hierarchies


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 15 of 15

Thread: Saving Object Hierarchies

  1. #1
    Richard Dalton . Guest

    Saving Object Hierarchies




    Let's assume I have an object called CTransaction. I give it a LoadData
    method so it can fetch itself from the database and populate its own properties.

    I should really represent a Transaction with 2 objects,
    one which has all the Properties and Methods of a Transaction
    and another which just worries about loading and saving Transactions. I'll
    call the second one CTransactionDB.
    Nothing too original there.

    I should now be able to create a CTransaction object set it's
    properties and call 'Save'. CTransaction would create an instance of CTransactionDB
    and would pass all of it's properties to CTransactionDB in one go. It could
    then call the 'Save' method of CTransactionDB which would take care of the
    saving.

    From what I can gather most people seem to think that the interface of DB
    objects is pretty standard, you provide some way to Load, Save and Delete
    and not much else. You certainly don't
    mimick the properties of the Business object.

    But here's a problem. Let's assume that you now want to create
    a CBatch object which will contain a collection of CTransactions.
    I can add Transactions to the Batch in the Client app without
    ever hitting the database. Eventually I will want to
    save the Batch, and all it's associated transactions.

    Let's complicate things be saying that when the Batch is
    saved its ID is generated by an AutoIncrement field. So
    to get the ID of the batch we have to hit the database.
    But let's also assume that each Transaction has a Batch
    property.

    We can't set the Batch property for the Transactions until
    we have hit the database to save the Batch and thus generate
    it's ID.

    So our Options seem to be:

    1. Save the Batch first, without saving any Transactions.
    Have the Batch ID passed back from the Batch Save
    so that you can then set the Batch properties of the
    transactions in the Business layer. When they have been
    updated you can then save them.

    Problem: This involves an extra trip to the database.
    Ideally we'd like the entire Batch and Transactions to
    get saved in one trip. Apart from the performance issue,
    it just feels like it should happen in one place.

    2. The Second option is to send the Batch and All the
    transactions to be saved at the same time. When the
    Batch get's saved it could iterate through it's
    Transactions and set their Batch property.

    Problem: I said earlier that DB objects shouldn't have
    properties. Is this a special case? I hate special
    cases.

    I'd appreciate any thoughts. This problem can get very messy
    if you allow hierarcies of arbitrary depth. Is there any
    consensus on saving object hierarchies? The books seem
    to take very simple examples, as usual.


    -Richard





  2. #2
    Pierre G. Boutquin Guest

    Re: Saving Object Hierarchies

    Well, there are some alternatives. You can use temporary IDs until an object
    is saved.

    I often use negative sequence numbers for such purpose. The database objects
    are strictly positive, initialized objects are strictly negative, a
    constructed, empty object may have an ID of 0 if there is a need to
    distinguish between a contructed and initialized obect. The need for a
    distinction may be driven by UI requirements. If you hit new, make changes,
    then close, it is fairly obvious you'll want to ask the user whether to save
    the changes. But hitting new, then cancel may not warrant a message box.

    Hth

    <Pierre />



  3. #3
    Richard Dalton . Guest

    Re: Saving Object Hierarchies


    "Pierre G. Boutquin" <boutquin@home.com> wrote:

    >Well, there are some alternatives. You can use temporary IDs >until an object

    is saved.

    I'm not sure I understand this.

    If I am saving a Header object and a number of it's child
    objects, I need to set some property of the child object
    at the point where the Header object is saved, so that the child
    objects will have the appropriate link to the header object.

    But I don't know the ID of the Header object until I save it,
    so I end up setting properties of the child objects in
    the Database layer.

    You seem to be suggesting that in the client application
    I give the Header object a negative ID (say -1). And I then
    assign -1 to the appropriate property of the child objects.
    I can do this in the business layer no problem. But I still
    have the problem that when I save the batch, and it gets
    it's real ID, I need to somehow pass that ID to each child object
    so that when they save themselves to the DB they have the appropriate link.

    The approach I've taken incidently is to create a method
    in DB objects called 'SetSaveTimeProperties' which
    can accept any properties which might need to be set
    during a save. I'm not entirely happy with this
    but it beats having to create Property Lets for every
    property.

    -Richard





  4. #4
    Anthony Jones Guest

    Re: Saving Object Hierarchies

    Richard,

    Fundemental questions: Why is it wrong to have the Data Centric layer
    objects talk to each other? In this case why can't a CBatchDB object
    inform a bunch of CTransactionDB objects of it's ID?

    In this case a single network round trip is expected to save the batch and
    its transactions. So there must be some controlling object that acts as
    the entry point for this action possibly the CBatchDB object itself. I
    don't see any reason why these two classes shouldn't cooperate to get this
    done.

    Another solution (one that I use) is to not use Database generated IDs. In
    this case when a CBatch is created I assign it a unique ID on the spot. Of
    course this means overcoming the non-trival problem of ensuring all IDs are
    unque regardless of where they are generated .

    --
    Anthony Jones
    Nuesoft Ltd




  5. #5
    Thomas Eyde Guest

    Re: Saving Object Hierarchies

    From an OOP point of view, you don't need the IDs.
    A Batch will know every Transactions contained, and if it's necessary each
    Transaction will know the Batch they belong.
    The ID is needed only in the database to distinguish Batches, and to relate
    a Transaction to a Batch. If updating/deleting Batches or Transaction is
    needed, then at least they need to know their database ID. But that
    information could be private.

    So:
    - Why not let CBatch save everything by CBatch.SaveDb.
    - SaveDb calls CBatchDb.Save and passes the Batch and Transactions data.
    CBatchDb.Save returns the Batch database ID.
    - CBatch keep track of its database ID.
    - If a Transaction need to know the Batch ID, it askes for it from the
    Batch.

    A single Transaction may need to know its database ID, but the ones
    contained in a Batch need not. The Batch can create an ID unique for each
    Transaction within the Batch. When you need to update/delete a Transaction,
    let the Batch do it.
    For the single case Transaction, use a Batch with one Transaction.

    Is this useable?

    Best regards,
    Thomas


    <Richard Dalton .> wrote in message news:3a3adc14$1@news.devx.com...
    >
    > 2. The Second option is to send the Batch and All the
    > transactions to be saved at the same time. When the
    > Batch get's saved it could iterate through it's
    > Transactions and set their Batch property.
    >





  6. #6
    Richard Dalton . Guest

    Re: Saving Object Hierarchies


    "Thomas Eyde" <thomas.eyde@bdc.no> wrote:

    >- Why not let CBatch save everything by CBatch.SaveDb.
    >- SaveDb calls CBatchDb.Save and passes the Batch and
    > Transactions data.
    >- CBatchDb.Save returns the Batch database ID.
    >- CBatch keep track of its database ID.
    >- If a Transaction need to know the Batch ID, it askes for it
    > from the Batch.


    It's certainly novel. I had assumed that adding a Batch property to the
    Transaction was the obvious way to go.

    You're right of course that the Transactions only need to store their Batch
    in the DB, they don't need to have a batch property necessarily. As long
    as there is a Batch to take care of the loading and saving.

    One problem is that for a Transaction to find out it's ID
    it needs to ask it's parent, so you are getting into circular
    reference territory.

    I assume lots of people have hit this problem. Although
    I've talked to a few people who seem to be using Objects as
    if they were old style API DLLs. i.e. collections of Functions.

    It seems pretty common to have objects that have lots of similar
    functions that work almost like stored precedures. There's
    no concept of properties or Object Hierarchies.

    Is that fair to say, or will someone out there tell me that
    Object Oriented programming is alive and well in the n-Tier
    world.

    -Richard





    ><Richard Dalton .> wrote in message news:3a3adc14$1@news.devx.com...
    >>
    >> 2. The Second option is to send the Batch and All the
    >> transactions to be saved at the same time. When the
    >> Batch get's saved it could iterate through it's
    >> Transactions and set their Batch property.
    >>




  7. #7
    Brian G. Rice Guest

    Re: Saving Object Hierarchies

    I also have used the method of generating a unique ID in the application
    instead of at the database. In the MS world, we have the OS generate a GUID
    for us. Always unique, and we have never had a problem with it.

    --
    Brian G. Rice
    Entier Solutions Inc.

    "Anthony Jones" <yadayadayada@msn.com> wrote in message
    news:3a3d1635@news.devx.com...
    > Richard,
    >
    > Fundemental questions: Why is it wrong to have the Data Centric layer
    > objects talk to each other? In this case why can't a CBatchDB object
    > inform a bunch of CTransactionDB objects of it's ID?
    >
    > In this case a single network round trip is expected to save the batch and
    > its transactions. So there must be some controlling object that acts as
    > the entry point for this action possibly the CBatchDB object itself. I
    > don't see any reason why these two classes shouldn't cooperate to get this
    > done.
    >
    > Another solution (one that I use) is to not use Database generated IDs.

    In
    > this case when a CBatch is created I assign it a unique ID on the spot.

    Of
    > course this means overcoming the non-trival problem of ensuring all IDs

    are
    > unque regardless of where they are generated .
    >
    > --
    > Anthony Jones
    > Nuesoft Ltd
    >
    >
    >




  8. #8
    Richard Dalton . Guest

    Re: Saving Object Hierarchies


    "Anthony Jones" <yadayadayada@msn.com> wrote:
    >Fundemental questions: Why is it wrong to have the Data Centric >layer objects

    talk to each other? In this case why can't a >CBatchDB object inform a bunch
    of CTransactionDB objects of >it's ID?

    I have no problem with that, In fact what I do is make the
    Batch Object call a method on the Transaction object
    to set any properties that can only be set in the DB layer.
    In this case only one, but there could be more in some cases.

    I absolutely think objects in the DB Layer should talk to
    each other. My problem is the question of properties.
    We don't know how future objects might like to communicate
    with the Transaction object in the DB layer. If our method
    of communication is through properties, then we might as well
    expose the same properties in the DB layer as the Business layer,
    since some future DB object might like to talk to the
    Transactions Amount property for instance.

    I seems like this would be a really bad route. The example
    I gave was a typical example, but it's the wider issue of
    what DB objects should expose that interests me.

    Having too much code to manage the relationships between objects
    in the DB layer also seems to be stealing or at least mimicking some of the
    so called business rules that should supposedly be one layer up.

    Perhaps I'm being too picky.
    I think I'll stick with having a method in the DB objects
    that lets me set any values that need to be set. I'll
    continue to avoid exposing business type properties in the
    DB Layer.








  9. #9
    Anthony Jones Guest

    Re: Saving Object Hierarchies

    Brian,

    Do you then use those GUIDs as foreign keys in referencing tables?
    If so, does it not bloat the record size excessively compared to an int?

    I considered using GUIDs but I have several tables which carry little real
    data, just a set of foreign keys.

    --
    Anthony Jones
    Nuesoft Ltd




  10. #10
    Anthony Jones Guest

    Re: Saving Object Hierarchies

    >>
    One problem is that for a Transaction to find out it's ID
    it needs to ask it's parent, so you are getting into circular
    reference territory.
    <<

    Circular references are fine.

    It's better to simply accept circular references and put in place stratergy
    to manage them. The alternative is to fight tooth and nail trying to
    avoid them in all sorts of unique situations.


    --
    Anthony Jones
    Nuesoft Ltd




  11. #11
    Brian G. Rice Guest

    Re: Saving Object Hierarchies

    It does bloat it a little bit, but not enough to matter (IMHO). I am
    dealing with enterprises where our Databases are often >20 Gigs, if not
    more. A couple of extra bytes for a GUID Key is not relevant. I felt that
    the guarantee of uniqueness was worth it.

    Cheers,

    --
    Brian G. Rice
    Entier Solutions Inc.
    "Professional Architecture + Formalized Process = Repeatable Success"
    www.entier.org

    "Anthony Jones" <yadayadayada@msn.com> wrote in message
    news:3a3fdaed@news.devx.com...
    > Brian,
    >
    > Do you then use those GUIDs as foreign keys in referencing tables?
    > If so, does it not bloat the record size excessively compared to an int?
    >
    > I considered using GUIDs but I have several tables which carry little real
    > data, just a set of foreign keys.
    >
    > --
    > Anthony Jones
    > Nuesoft Ltd
    >
    >
    >




  12. #12
    Pierre G. Boutquin Guest

    Re: Saving Object Hierarchies

    "Brian G. Rice" <bgrice@entier.org> wrote in message
    news:3a409228$1@news.devx.com...
    > A couple of extra bytes for a GUID Key is not relevant.


    The benefit is that you can avoid a network trip. You can e.g. offload the
    GUID generation to the client. A sequence requires a network trip and can
    cause hotspots.

    <Pierre />



  13. #13
    Richard Dalton . Guest

    Re: Saving Object Hierarchies



    "Anthony Jones" <yadayadayada@msn.com> wrote:
    >I considered using GUIDs but I have several tables which carry >little real

    data, just a set of foreign keys.


    I'm the same. Using GUIDs feels strange, but what the guy's
    are saying does make some sense. I don't know it would
    work in all cases. For one thing it's nice to go in and
    create a query now and then, and know that you are looking
    for all transactions with a batch id of 13.
    I know you could copy and paste the GUID, but I still think
    it'd me messy. Maybe I'm wrong.

    I suppose there are other ways of generating a key.
    You could use the date and time, in the following format.

    yyyymmddhhnnss or yyyymmdd.hhnnss

    I use the latter at the moment for Time stamping. I hadn't
    considered using it as a Key. Of course there's the problem
    of creating multiple objects at the same time. Particularly
    accross machines.

    Actually forget it, if you are generating the key on the client,
    the GUID is the only way.

    -Richard








  14. #14
    Matthew Cromer Guest

    Re: Saving Object Hierarchies


    "Anthony Jones" <yadayadayada@msn.com> wrote:
    >Brian,
    >
    >Do you then use those GUIDs as foreign keys in referencing tables?
    >If so, does it not bloat the record size excessively compared to an int?
    >
    >I considered using GUIDs but I have several tables which carry little real
    >data, just a set of foreign keys.
    >

    We use a Number(15) for our primary keys and foreign keys. Number(9) which
    won't overflow a long could become exhausted in a very long-duration system
    with a lot of transactions.

    In VB our Number(15) is handled in a Variant (Decimal) datatype -- our Java
    code uses variously BigDecimal (handled via JDBC) and occasionally BigInteger
    (unfortunately not handled via JDBC).

    We use an Oracle sequence to generate all these keys.

    Matthew Cromer

  15. #15
    Matthew Cromer Guest

    Re: Saving Object Hierarchies


    "Richard Dalton" . wrote:
    >
    >
    >"Anthony Jones" <yadayadayada@msn.com> wrote:
    >>I considered using GUIDs but I have several tables which carry >little

    real
    >data, just a set of foreign keys.
    >
    >
    >I'm the same. Using GUIDs feels strange, but what the guy's
    >are saying does make some sense. I don't know it would
    >work in all cases. For one thing it's nice to go in and
    >create a query now and then, and know that you are looking
    >for all transactions with a batch id of 13.
    >I know you could copy and paste the GUID, but I still think
    >it'd me messy. Maybe I'm wrong.
    >
    >I suppose there are other ways of generating a key.
    >You could use the date and time, in the following format.
    >
    >yyyymmddhhnnss or yyyymmdd.hhnnss
    >
    >I use the latter at the moment for Time stamping. I hadn't
    >considered using it as a Key. Of course there's the problem
    >of creating multiple objects at the same time. Particularly
    >accross machines.
    >
    >Actually forget it, if you are generating the key on the client,
    >the GUID is the only way.



    We use a Sequence, but the client doesn't have to put it when writing a row.
    All of our tables have a trigger to fill in the ID if it is blank on an
    insert.

    Both ways seem good to me, I just prefer the aesthetics of an incrementing
    sequence over a GUID.

    The real win for us is we are 100% consistent with our databases. All relationships
    are via this synthetic key (ID), every table has ID as its primary key.
    It lets us write some relatively simple and straightforward generic code
    to create rich clients.

    Matthew Cromer

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center