James,

Why don't you actually use Database.getJdbcConnection() instead ? Iow, your 
code could look similar to 

Database db = jdo.getDatabase(9;
db.begin();
Connection connection = db.getJdbcConnection();
...
db.commit();
db.close();

Werner

PS Apart from this, you could try to start using the Spring ORM implemention 
for Castor JDO, and then - when implementing individual methods of your DAOs - 
either use the CastorTemplate or the JDBCTemplate, whatever your preferences 
are.


> -----Original Message-----
> From: James Abley [mailto:[EMAIL PROTECTED] 
> Sent: Donnerstag, 11. Jänner 2007 11:37
> To: [email protected]
> Subject: Re: [castor-user] [JDO] Castor Locking on Object Graphs
> 
> Cheers Ralf,
> 
> I'd guessed as much and have set the cache to none for that object. 
> Preliminary indications from running my tests show that the 
> application still works correctly using this hybrid approach 
> of Castor and JDBC. 
> This application should be the only thing writing to that 
> database, so otherwise the cache should work correctly, but I 
> might need to judiciously disable it for certain domain 
> objects. Shouldn't be a problem.
> 
> I do have one question about it though. Obviously, I'd like 
> to utilise the same mechanism that Castor uses for retrieving 
> a JDBC Connection. 
> Initial browsing of the code makes me think that I can do it 
> fairly easily using this:
> 
> /**
>   * Return a Connection, using the same mechanisms that 
> Castor uses, so
>   * hopefully doing the same ConnectionPool / JNDI lookup 
> whatever, that
>   * Castor is configured to use.
>   *
>   * @return a Connection - not null.
>   * @throws SQLException if there was a problem.
>   */
> private Connection getConnection() throws SQLException {
> 
>      // We know the name of the Database entry in the configuration is
>      // "default"
>      DatabaseRegistry databaseRegistry = DatabaseRegistry
>              .getDatabaseRegistry("default");
>      return databaseRegistry.createConnection();
> }
> 
> It seems to work, but it would be nice to have it confirmed 
> by someone more familiar with the code!
> 
> Cheers,
> 
> James
> 
> Ralf Joachim wrote:
> > Hi James,
> > 
> > as far as I remember, CALL SQL does only work for select statements 
> > but not for update or insert. You have to use JDBC for this 
> kind of things.
> > 
> > Having said that you have to take care on cached objects 
> that you have 
> > updated through JDBC. Castor does not know about the 
> database changes 
> > and will hold dirthy objects in its cache. This will lead to 
> > ObjectModifiedExceptions thrown when updating these objects through 
> > Castor. Another problem is that you do not instantly see 
> your changes 
> > done by JDB statements. Therefore you need to set cache 
> type to none 
> > or remove the updated object from cache. While I have used 
> the first 
> > myself I have no experience about the second solution.
> > 
> > Regards
> > Ralf
> > 
> > 
> > James Abley schrieb:
> >> Actually, it doesn't look like I can drop into raw SQL in this way.
> >>
> >> CALL SQL UPDATE myObject SET field = $1 WHERE ID = $2
> >>
> >> That doesn't get parsed properly by OQLQueryImpl.createCall - it 
> >> looks for the WHERE clause and examines the statement for 
> $x tokens 
> >> after the string value WHERE, rather than checking the whole 
> >> statement. Later,
> >> OQLQueryImpl.bind(Object) throws a NullPointerException 
> when it tries 
> >> to bind the first parameter, and can't find a ParamInfo 
> object in the 
> >> _paramInfo field keyed on Integer(1).
> >>
> >> So it looks like I will have to drop into JDBC to use this sort of 
> >> update approach.
> >>
> >> Should I raise a JIRA ticket about the OQL parsing?
> >>
> >> Cheers,
> >>
> >> James
> >>
> >> James Abley wrote:
> >>> To provide more context, I'm seeing locking and 
> >>> LockNotGrantedException problems with a part of the 
> application that 
> >>> tries to update a single field in a root object, and 
> >>> LockNotGrantedExceptions happen over the root object, or 
> something 
> >>> in the related object graph. I'm leaning towards the idea of 
> >>> swapping out the current implementation for a simple raw 
> SQL 'UPDATE 
> >>> MyObject SET field = ? WHERE ID = ' approach to see if 
> that removes 
> >>> the problem and was wondering if anyone else has seen 
> similar issues 
> >>> or resorted to that type of thing?
> >>>
> >>> Cheers,
> >>>
> >>> James
> >>>
> >>> James Abley wrote:
> >>>> Cheers Ralf and Werner,
> >>>>
> >>>> That tallies with my understanding.
> >>>>
> >>>> Does anyone have real-world examples they can share about 
> >>>> complexity of objects graphs that they have in their 
> domain? One of 
> >>>> the applications I deal with locks a lot of objects (maybe ten 
> >>>> objects) when a root object is loaded.
> >>>>
> >>>> Some of this (I believe) is mitigated since some of the domain 
> >>>> objects can be marked in the mapping file as read-only, and so I 
> >>>> would hope that Castor never gets any lock on that; e.g. 
> if one of 
> >>>> the objects references a Country object that is marked 
> as read-only 
> >>>> in the mapping file, any attempt to load something referencing a 
> >>>> Country object will always return that Country object as 
> read-only 
> >>>> and thus no transaction should experience race-conditions on 
> >>>> attempting to gain a lock on a Country object, no matter what 
> >>>> AccessMode is being used by the client transaction.
> >>>>
> >>>> But my main concern is whether having such a complex 
> object graph 
> >>>> is damaging to concurrency, and whether I should look at 
> >>>> de-normalisation to flatten it a bit.
> >>>>
> >>>> Cheers,
> >>>>
> >>>> James
> >>>>
> >>>> Werner Guttmann wrote:
> >>>>> In addition to what Ralf has said, please note that loading 
> >>>>> objects as read-only mode (in one way or the other) 
> will help you 
> >>>>> improving performance as Castor will perform less checks at the 
> >>>>> end of the transaction.
> >>>>>
> >>>>> In other words, make sure that you know your domain model, 
> >>>>> especially when it comes down to categorizations such as 
> >>>>> 'stability', 'cacheability', etc.
> >>>>>
> >>>>> Regards
> >>>>> Werner
> >>>>>
> >>>>> Ralf Joachim wrote:
> >>>>>> Hi James,
> >>>>>>
> >>>>>> Castor locks the whole object graph from the time when it gets 
> >>>>>> loaded until the end of the transaction which is 
> _db.commit(). If 
> >>>>>> Castor would not lock the whole object graph that 
> could lead to 
> >>>>>> inconsistenties.
> >>>>>> With
> >>>>>> the default access mode 'Shared' these locks are handled by 
> >>>>>> Castor internally.
> >>>>>>
> >>>>>> As the transaction at your first example is open during 'some 
> >>>>>> long operation' the whole graph gets locked until the 
> end of this 
> >>>>>> transaction.
> >>>>>>
> >>>>>> At the second example you have 2 short transaction. 
> The first one 
> >>>>>> loads the object and thereafter releases any locks at first 
> >>>>>> _db.commit().
> >>>>>> According to this no object is locked during the 'some long 
> >>>>>> operation'.
> >>>>>> After that operation you start the second transaction 
> which again 
> >>>>>> loads and locks the object including all related ones. 
> Then you 
> >>>>>> do some changes to the objects and commit them. At this commit 
> >>>>>> the changes are written to database and the locks get released 
> >>>>>> again.
> >>>>>>
> >>>>>> As the objects are not locked during 'some lock 
> operation' at the 
> >>>>>> second example, you need to be aware that your object may have 
> >>>>>> changed in the meantime.
> >>>>>>
> >>>>>> Hope this helps
> >>>>>> Ralf
> >>>>>>
> >>>>>>
> >>>>>> James Abley schrieb:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> I'm trying to understand Castor's locking mechanism 
> for object 
> >>>>>>> graphs.
> >>>>>>>
> >>>>>>> Say I have the following classes:
> >>>>>>>
> >>>>>>> class Book {
> >>>>>>>
> >>>>>>>     int id;
> >>>>>>>
> >>>>>>>     String author;
> >>>>>>>
> >>>>>>>     ...
> >>>>>>> }
> >>>>>>>
> >>>>>>> class Customer {
> >>>>>>>
> >>>>>>>     int id;
> >>>>>>>
> >>>>>>>     // Assume this will be a collection of Books that
> >>>>>>>     // has been browsed by each customer.
> >>>>>>>     Collection booksBrowsed;
> >>>>>>>
> >>>>>>>     // Assume that this is the transaction history of
> >>>>>>>     // each customer, so a collection of Transaction
> >>>>>>>     // objects
> >>>>>>>     Collection transactions;
> >>>>>>>
> >>>>>>>     Date lastLoginTime;
> >>>>>>>
> >>>>>>>     ...
> >>>>>>> }
> >>>>>>>
> >>>>>>> class Transaction {
> >>>>>>>
> >>>>>>>     int id;
> >>>>>>>
> >>>>>>>     Date purchaseTime;
> >>>>>>>
> >>>>>>>     Book item;
> >>>>>>>
> >>>>>>>     ...
> >>>>>>> }
> >>>>>>>
> >>>>>>> If I have client code that does something like the following:
> >>>>>>>
> >>>>>>>
> >>>>>>> Database db = getDatabase();
> >>>>>>> db.begin();
> >>>>>>> db.load(Customer.class, 3, Database.Shared);
> >>>>>>>
> >>>>>>> // do some long operation here
> >>>>>>>
> >>>>>>> customer.setLastLoginTime(Calendar.getInstance().getTime());
> >>>>>>> db.commit();
> >>>>>>> db.close();
> >>>>>>>
> >>>>>>>
> >>>>>>> Is there a lock held on all of the objects in the 
> collections in 
> >>>>>>> the Customer object? Or is a lock only obtained on 
> the Customer 
> >>>>>>> object when the transaction is ending and Castor can examine 
> >>>>>>> each object, see if it's dirty and thus needs to get 
> a lock to 
> >>>>>>> update the object?
> >>>>>>>
> >>>>>>> Second related part. I'm very familiar with 
> >>>>>>> http://www.castor.org/jdo-best-practice.html, but I 
> was curious 
> >>>>>>> about another aspect. Assume that I re-write the 
> client to try 
> >>>>>>> to minimize the
> >>>>>>> transaction:
> >>>>>>>
> >>>>>>>
> >>>>>>> Database db = getDatabase();
> >>>>>>> db.begin();
> >>>>>>> db.load(Customer.class, 3, Database.ReadOnly); db.commit(); 
> >>>>>>> db.close();
> >>>>>>>
> >>>>>>> // do some long operation here
> >>>>>>> db.begin();
> >>>>>>> db.load(Customer.class, 3, Database.Shared); 
> >>>>>>> customer.setLastLoginTime(Calendar.getInstance().getTime());
> >>>>>>> db.commit();
> >>>>>>> db.close();
> >>>>>>>
> >>>>>>>
> >>>>>>> Again, what gets locked? Is it the entire object 
> graph, or just 
> >>>>>>> the dirty objects?
> >>>>>>>
> >>>>>>> Presumably the latter code sample is the recommended 
> way to go, 
> >>>>>>> irrespective of how the object graph gets locked?
> >>>>>>>
> >>>>>>> Cheers,
> >>>>>>>
> >>>>>>> James
> >>>>>>>
> >>>>>>> 
> ----------------------------------------------------------------
> >>>>>>> ----- To unsubscribe from this list please visit:
> >>>>>>>
> >>>>>>>    http://xircles.codehaus.org/manage_email
> >>>>>
> >>>>> 
> ------------------------------------------------------------------
> >>>>> --- To unsubscribe from this list please visit:
> >>>>>
> >>>>>     http://xircles.codehaus.org/manage_email
> >>>>>
> >>>>
> >>>> 
> -------------------------------------------------------------------
> >>>> -- To unsubscribe from this list please visit:
> >>>>
> >>>>    http://xircles.codehaus.org/manage_email
> >>>>
> >>>
> >>> 
> --------------------------------------------------------------------
> >>> - To unsubscribe from this list please visit:
> >>>
> >>>    http://xircles.codehaus.org/manage_email
> >>>
> >>
> >> 
> ---------------------------------------------------------------------
> >> To unsubscribe from this list please visit:
> >>
> >>    http://xircles.codehaus.org/manage_email
> > 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
> 
>     http://xircles.codehaus.org/manage_email
> 

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply via email to