You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by Thomas Mahler <th...@web.de> on 2003/08/08 20:25:14 UTC

Re: OJB uses jdbc cursor to Update - but my cursor doesn't suppor t up date!

Hi Alex,

Bates, Alex wrote:
> Hi Thomas,
> 
> Hmmm, so it doesn't use updatable cursors.  So OJB is not recognizing that
> an update has taken place.  When I call ODMG's Transaction.lock(obj,
> Transaction.WRITE), how does it determine if an update has taken place?  In
> my app, the servlet tier gets a Vector of O/R mapped objects from the EJB
> tier, updates a given object, then calls the EJB tier updateObject() method
> to update it.  Is there a problem with this?  I noticed in your ODMG
> examples you explicitly lock an object before calling the update methods -
> but I assumed it was different in an EJB-based app.
> 
> Q: is there a problem with this scenario?

Yes! ODMG has no notion of long transactions. that is ODMG want's you to 
perform all changes to object after locking them to the transactions.

So changing objects on the client, then sending them back to the server 
and locking them to a transaction will fail!

That's because the ODMG transaction manager was not able to track the 
state of that object.

The trick is as Follows:

After locking the changed object from the client call:
((o.a.ojb.odmg.TransactionImpl) tx).markDirty(instance);



> *servlet app retrieves O/R mapped object via EJB layer (which uses ODMG),
> but object is not locked (optimistic)
> *servlet calls setter methods on the object
> *servlet calls EJB updateObject method, which calls Transaction.lock
> 
> Q2: do I need to put an explicit READ lock on a retrieved list of objects
> returned by the EJB tier?

Yes, that would be another option. But it would mean to keep the ODMG tx 
open during the client operations. And when the client returns the 
changes object you have to looup the proper transaction.

cheers,
Thomas

> 
> 
> Details:
> 
> 
> Here is my app's architecture:
> 
> *OJB: uses the ODMG API w/in Jboss 3.2.1
> 
> *EJB tier: uses a PersistenceManagerBean SessionBean w/ insert, update,
> delete methods; the implementation of the update methods are as follows
> 
>     /**
>      * Store object that has been mapped in OJB repository
>      * @param obj
>      *
>      * @ejb:interface-method
>      */
>     public Object updateObject(Object obj) throws DataAccessException {
> 
>         return storeObject(obj);
>     }
> 
>     /**
>      */
>     public Object storeObject(Object obj) throws DataAccessException
>     {
>         try
>         {
>             if(log.isDebugEnabled()) log.debug("storeObject");
> 
>             Transaction tx = odmg.currentTransaction();
>             tx.lock(obj, Transaction.WRITE);
>         }
>         catch (Throwable t)
>         {
>             t.printStackTrace();
>             System.out.println(t.getMessage());
>         }
>         return obj;
>     }
> 
> Here is the method used to retrieve a list for the servlet tier:
>     /**
>      * @ejb:interface-method
>      */
>     public Vector getVector(Class klass) throws DataAccessException {
> 
>         Vector result = null;
>         try {
> 
>             OQLQuery query = odmg.newOQLQuery();
>             query.create("select allObjects from " + klass.getName());
>             DList list = (DList) query.execute();
> 
>             result = new Vector();
>             Object[] vals = list.toArray();
>             for (int i=0; i<list.size(); i++) {
>                 // Retrieve associated CLOB
>                 if (klass.newInstance() instanceof ClobVOInterface)
>                 {
>                     ClobVOInterface vo = (ClobVOInterface)list.get(i);
>                     retrieveClob((ClobVOInterface)vo);
>                 }
> 
>                 result.add(list.get(i));
>             }
> 
>         } catch (Throwable t) {
>             t.printStackTrace();
>         }
> 
>         return result;
>     }
> 
> *DAO: 
> DAO used by servlet tier to perform updates/retrieval (servlet doesn't
> directly access PM), w/ following code:
> 
> public class DefaultDAO implements DAOInterface {
> 
>     public void updateVO(VOInterface obj) throws DataAccessException {
>         PersistenceManagerRemote pm =
> ServiceLocator.getInstance().getPersistenceManager();
>         try {
>             pm.updateObject(obj);
>         } catch (DataAccessException e) {
>             e.printStackTrace();
>         } catch (RemoteException e) {
>             e.printStackTrace();
>         }
>     }
> 
>     public Vector getAllVO(Class klass, ACL acl) throws DataAccessException
> {
>         PersistenceManagerRemote pm =
> ServiceLocator.getInstance().getPersistenceManager();
>         try {
>             return pm.getVector(klass, acl);
>         } catch (DataAccessException e) {
>             e.printStackTrace();
>         } catch (RemoteException e) {
>             e.printStackTrace();
>         }
> 
>         return null;
>     }
> 
> 
> 
> *Servlet tier:
> Uses DAO method to retrieve list of objects; then has edit form that allows
> user to edit; here's the servlet update code 
>         
> 	  QueryVO query = (QueryVO)component;
>         query.setLabel(validator.getUIValue("label"));
>         query.setSql(validator.getUIValue("sql"));
>         query.setMaxRows(validator.getUIValueAsInt("maxRows"));
>  
> query.setQueryTimeoutSecs(validator.getUIValueAsInt("queryTimeoutSecs"));
> 
>         DAOFactory.getDAO(DefaultDAO.class.getName()).updateVO(component,
> acl);
> 
> 
> -----Original Message-----
> From: Thomas Mahler [mailto:thma32@web.de] 
> Sent: Thursday, August 07, 2003 11:08 PM
> To: OJB Users List
> Subject: Re: OJB uses jdbc cursor to Update - but my cursor doesn't support
> up date!
> 
> 
> Hi Alex
> 
> Bates, Alex wrote:
> 
>>Hello,
>>
>>I've isolated the root cause of my problem.  But turning debugging on, 
>>I saw all the SQL OJB was generating in my JBoss log file.
>>
>>OJB generates SQL for SELECT and INSERT.  But for UPDATE, no SQL is 
>>generated - it assumes it has an Updatable Cursor.  But my driver 
>>cursor does not support update.
> 
> 
> OJB does not use Updatable Cursors.
> Using UC would mean to have a cursor  opened between read and the final 
> broker.store() call. We don't do this to avoid problems with opened 
> resources and because only a few JDBC drivers properly support this feature.
> 
> SO if there are no UPDATE statements generated it must be caused by 
> something else.
> 
> are you using the ODMG API or the PB API?
> Please provide the code section where you don't get UPDATES generated.
> 
> cheers,
> Thomas
> 
> 
>>Q:  How do I tell OJB to use SQL to update instead of updating through 
>>a Cursor?  I tried setting JDBC level to 1.0 in 
>>repository_database.xml, but this didn't work.
>>
>>Thanks in advance!
>>
>>Alex
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
>>For additional commands, e-mail: ojb-user-help@db.apache.org
>>
>>
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org