You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Michael Lepine <mi...@gmail.com> on 2007/06/21 22:45:52 UTC

creating/saving transient objects to database

I've got a situation where I've got strict POJO objects that I'll need to
copy data from and into my generated Cayenne classes. My issue is that when
I copy the data from the bean to the Cayenne class, I don't know whether the
object exists or not. Thus, I create the Cayenne class instance using
DataContext.newObject(). Obviously, when I call DataContext.commitChanges(),
an insert is being attempted on the corresponding table even if a record
already exists in the database.

Is there a way to create the Cayenne instance so that the persistent layer
will know to check whether the record exists and update it instead of always
attempting an insert?

Any help and guidance are appreciated.

Re: AW: creating/saving transient objects to database

Posted by Craig L Russell <Cr...@Sun.COM>.
On Jun 22, 2007, at 12:30 AM, Peter Schröder wrote:

> this approach has the downside that you may run into concurrency  
> issues (check than act).
> you may get a duplicate even if you first check for an existing entry.
> this is really tricky in webapplications...

You can overcome this by running the transaction in serializable  
mode. This will put read locks on ranges to prevent other  
transactions from inserting records that you are inserting after  
querying.

Craig
>
> kind regards,
> peter
>
> -----Ursprüngliche Nachricht-----
> Von: Fredrik Liden [mailto:fliden@translate.com]
> Gesendet: Freitag, 22. Juni 2007 00:10
> An: user@cayenne.apache.org
> Betreff: RE: creating/saving transient objects to database
>
> If you're calling newObject you'll get a registered object with
> PersistenceState.NEW. so consequently the commit tries to insert it.
>
> I'm thinking at some point you'll need to manually check if the object
> exists in the database or not based on some criteria. Maybe you can
> create a service class that checks using a query if the Pojo object
> exists in the db. If it does it returns the existing DataObject and if
> not it returns the object using newObject. Then the persistenceState
> will be either NEW or COMMITED and commit will trigger insert and  
> update
> respectively.
>
> Of course the Cayenne guys probably have some other nifty way to do  
> it.
>
> Fredrik
>
>
>
> -----Original Message-----
> From: Michael Lepine [mailto:mikelepine@gmail.com]
> Sent: Thursday, June 21, 2007 2:46 PM
> To: user@cayenne.apache.org
> Subject: creating/saving transient objects to database
>
> I've got a situation where I've got strict POJO objects that I'll need
> to
> copy data from and into my generated Cayenne classes. My issue is that
> when
> I copy the data from the bean to the Cayenne class, I don't know  
> whether
> the
> object exists or not. Thus, I create the Cayenne class instance using
> DataContext.newObject(). Obviously, when I call
> DataContext.commitChanges(),
> an insert is being attempted on the corresponding table even if a  
> record
> already exists in the database.
>
> Is there a way to create the Cayenne instance so that the persistent
> layer
> will know to check whether the record exists and update it instead of
> always
> attempting an insert?
>
> Any help and guidance are appreciated.

Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


AW: creating/saving transient objects to database

Posted by Peter Schröder <Pe...@freenet-ag.de>.
this approach has the downside that you may run into concurrency issues (check than act).
you may get a duplicate even if you first check for an existing entry.
this is really tricky in webapplications...

kind regards,
peter

-----Ursprüngliche Nachricht-----
Von: Fredrik Liden [mailto:fliden@translate.com] 
Gesendet: Freitag, 22. Juni 2007 00:10
An: user@cayenne.apache.org
Betreff: RE: creating/saving transient objects to database

If you're calling newObject you'll get a registered object with
PersistenceState.NEW. so consequently the commit tries to insert it.

I'm thinking at some point you'll need to manually check if the object
exists in the database or not based on some criteria. Maybe you can
create a service class that checks using a query if the Pojo object
exists in the db. If it does it returns the existing DataObject and if
not it returns the object using newObject. Then the persistenceState
will be either NEW or COMMITED and commit will trigger insert and update
respectively.

Of course the Cayenne guys probably have some other nifty way to do it.

Fredrik
 


-----Original Message-----
From: Michael Lepine [mailto:mikelepine@gmail.com] 
Sent: Thursday, June 21, 2007 2:46 PM
To: user@cayenne.apache.org
Subject: creating/saving transient objects to database

I've got a situation where I've got strict POJO objects that I'll need
to
copy data from and into my generated Cayenne classes. My issue is that
when
I copy the data from the bean to the Cayenne class, I don't know whether
the
object exists or not. Thus, I create the Cayenne class instance using
DataContext.newObject(). Obviously, when I call
DataContext.commitChanges(),
an insert is being attempted on the corresponding table even if a record
already exists in the database.

Is there a way to create the Cayenne instance so that the persistent
layer
will know to check whether the record exists and update it instead of
always
attempting an insert?

Any help and guidance are appreciated.

Re: creating/saving transient objects to database

Posted by Aristedes Maniatis <ar...@maniatis.org>.
On 22/06/2007, at 8:32 AM, Michael Lepine wrote:

> I'll look (and hope) for other solutions that may be cleaner though.


I've not tried to do this, so its just an idea to investigate:  
version 3.0 has lifecycle events which allow you to intercept certain  
calls to the Cayenne engine. One of those is PrePersist:

http://cayenne.apache.org/doc/lifecycle-callbacks.html

You may be able to do some magic there and swap your new Cayenne  
object for a used one from the data store.


Ari Maniatis


-------------------------->
Aristedes Maniatis
phone +61 2 9660 9700
PGP fingerprint 08 57 20 4B 80 69 59 E2  A9 BF 2D 48 C2 20 0C C8



Re: creating/saving transient objects to database

Posted by Michael Lepine <mi...@gmail.com>.
Thanks for replying. I started to think I may have to do what you were
suggesting below as well.

I'll look (and hope) for other solutions that may be cleaner though.

Thanks again.


On 6/21/07, Fredrik Liden <fl...@translate.com> wrote:
>
> If you're calling newObject you'll get a registered object with
> PersistenceState.NEW. so consequently the commit tries to insert it.
>
> I'm thinking at some point you'll need to manually check if the object
> exists in the database or not based on some criteria. Maybe you can
> create a service class that checks using a query if the Pojo object
> exists in the db. If it does it returns the existing DataObject and if
> not it returns the object using newObject. Then the persistenceState
> will be either NEW or COMMITED and commit will trigger insert and update
> respectively.
>
> Of course the Cayenne guys probably have some other nifty way to do it.
>
> Fredrik
>
>
>
> -----Original Message-----
> From: Michael Lepine [mailto:mikelepine@gmail.com]
> Sent: Thursday, June 21, 2007 2:46 PM
> To: user@cayenne.apache.org
> Subject: creating/saving transient objects to database
>
> I've got a situation where I've got strict POJO objects that I'll need
> to
> copy data from and into my generated Cayenne classes. My issue is that
> when
> I copy the data from the bean to the Cayenne class, I don't know whether
> the
> object exists or not. Thus, I create the Cayenne class instance using
> DataContext.newObject(). Obviously, when I call
> DataContext.commitChanges(),
> an insert is being attempted on the corresponding table even if a record
> already exists in the database.
>
> Is there a way to create the Cayenne instance so that the persistent
> layer
> will know to check whether the record exists and update it instead of
> always
> attempting an insert?
>
> Any help and guidance are appreciated.
>

RE: creating/saving transient objects to database

Posted by Fredrik Liden <fl...@translate.com>.
If you're calling newObject you'll get a registered object with
PersistenceState.NEW. so consequently the commit tries to insert it.

I'm thinking at some point you'll need to manually check if the object
exists in the database or not based on some criteria. Maybe you can
create a service class that checks using a query if the Pojo object
exists in the db. If it does it returns the existing DataObject and if
not it returns the object using newObject. Then the persistenceState
will be either NEW or COMMITED and commit will trigger insert and update
respectively.

Of course the Cayenne guys probably have some other nifty way to do it.

Fredrik
 


-----Original Message-----
From: Michael Lepine [mailto:mikelepine@gmail.com] 
Sent: Thursday, June 21, 2007 2:46 PM
To: user@cayenne.apache.org
Subject: creating/saving transient objects to database

I've got a situation where I've got strict POJO objects that I'll need
to
copy data from and into my generated Cayenne classes. My issue is that
when
I copy the data from the bean to the Cayenne class, I don't know whether
the
object exists or not. Thus, I create the Cayenne class instance using
DataContext.newObject(). Obviously, when I call
DataContext.commitChanges(),
an insert is being attempted on the corresponding table even if a record
already exists in the database.

Is there a way to create the Cayenne instance so that the persistent
layer
will know to check whether the record exists and update it instead of
always
attempting an insert?

Any help and guidance are appreciated.

Re: creating/saving transient objects to database

Posted by Michael Lepine <mi...@gmail.com>.
Excellent. I will check this out.

Thanks to all for the replies/suggestions.


On 6/22/07, Michael Gentry <bl...@gmail.com> wrote:
>
> We had something similar here where a batch job needed to read a data file
> and insert new records or update existing records (handle duplicates,
> essentially).  What we did was:
>
> * Read the data file, find the key data.
> * Write and call a getFoo(dataContext, keys) method.
> * The getFoo() method would query the database and if it found a record,
> it
> would return the Cayenne object to us.  If no record was found, it would
> create and register a new object in the DC and return the new object.
> * Then we'd apply all the data in the data file to the object return by
> getFoo().
> * Then dataContext.commitChanges().
> * Repeat until we processed all the data.
>
> Seemed to work pretty well and I think that approach would work for you,
> too, most likely.  In your case, your POJO is the equivalent of a record
> in
> our data file.  This also frees you up from having to care about the
> persistence state.  You don't care.  You have an object, apply the
> changes,
> commit.
>
> /dev/mrg
>
> PS. If relationships are involved, your getFoo() should create all the
> objects for all of the required relationships if you have to
> create/register
> new objects (when there was no DB match).  This way your main processing
> code can just apply changes blindly without having to check if the
> relationships exist.
>
>
> On 6/21/07, Michael Lepine <mi...@gmail.com> wrote:
> >
> > I've got a situation where I've got strict POJO objects that I'll need
> to
> > copy data from and into my generated Cayenne classes. My issue is that
> > when
> > I copy the data from the bean to the Cayenne class, I don't know whether
> > the
> > object exists or not. Thus, I create the Cayenne class instance using
> > DataContext.newObject(). Obviously, when I call
> DataContext.commitChanges
> > (),
> > an insert is being attempted on the corresponding table even if a record
> > already exists in the database.
> >
> > Is there a way to create the Cayenne instance so that the persistent
> layer
> > will know to check whether the record exists and update it instead of
> > always
> > attempting an insert?
> >
> > Any help and guidance are appreciated.
> >
>

Re: creating/saving transient objects to database

Posted by Michael Gentry <bl...@gmail.com>.
We had something similar here where a batch job needed to read a data file
and insert new records or update existing records (handle duplicates,
essentially).  What we did was:

* Read the data file, find the key data.
* Write and call a getFoo(dataContext, keys) method.
* The getFoo() method would query the database and if it found a record, it
would return the Cayenne object to us.  If no record was found, it would
create and register a new object in the DC and return the new object.
* Then we'd apply all the data in the data file to the object return by
getFoo().
* Then dataContext.commitChanges().
* Repeat until we processed all the data.

Seemed to work pretty well and I think that approach would work for you,
too, most likely.  In your case, your POJO is the equivalent of a record in
our data file.  This also frees you up from having to care about the
persistence state.  You don't care.  You have an object, apply the changes,
commit.

/dev/mrg

PS. If relationships are involved, your getFoo() should create all the
objects for all of the required relationships if you have to create/register
new objects (when there was no DB match).  This way your main processing
code can just apply changes blindly without having to check if the
relationships exist.


On 6/21/07, Michael Lepine <mi...@gmail.com> wrote:
>
> I've got a situation where I've got strict POJO objects that I'll need to
> copy data from and into my generated Cayenne classes. My issue is that
> when
> I copy the data from the bean to the Cayenne class, I don't know whether
> the
> object exists or not. Thus, I create the Cayenne class instance using
> DataContext.newObject(). Obviously, when I call DataContext.commitChanges
> (),
> an insert is being attempted on the corresponding table even if a record
> already exists in the database.
>
> Is there a way to create the Cayenne instance so that the persistent layer
> will know to check whether the record exists and update it instead of
> always
> attempting an insert?
>
> Any help and guidance are appreciated.
>