RE: Working with Transient Objects

From: Gentry, Michael (michael_gentr..anniemae.com)
Date: Wed Jun 30 2004 - 13:17:27 EDT

  • Next message: Elia Morling: "Re: Working with Transient Objects"

    OK, how about option 4 ... :-)

    Add an isRandom column to your Car and delete those every time your game
    starts (when you create a new ParkingLot). Sure, they'll persist, but
    you really don't care if you can easily get rid of them (or just replace
    their values with new random car values?). Or, I suppose you could
    easily delete them prior to saving your parking lot. Something along
    that line.

    /dev/mrg

    -----Original Message-----
    From: Elia Morling [mailto:eli..amiljen.se]
    Sent: Wednesday, June 30, 2004 1:05 PM
    To: cayenne-use..bjectstyle.org
    Subject: Re: Working with Transient Objects

    I've tried Option 1 and it will give me errors as I can't do a
    Car.getParkingLot() which is the case all over my code. ;)

    Option 3 doesn't change that much as all newly created objects
    are TRANSIENT per default. First registering and then unregistering
    is the same as not adding it to the DataContext in the first place.

    This leaves me to try option 2. I guess as long as the DataObject
    is in the DataContext it will try to change its PersistenceState each
    time I change the value of a field. So I will have to override each
    set method in the DataObject and set its PersistenceState to TRANSIENT
    after the field has been changed.

    I will not be able to try this for abit, so if anyone has anything
    valuable
    to add that would be fine.

    Elia

    ----- Original Message -----
    From: "Gentry, Michael" <michael_gentr..anniemae.com>
    To: "Elia Morling" <eli..amiljen.se>; <cayenne-user@objectstyle.org>
    Sent: Wednesday, June 30, 2004 6:50 PM
    Subject: RE: Working with Transient Objects

    Option 3?

    There is also a dataContext.unregisterObjects() call which supposedly
    sets the collection of objects you pass in (your random cars) to a
    TRANSIENT state, which might be better than setting them directly on the
    object (in case the data context does some other stuff behind the
    scenes).

    /dev/mrg

    -----Original Message-----
    From: Gentry, Michael
    Sent: Wednesday, June 30, 2004 12:46 PM
    To: Elia Morling; cayenne-use..bjectstyle.org
    Subject: RE: Working with Transient Objects

    OK, two suggestions to try (since you obviously have a better test
    environment for this than me).

    1) Use transient variables like I suggested. Just keep the persistent
    cars separate from the random cars. The persistent cars are obviously
    in a data context, the random ones created outside of one (this might
    not be possible, but I'd hope so).

    public List allCars()
    {
      List results = new List();

      results.addAll(savedCars());
      results.addAll(randomCars());

      return results;
    }

    (Add all the other plumbing you need to create the random cars, etc.)

    2) Cheat.

    import org.objectstyle.cayenne.PersistenceState;

    randomCar.setPersistenceState(COMMITTED); // Make it think it's already
    saved

    Or, have you tried this one?

    randomCar.setPersistenceState(TRANSIENT);

    Let us know if either of these approaches work for you.

    Thanks,

    /dev/mrg

    -----Original Message-----
    From: Elia Morling [mailto:eli..amiljen.se]
    Sent: Wednesday, June 30, 2004 12:34 PM
    To: cayenne-use..bjectstyle.org
    Subject: Re: Working with Transient Objects

    Sorry, let me try to make a better example.

    In the Cayenne Modeler I have a Car and a ParkingLot. In my
    database I have stored 1 ParkingLot and 5 Car(s).

    Now, I fire up my game. I get the ParkingLot and 5 Car(s) all stored
    in the database. Now I want 5 randomly created computer-controlled
    Car(s) for the duration of the game only. I want to use all the fields
    in
    my Car class as they are identical, except that I don't want to store
    them in the database. Why? Because the next time I start the game I
    want to randomly create 5 new ones. Meanwhile I want to commit any
    changes made to the 5 Car(s) controlled by players. All I need is
    a PersistenceState flag like NEW_DONT_COMMIT or similar on
    the computer controlled Car(s) so that the DataContext doesn't store
    them in the database.

    Elia

    ----- Original Message -----
    From: "Gentry, Michael" <michael_gentr..anniemae.com>
    To: "Elia Morling" <eli..amiljen.se>; <cayenne-user@objectstyle.org>
    Sent: Wednesday, June 30, 2004 6:05 PM
    Subject: RE: Working with Transient Objects

    I'm not sure if I understand what you are trying to do, but ...

    You have two entities which you modeled in Cayenne Modeler, Car and
    ParkingLot. You want to persist the ParkingLot entities, but not the
    Car entities? Do you ever persist Car entities? It doesn't sound to me
    like you want to persist them.

    If you do not want to persist the Car, you shouldn't be modeling it in
    Cayenne Modeler at all. What you should do is model the ParkingLot
    entity and in the subclass of the ParkingLot class (where you add your
    business logic), create your own setters, getters, and transient
    instance variables. Something similar to this:

    public class ParkingLot extends _ParkingLot
    {
      private List cars;

      public void addToCarArray(Car car)
      {
        if (cars == null)
          cars = new List();
        cars.add(car);
      }

      public void removeFromCarArray(Car car)
      {
        if (cars != null)
          cars.remove(car);
      }

      public List cars()
      {
        if (cars == null)
          cars = new List();

        return cars;
      }
    }

    NOTE: I didn't try to compile any of the above, but the general idea is
    to handle transient information in the subclass. You don't model
    transient information in Cayenne Modeler (the Car -- make plain old java
    class for it). It's also a good idea to use the subclass to handle
    derived information, possibly even caching it for efficiency (if it
    makes sense to do so -- you have to be careful if the parent values
    change, which would change the derived value). For example, you could
    have a fullName() method which returns firstName() + " " + middleName()
    + " " + lastName(). And, of course, any convenience methods go in the
    subclass, too.

    Hope that helps!

    /dev/mrg

    -----Original Message-----
    From: Elia Morling [mailto:eli..amiljen.se]
    Sent: Tuesday, June 29, 2004 5:21 PM
    To: cayenne-use..bjectstyle.org
    Subject: Working with Transient Objects

    Hi,
    Here's an example to illustrate my problem. I have a parking lot
    with 5 cars stored in the database. Every time I start up my
    application I need to create 5 new cars for the duration of the
    run only. I don't want to store them in the database so I simply
    create the objects without a context using regular new().

    Now I can't make them work with the parking lot, when using:

    parkinglot.addToCarArray(car);

    OR

    car.setParkinglot(parkinglot)

    Why doesn't this work and what should I do about it? I need to
    have database cars and non-database cars to co-exist in the
    parkinglot.

    Elia



    This archive was generated by hypermail 2.0.0 : Wed Jun 30 2004 - 13:17:31 EDT