Hi Damon,
I'm really new to Castor (a couple weeks in), but I'll try and help ya out. I was having a problem with no-cache updates, since our db is modified from outside Castor, so we need those changes reflected. I'm still writing a procedure to handle this until "reliable" dirty checking is implemented, so I've attached it below.
Basically, it is doing what someone had previously recommended about copying data from existing object to a newly created transaction object ("freshObj" in my code). I use Castor's FieldMolder to copy the values, and the only "special/custom" stuff for me is the "getNonTransactionalIdentity()". All my objects have a "public int getId()" method for the primary key, so this method determines the primary key for the obj passed in (so that it can load the "freshObj" to match). NOTE: This code will not flag any changes in db from BEFORE it was called, so (at the moment) it will overwrite any changes made outside Castor, and any changes made after original "obj" created, but before "freshObj" is loaded.
I'm sure this could be improved, but I'm still learning Castor. Hope this helps you.
<CODE>
public void updateLongNoCache(Object obj) throws PersistenceException
{
Database db = getDatabase();
FieldMolder[] fields = db.getScope().getPersistenceInfo(obj.getClass()).molder.getFields();
try {
db.begin();
Object freshObj = db.load(obj.getClass(), getNonTransactionalIdentity(obj));
for ( int i=0; i < fields.length; i++ ) {
FieldMolder curField = fields[i];
curField.setValue(freshObj, curField.getValue(obj, db.getClassLoader()) ,db.getClassLoader());
}
db.commit();
} catch (PersistenceException pe) {
throw pe;
} finally {
db.close();
}
}
private Object getNonTransactionalIdentity(Object obj) throws PersistenceException
{
try {
Method[] methods = obj.getClass().getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals("getId")) {
return methods[i].invoke(obj, new Object[] {} );
}
}
} catch (InvocationTargetException itex) {
throw new PersistenceException("No 'getId()' method found: ", itex);
} catch (IllegalAccessException iaex) {
throw new PersistenceException("No 'getId()' method found: ", iaex);
}
throw new PersistenceException("No 'getId()' method found");
}
</CODE>
Example use:
<CODE>
Supplier foo = null;
db.begin();
foo = db.load(Supplier.class, 3);
db.commit();
db.close();
... (other stuff occurs)
foo.setName("new supplier name");
updateLongNoCache(foo);
</CODE>
Trevor D. Cook
Waterloo, Ontario, Canada
-----Original Message-----
From: Damon Maria [mailto:[EMAIL PROTECTED]]
Sent: October 11, 2001 4:48 PM
To: [EMAIL PROTECTED]
Subject: Re: [castor-dev] ClassMolder.create() with PERSISTANCECAPABLE
field
OK, I just seem to be talking to myself here (first sign of madness?) but I'll
try again to illicit a response from someone.
Would it be a quick fix in JDO to turn on a flag/option that if update() is
called on an object that isn't in the cache then the object is loaded from the
database and castor updates it (without complaining that update() was called on
something loaded in this transaction. Since I'm basically having to do this all
manually at the moment, loading up the old object and then calling old.setX(
new.getX() ) for each property. And I'm sure castor with just a tweak or two
could do all this automagically for me.
please, someone?
Damon.
Damon Maria wrote:
>
> If I do make the change described in my previous email (getActualIdentity) then
> the create still doesn't work since castor doesn't like the parent
> UserInformation object not existing in the transaction already.
>
> The best answer would be to just call update on the UserInformation object and
> let castor handle it, but since this is running in a clustered environment I've
> turned caching off in the mapping file and therefore long-transactions just
> don't work.
>
> The reason long-transactions want the Timestampable interface and the cache is
> to perform dirty checking. But what if I *don't* want dirty checking. Just let
> me update it, please! Is there an easy way I can disable the dirty checking for
> long-transactions? I've done a lot of debugging inside castor, but I've no idea
> of how to do this, or more importantly, the implications of it.
>
> Otherwise, I'm stuffed basically. I can see no other way of writing to my
> database using castor. But it's pretty damn good at reading!
>
> regards,
> Damon.
>
> Damon Maria wrote:
> >
> > The situation:
> >
> > 1. In one transaction I load up a UserInformation object which has a collection
> > of UserSetting's.
> > 2. After closing the transaction I create a new UserSetting and link it up to
> > the UserInformation previously loaded.
> > 3. I start a new transaction and call database.create() on the new UserSetting.
> > 4. Eventually the call gets down to ClassMolder.create().
> > 5. It retrieves the value for the field that links the UserSetting back to it's
> > parent UserInformation (i.e. it gets the UserInformation object, line 833).
> > 6. It _tries_ to get the identity for this object but fails (gets null) since it
> > calls fieldClassMolder.getIdentity() and the UserInformation object hasn't been
> > loaded in this transaction (line 855).
> >
> > Should the fieldClassMolder.getIdentity() call instead be getActualIdentity(),
> > as this would correctly get the identity.
> >
> > Seperately, should I be declaring UserSettings as dependent on UserInformation?
> >
> > This is a long transaction and the objects are not the original ones returned by
> > castor because this is being used in an EJB continer and passed back and forth
> > to the client.
> >
> > Usual stuff: I am using the latest CVS (as of yesterday), and my mapping.xml:
> >
> > <class name="nz.co.ontap.motorweb.jdo.UserInformation" identity="id"
> > key-generator="global">
> > <map-to table="user_information" />
> > <cache-type type="none" />
> > <field name="id" type="integer">
> > <sql name="user_information_id" type="numeric" />
> > </field>
> > [...]
> > <field name="settings" type="nz.co.ontap.motorweb.jdo.UserSetting"
> > collection="collection" />
> > </class>
> >
> > <class name="nz.co.ontap.motorweb.jdo.UserSetting" identity="id"
> > key-generator="global">
> > <map-to table="user_setting" />
> > <cache-type type="none" />
> > <field name="id" type="integer">
> > <sql name="user_setting_id" type="numeric" />
> > </field>
> > <field name="userInformation"
> > type="nz.co.ontap.motorweb.jdo.UserInformation">
> > <sql name="user_information_id" />
> > </field>
> > <field name="stringValue" type="string">
> > <sql name="user_setting_string_value" type="varchar" />
> > </field>
> > <field name="typeId" type="integer">
> > <sql name="user_setting_type_id" type="numeric" />
> > </field>
> > </class>
> >
> > thanks in advance,
> > Damon.
>
> -----------------------------------------------------------
> If you wish to unsubscribe from this mailing, send mail to
> [EMAIL PROTECTED] with a subject of:
> unsubscribe castor-dev
--
Strobe lights and blown speakers
Fireworks and hurricanes
-----------------------------------------------------------
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
unsubscribe castor-dev
