Re: Re: Re: Moving object between DataContext

From: Michael Gentry (blacknex..mail.com)
Date: Mon Jul 24 2006 - 11:03:51 EDT

  • Next message: Michael Gentry: "Re: NamedQuery parameters"

    Oh yeah, a couple other options ...

    Put your getUser() etc queries in the model and then call them:

    http://cwiki.apache.org/confluence/display/CAYDOC/NamedQuery
    http://cwiki.apache.org/confluence/display/CAYDOC/Queries+Stored+in+DataMap

    Put getUser(DataContext dc, ...) in UserDataObject.java

    /dev/mrg

    On 7/24/06, Michael Gentry <blacknex..mail.com> wrote:
    > I'm still not 100% certain your workflow/etc, but here are some thoughts.
    >
    > Cayenne doesn't really have a disconnect/reconnect feature, which
    > sounds a bit like something Hibernate would have. The Cayenne
    > DataContext is a work area to manage your objects. Anything you
    > change in it is, conceptually, part of a transaction of changes you
    > want committed to the database. If you need two different
    > transactions, you can use two DataContexts or possibly even a nested
    > DataContext if that fits your workflow. Also, you could make your
    > method look more like:
    >
    > public doSomething() {
    > UserDataObject udo= m_userService.getUserXXX(...);
    > udo.setXXX(...);
    > udo.setXXX(...);
    > udo.setXXX(...);
    >
    > m_userService.saveUser(uod);
    >
    > AppointementDataObject ado=
    > m_appointementService.getAppointemetXXX(...);
    > ado.setXXX(...);
    > ado.setXXX(...);
    > ado.setXXX(...);
    > }
    >
    > You could also have your service layer receive as a parameter the
    > DataContext to use in which to load/save, which would give you more
    > flexibility.
    >
    > In all my years of using WebObjects, which includes EOF and is very
    > similar to Cayenne, I've never needed to disconnect/reconnect my
    > database objects. Even using Tapestry/Cayenne, which is a lot like
    > WebObjects, I've not needed to do that. I think if you tweak your
    > pattern a bit you'll find it can work very well for you.
    >
    > /dev/mrg
    >
    >
    >
    > On 7/23/06, Jonathan Bélisle <jonathan.belisl..cda.ca> wrote:
    > > I need the second DataContext for the following reasons :
    > >
    > > I have a service class for business logic.
    > > It's the service class that is responsible for accessing the database.
    > > The UI layer calls the service class and gets a DataObject or a list of
    > > DataObjects.
    > > The UI Layer perform some modification on the objects and then call
    > > the service to save the data and perform extra work.
    > >
    > > For this to work, the dataobjects returned by the service must have a
    > > datacontext or I won't be able
    > > to modified the relationships in the UI layer.
    > > The second DataContext is needed when I call the service to save the
    > > data. I need to be sure that there is no other object in the dataContext
    > > that will be saved on commitChanges except the ones pass to the method.
    > >
    > > Class UserService {
    > >
    > > public UserDataObject getUserXXX(...) {
    > > List results=
    > > DataContext.getThreadDataContext().performQuery(new
    > > SelectQuery(User.class.....);
    > > ...
    > > return (UserDataObject) result.get(x);
    > > }
    > >
    > > public void saveUser(UserDataObject udo) {
    > > DataContext writeDc= DataContext.createDataContext();
    > > udo= writeDc.localObject(udo.getObjectId(), udo);
    > >
    > > ... Perform extra work, send email, log, extra validation, ...
    > >
    > > writeContext.commitChanges();
    > > }
    > > }
    > >
    > > Class UIWebPage {
    > >
    > > public doSomething() {
    > > UserDataObject udo= m_userService.getUserXXX(...);
    > > udo.setXXX(...);
    > > udo.setXXX(...);
    > > udo.setXXX(...);
    > >
    > > AppointementDataObject ado=
    > > m_appointementService.getAppointemetXXX(...);
    > > ado.setXXX(...);
    > > ado.setXXX(...);
    > > ado.setXXX(...);
    > >
    > > m_userService.saveUser(uod);
    > > }
    > > }
    > >
    > > If i don't use another dataContext in saveUser, the appointement will
    > > get saved too.
    > > What i really would like to be able to do, is to be able to
    > > disconnect/reconnect the dataObjects.
    > > This way, the service disconnect the dataObjects before returning them
    > > to the client and reconnect them when saving them.
    > > Is it possible with cayenne ?
    > > I have tried unregister/register the objects but you cannot modify the
    > > relationships when there is no dataContext.
    > > I also need cayenne to be able to update only the modified properties
    > > when i reconnect them, not all the properties.
    > >
    > > I've been struggling with this issue for a while. Can someone help me on
    > > this.
    > > I'm using cayenne in a project where multiple UI access the service
    > > layer; Tapestry and Swing.
    > >
    > > Jonathan.
    > >
    > >
    > > Michael Gentry wrote:
    > > > At the risk of asking silly questions, why do you need the second
    > > > DataContext? If you do need the second one, could you wait until you
    > > > pull the object into the second context to do the setters? (So the
    > > > second context sets modified correctly.)
    > > >
    > > > Your comment about Cayenne not thinking an object is modified is
    > > > correct. If you have:
    > > >
    > > > if (object.getFirstName().equals("Michael"))
    > > > {
    > > > object.setFirstName("michael");
    > > > object.setFirstName("Michael");
    > > > }
    > > >
    > > > You essentially haven't modified the object and Cayenne figures this out.
    > > >
    > > > Thanks,
    > > >
    > > > /dev/mrg
    > > >
    > > >
    > > > On 7/23/06, Jonathan Bélisle <jonathan.belisl..cda.ca> wrote:
    > > >> Hi, here is my problem.
    > > >>
    > > >> I have a DataObject da1 registered with DataContext dc1.
    > > >> I perform modification on da1. It's persistence state becomes MODIFIED.
    > > >>
    > > >> Now I want to move da1 to DataContext dc2 and keep it's state MODIFIED
    > > >> so that when I do dc2.commitChanges(); da1 get written to the database.
    > > >>
    > > >> Using dc2.localObject(da1.getObjectId(), da1) doesn't work because it's
    > > >> set the persistence state to COMMITTED and loose
    > > >> track of witch properties were modified.
    > > >> Even if I do da1.setPersistanceState(PersistenceState.MODIFIED) after
    > > >> localObject() da1 does not get written to the database on the next
    > > >> commit because dc2 thinks that no properties were modified.
    > > >>
    > > >> Anybody know how to do that, a workaround ?
    > > >>
    > > >> Thanks in advance, Jonathan.
    > > >>
    > > >>
    > > >>
    > > >>
    > > >>
    > > >
    > > >
    > > >
    > >
    > >
    > >
    >



    This archive was generated by hypermail 2.0.0 : Mon Jul 24 2006 - 11:04:14 EDT