August,
one tiny little question, pls. see below ...
Werner
On Fri, 2 Apr 2004 17:35:17 -0800 (PST), August Detlefsen wrote:
>
>I understand the need for dirty checking to manage concurrency across
>many transactions, but what is the need for dirty checking within the
>bounds of one transaction?
>
>In my case, I originally attempted to create the object, get the newly
>created ID, us the ID to set a field within the same object, then
>commit -all in the course of a single short transaction.
Why are you trying to set this property as a String valeu and not a fully fledget
object reference ? Just wondering ? Having said that, I do not know top
of my head whether self-referential relationships would be supported fully with the
current code-base.
Werner
The
>ObjectModifiedException cannot be from another transaction trying to
>modify the same object because in this case the create() call has not
>even committed yet so there is no way for another transaction to even
>know it exists.
>
>You are right about the second code example, it is pure hack! But it
>was the only way I could get around that exception. I would love to do
>it the right way, believe me. Is this is actually a bug then?
>
>-August
>
>
>
>
>
>--- Bruce Snyder <[EMAIL PROTECTED]> wrote:
>>
>> August Detlefsen wrote:
>> > I recently ran into this and I'm interested to know if it is
>> > designed-in behavior, a bug, or a 'feature'. The abstract is that I
>> > needed to create a NavPageContent Object, then use its ID to
>> formulate
>> > a link String, which was then set back into the same Object and
>> > persisted.
>> >
>> > When I tried something like this:
>> >
>> > db.create(page);
>> > String link = "/page/" + page.getId();
>> > page.setLink(link);
>> > db.commit();
>> >
>> > I get this error:
>> >
>> > org.exolab.castor.jdo.ObjectModifiedException: Transaction aborted:
>> > Object of type model.NavPageContent with identity 6,044 has been
>> > modified by a concurrent transaction (cache entry is different from
>> > database row)
>> > at
>> > org.exolab.castor.jdo.engine.SQLEngine.store(SQLEngine.java:882)
>> > at
>> > org.exolab.castor.persist.ClassMolder.store(ClassMolder.java:1609)
>> > at
>> > org.exolab.castor.persist.LockEngine.store(LockEngine.java:750)
>> > at
>> >
>>
>org.exolab.castor.persist.TransactionContext.prepare(TransactionContext.java:1540)
>> > at
>> >
>>
>org.exolab.castor.jdo.engine.DatabaseImpl.commit(DatabaseImpl.java:512)
>> > at AdminController.dispatchPage(AdminController.java:1087)
>> > at AdminController.service(AdminController.java:157)
>> > at
>> javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
>> > at
>> >
>>
>org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
>> > ....
>> >
>> >
>> > Ultimately as a workaround I had to create the object, commit,
>> expire
>> > the cache, close the DB, reopen the DB, reload the object, make the
>> > changes and commit:
>> >
>> > db.create(page);
>> > db.commit();
>> > //expire cache
>> > Class[] type = { NavPageContent.class } ;
>> > Object[] identity = { page.getId() } ;
>> > db.expireCache( type, identity );
>> >
>> > db.close();
>> > db = jdo.getDatabase();
>> > db.begin();
>> > page = (NavPageContent)db.load(NavPageContent.class, page.getId());
>> >
>> > link = "/page/" + page.getId();
>> > page.setLink( link );
>> >
>> > db.commit();
>> >
>> > Is this behavior by design? Is there some way to get the next ID
>> rather
>> > than actually creating the Object -Can it be pulled directly from a
>> > sequence generator prior to create()?
>>
>> August,
>>
>> The ObjectModifiedException is defintely by design. In fact, it's one
>> of
>> Castor's biggest hidden features - dirty checking. Dirty checking is
>> hugely powerful because it allows many tx contexts to work with the
>> same
>> object without stomping on one another.
>>
>> First of all, what cache-type are you using for this object in the
>> mapping descriptor? You'll need to use something other than none. The
>>
>> count-limited cache is the default cache-type.
>>
>> The example code above is actually circumventing the dirty checking
>> functionality completely and rendering Castor almost useless because
>> it's a brute force approach that doesn't take into consideration the
>> possibility of concurrency. By expiring the cache in the code example
>>
>> above, there is potential for overwriting someone else's changes and
>> corrupting the data.
>>
>> Because you're already using long transactions, maybe a better thing
>> to
>> do is to grab the timestamp from the object in the first tx using
>> jdoGetTimeStamp() and cache it. Then in the tx where the object will
>> be
>> persisted just apply that timestamp to the object using
>> jdoSetTimeStamp() before calling db.update(). This will get you
>> around
>> the ObjectModifiedException. The problem with this workaround is that
>> it
>> could get messy with concurrency.
>>
>> Bruce
>> --
>> perl -e 'print
>> unpack("u30","<0G)[EMAIL PROTECTED]&5R\"F9E<G)E=\$\!F<FEI+F-O;0\`\`");'
>>
>> The Castor Project
>> http://www.castor.org/
>>
>> Apache Geronimo
>> http://incubator.apache.org/projects/geronimo.html
>>
>> -----------------------------------------------------------
>> If you wish to unsubscribe from this mailing, send mail to
>> [EMAIL PROTECTED] with a subject of:
>> unsubscribe castor-dev
>>
>
>
>__________________________________
>Do you Yahoo!?
>Yahoo! Small Business $15K Web Design Giveaway
>http://promotions.yahoo.com/design_giveaway/
>
>-----------------------------------------------------------
>If you wish to unsubscribe from this mailing, send mail to
>[EMAIL PROTECTED] with a subject of:
> unsubscribe castor-dev
>
-----------------------------------------------------------
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
unsubscribe castor-dev