You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ol...@apache.org on 2003/07/27 18:18:16 UTC
cvs commit: db-ojb/src/test/org/apache/ojb/otm OtmExamples.java
olegnitz 2003/07/27 09:18:16
Modified: src/java/org/apache/ojb/broker/accesslayer
CollectionProxy.java IndirectionHandler.java
src/java/org/apache/ojb/otm/core ConcreteEditingContext.java
src/test/org/apache/ojb/otm OtmExamples.java
Added: src/java/org/apache/ojb/broker/accesslayer
CollectionProxyListener.java
Log:
Added CollectionProxyListener for use in OTM:
now OTM doesn't load all CollectionProxies automatically
Revision Changes Path
1.22 +37 -5 db-ojb/src/java/org/apache/ojb/broker/accesslayer/CollectionProxy.java
Index: CollectionProxy.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/CollectionProxy.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- CollectionProxy.java 19 Jun 2003 11:26:00 -0000 1.21
+++ CollectionProxy.java 27 Jul 2003 16:18:15 -0000 1.22
@@ -92,7 +92,9 @@
*/
private boolean needsClose;
- public CollectionProxy(PBKey aKey, Query aQuery)
+ private ArrayList m_listeners;
+
+ public CollectionProxy(PBKey aKey, Query aQuery)
{
this(aKey, RemovalAwareCollection.class, aQuery);
}
@@ -143,8 +145,9 @@
else
{
result = (Collection) getCollectionClass().newInstance();
- }
- return result;
+ }
+ notifyListeners();
+ return result;
}
catch (Exception ex)
{
@@ -156,7 +159,19 @@
}
}
- /**
+ protected void notifyListeners()
+ {
+ if (m_listeners != null)
+ {
+ for (int i = m_listeners.size() - 1; i >= 0; i--)
+ {
+ CollectionProxyListener l = (CollectionProxyListener) m_listeners.get(i);
+ l.loaded(this);
+ }
+ }
+ }
+
+ /**
* @see Collection#size()
*/
public int size()
@@ -457,5 +472,22 @@
{
this.m_brokerKey = brokerKey;
}
+
+ public synchronized void addListener(CollectionProxyListener l)
+ {
+ if (m_listeners == null)
+ {
+ m_listeners = new ArrayList();
+ }
+ m_listeners.add(l);
+ }
+
+ public synchronized void removeListener(CollectionProxyListener l)
+ {
+ if (m_listeners != null)
+ {
+ m_listeners.remove(l);
+ }
+ }
}
1.17 +1 -15 db-ojb/src/java/org/apache/ojb/broker/accesslayer/IndirectionHandler.java
Index: IndirectionHandler.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/IndirectionHandler.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- IndirectionHandler.java 9 Jun 2003 18:50:25 -0000 1.16
+++ IndirectionHandler.java 27 Jul 2003 16:18:15 -0000 1.17
@@ -297,14 +297,9 @@
{
try
{
- // [oleg] getBroker should go before beforeMaterialization()
- // releaseBroker() should go after afterMaterialization()
- // because getMaterializingBroker() should return not null for them
- PersistenceBroker materializingBroker = getBroker();
-
beforeMaterialization();
- realSubject = materializingBroker.getObjectByIdentity(id);
+ realSubject = getBroker().getObjectByIdentity(id);
if (realSubject == null)
{
@@ -348,13 +343,4 @@
{
this.brokerKey = brokerKey;
}
-
- /**
- * This method is for use in MaterializationListeners.
- * It allow to use the same broker that was used during the materialization.
- */
- public PersistenceBroker getMaterializingBroker()
- {
- return broker;
- }
}
1.1 db-ojb/src/java/org/apache/ojb/broker/accesslayer/CollectionProxyListener.java
Index: CollectionProxyListener.java
===================================================================
package org.apache.ojb.broker.accesslayer;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache ObjectRelationalBridge" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache ObjectRelationalBridge", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/**
* This is a callback interface that allows interaction with the
* loading process of the CollectionProxy
* The OTM layer implements this interface to
* provide a delayed registration mechanism for ColelctionProxies.
* @author Oleg Nitz
* @version $Id: CollectionProxyListener.java,v 1.1 2003/07/27 16:18:15 olegnitz Exp $
*/
public interface CollectionProxyListener
{
/**
* this callback is invoked after a CollectionProxy is loaded
* @param colProxy the CollectionProxy
*/
public void loaded(CollectionProxy colProxy);
}
1.24 +121 -19 db-ojb/src/java/org/apache/ojb/otm/core/ConcreteEditingContext.java
Index: ConcreteEditingContext.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/core/ConcreteEditingContext.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- ConcreteEditingContext.java 25 Jul 2003 22:49:08 -0000 1.23
+++ ConcreteEditingContext.java 27 Jul 2003 16:18:16 -0000 1.24
@@ -79,6 +79,8 @@
import org.apache.ojb.broker.PBKey;
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.VirtualProxy;
+import org.apache.ojb.broker.accesslayer.CollectionProxy;
+import org.apache.ojb.broker.accesslayer.CollectionProxyListener;
import org.apache.ojb.broker.accesslayer.ConnectionManagerIF;
import org.apache.ojb.broker.accesslayer.IndirectionHandler;
import org.apache.ojb.broker.accesslayer.MaterializationListener;
@@ -123,6 +125,7 @@
private PersistenceBroker _pb;
private HashMap _original;
private HashMap _checkpointed;
+ private HashMap _colProxyListeners;
//////////////////////////////////////////
// Constructor
@@ -240,7 +243,7 @@
if (origObj != null)
{
- _original.put(oid, getFields(origObj, false));
+ _original.put(oid, getFields(origObj, false, true));
}
}
_objects.put(oid, entry);
@@ -348,7 +351,7 @@
// I think it make sense for efficiency
_pb.serviceObjectCache().cache(oid, object);
- _original.put(oid, getFields(object, false));
+ _original.put(oid, getFields(object, false, true));
// replace the proxy object with the real one
entry.object = object;
@@ -381,13 +384,14 @@
*/
public void commit() throws TransactionAbortedException
{
- checkpointInternal();
+ checkpointInternal(true);
releaseLocksAndClear();
}
private void releaseLocksAndClear()
{
releaseLocks();
+ removeMaterializationListener();
_objects.clear();
_order.clear();
_original.clear();
@@ -404,13 +408,13 @@
*/
public void checkpoint() throws TransactionAbortedException
{
- checkpointInternal();
+ checkpointInternal(false);
_checkpointed = new HashMap();
for (Iterator iterator = _order.iterator(); iterator.hasNext();)
{
Identity oid = (Identity) iterator.next();
ContextEntry entry = (ContextEntry) _objects.get(oid);
- _checkpointed.put(oid, getFields(entry.object, false));
+ _checkpointed.put(oid, getFields(entry.object, false, true));
}
}
@@ -419,13 +423,16 @@
* Writes all changes in this context into the persistent store.
*
*/
- private void checkpointInternal() throws TransactionAbortedException
+ private void checkpointInternal(boolean isCommit)
+ throws TransactionAbortedException
{
if (_order.size() == 0)
{
return;
}
+ removeCollectionProxyListeners();
+
ConnectionManagerIF connMan = _pb.serviceConnectionManager();
boolean saveBatchMode = connMan.isBatchMode();
Swizzling swizzlingStrategy = _tx.getKit().getSwizzlingStrategy();
@@ -474,7 +481,7 @@
if (!state.needsDelete())
{
Object[][] origFields = (Object[][]) _checkpointed.get(oid);
- Object[][] newFields = getFields(entry.object, true);
+ Object[][] newFields = getFields(entry.object, true, !isCommit);
if (origFields == null)
{
@@ -510,10 +517,6 @@
}
}
}
- else
- {
- entry.handler.removeListener(this);
- }
}
countNewObjects = newObjects.size();
if (countNewObjects > 0)
@@ -662,6 +665,32 @@
return null;
}
}
+
+ private void removeMaterializationListener()
+ {
+ for (Iterator it = _order.iterator(); it.hasNext();)
+ {
+ Identity oid = (Identity) it.next();
+ ContextEntry entry = (ContextEntry) _objects.get(oid);
+ if (entry.handler != null)
+ {
+ entry.handler.removeListener(this);
+ }
+ }
+ }
+
+ private void removeCollectionProxyListeners()
+ {
+ if (_colProxyListeners != null)
+ {
+ for (Iterator it = _colProxyListeners.keySet().iterator(); it.hasNext();)
+ {
+ CollectionProxyListener listener = (CollectionProxyListener) it.next();
+ CollectionProxy colProxy = (CollectionProxy) _colProxyListeners.get(listener);
+ colProxy.removeListener(listener);
+ }
+ }
+ }
/**
* Read lock all objects reachable via 1:N and N:1 relations
@@ -699,25 +728,35 @@
// 1:N relations
Iterator collections = mif.getCollectionDescriptors().iterator();
- CollectionDescriptor collectionDescriptor;
+ CollectionDescriptor cds;
Object col;
Iterator colIterator;
+ PersistentField f;
+ Class type;
while (collections.hasNext())
{
- collectionDescriptor = (CollectionDescriptor) collections.next();
- if (onlyDependants && !collectionDescriptor.getOtmDependent())
+ cds = (CollectionDescriptor) collections.next();
+ f = cds.getPersistentField();
+ type = f.getType();
+ if (onlyDependants && !cds.getOtmDependent())
{
continue;
}
- col = collectionDescriptor.getPersistentField().get(object);
+ col = f.get(object);
if (col != null)
{
- if (col instanceof Collection)
+ if ((col instanceof CollectionProxy)
+ && !((CollectionProxy) col).isLoaded())
+ {
+ continue;
+ }
+
+ if (Collection.class.isAssignableFrom(type))
{
colIterator = ((Collection) col).iterator();
}
- else if (col.getClass().isArray())
+ else if (type.isArray())
{
colIterator = new ArrayIterator(col);
}
@@ -735,7 +774,7 @@
if (_objects.get(relOid) == null)
{
insertInternal(relOid, relObj, LockType.READ_LOCK, false,
- collectionDescriptor.getOtmDependent());
+ cds.getOtmDependent());
}
}
}
@@ -796,6 +835,7 @@
}
/**
+ * @param addListeners Whether to add CollectionProxy listeners
* @return four arrays of field values:
* 1) The class, simple fields, identities of references
* 2) collections of identities
@@ -804,7 +844,7 @@
* if "withObjects" parameter is "false", then returns nulls
* in places of 3) and 4)
*/
- private Object[][] getFields(Object obj, boolean withObjects)
+ private Object[][] getFields(Object obj, boolean withObjects, boolean addListeners)
{
ClassDescriptor mif = _pb.getClassDescriptor(obj.getClass());
FieldDescriptor[] fieldDescs = mif.getFieldDescriptions();
@@ -856,6 +896,25 @@
PersistentField f = cds.getPersistentField();
Class type = f.getType();
Object col = f.get(obj);
+
+ if ((col != null) && (col instanceof CollectionProxy)
+ && !((CollectionProxy) col).isLoaded())
+ {
+ if (addListeners)
+ {
+ OTMCollectionProxyListener listener =
+ new OTMCollectionProxyListener(cds, collections, count);
+
+ ((CollectionProxy) col).addListener(listener);
+ if (_colProxyListeners == null)
+ {
+ _colProxyListeners = new HashMap();
+ }
+ _colProxyListeners.put(listener, col);
+ }
+ continue;
+ }
+
if (col != null)
{
ArrayList list = new ArrayList();
@@ -1338,4 +1397,47 @@
}
}
+ private class OTMCollectionProxyListener
+ implements CollectionProxyListener
+ {
+
+ private final CollectionDescriptor _cds;
+ private final ArrayList[] _collections;
+ private final int _index;
+
+ OTMCollectionProxyListener(CollectionDescriptor cds,
+ ArrayList[] collections, int index)
+ {
+ _cds = cds;
+ _collections = collections;
+ _index = index;
+ }
+
+ public void loaded(CollectionProxy colProxy)
+ {
+ ArrayList list = new ArrayList();
+
+ _collections[_index] = list;
+
+ for (Iterator it = colProxy.iterator(); it.hasNext(); )
+ {
+ Object relObj = it.next();
+ Identity relOid = new Identity(relObj, _pb);
+
+ list.add(relOid);
+ if (_objects.get(relOid) == null)
+ {
+ try
+ {
+ insertInternal(relOid, relObj, LockType.READ_LOCK, false,
+ _cds.getOtmDependent());
+ }
+ catch (LockingException ex)
+ {
+ throw new LockingPassthruException(ex);
+ }
+ }
+ }
+ }
+ }
}
1.14 +76 -0 db-ojb/src/test/org/apache/ojb/otm/OtmExamples.java
Index: OtmExamples.java
===================================================================
RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/otm/OtmExamples.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- OtmExamples.java 28 Jun 2003 12:48:52 -0000 1.13
+++ OtmExamples.java 27 Jul 2003 16:18:16 -0000 1.14
@@ -6,8 +6,10 @@
import org.apache.ojb.broker.Article;
import org.apache.ojb.broker.InterfaceArticle;
import org.apache.ojb.broker.ProductGroup;
+import org.apache.ojb.broker.ProductGroupWithCollectionProxy;
import org.apache.ojb.broker.Identity;
import org.apache.ojb.broker.PersistenceBrokerFactory;
+import org.apache.ojb.broker.accesslayer.CollectionProxy;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.QueryFactory;
@@ -128,6 +130,80 @@
tx.begin();
example = (Article) _conn.getObjectByIdentity(oid);
_conn.deletePersistent(example);
+ tx.commit();
+ }
+ catch (Throwable ex)
+ {
+ ex.printStackTrace();
+ tx.rollback();
+ }
+ }
+ catch (Throwable ex)
+ {
+ try
+ {
+ if (tx != null && tx.isInProgress())
+ {
+ tx.rollback();
+ }
+ }
+ catch (Exception ex2)
+ {
+ }
+ throw ex;
+ }
+ }
+
+ public void testCollectionProxy() throws Throwable
+ {
+ Transaction tx = null;
+
+ //perform transaction
+ try
+ {
+ tx = _kit.getTransaction(_conn);
+ tx.begin();
+
+ ProductGroupWithCollectionProxy pg = new ProductGroupWithCollectionProxy();
+ pg.setId(77777);
+ pg.setName("1");
+ _conn.makePersistent(pg);
+
+ tx.commit();
+
+ Identity oid = _conn.getIdentity(pg);
+
+ // get from the database
+ tx = _kit.getTransaction(_conn);
+ tx.begin();
+ _conn.invalidate(oid);
+ pg = (ProductGroupWithCollectionProxy) _conn.getObjectByIdentity(oid);
+ assertTrue("CollectionProxy isn't loaded",
+ !((CollectionProxy) pg.getAllArticlesInGroup()).isLoaded());
+ Article article = Article.createInstance();
+ article.setArticleId(77777);
+ article.setProductGroup(pg);
+ article.setStock(333);
+ article.setArticleName("333");
+ pg.getAllArticlesInGroup().add(article);
+ _conn.makePersistent(article);
+ tx.commit();
+
+ // get from the database
+ tx = _kit.getTransaction(_conn);
+ tx.begin();
+ _conn.invalidate(oid);
+ pg = (ProductGroupWithCollectionProxy) _conn.getObjectByIdentity(oid);
+ assertEquals("CollectionProxy size", 1, pg.getAllArticlesInGroup().size());
+ tx.commit();
+
+ try
+ {
+ tx = _kit.getTransaction(_conn);
+ tx.begin();
+ pg = (ProductGroupWithCollectionProxy) _conn.getObjectByIdentity(oid);
+ _conn.deletePersistent(pg.getAllArticlesInGroup().get(0));
+ _conn.deletePersistent(pg);
tx.commit();
}
catch (Throwable ex)
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org