arminw 2005/09/27 17:30:23
Modified: src/java/org/apache/ojb/broker/core/proxy Tag:
OJB_1_0_RELEASE AbstractIndirectionHandler.java
Log:
use inner class to handle temporary used PB instances to avoid concurrency
issues
Revision Changes Path
No revision
No revision
1.1.2.4 +88 -74
db-ojb/src/java/org/apache/ojb/broker/core/proxy/AbstractIndirectionHandler.java
Index: AbstractIndirectionHandler.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/proxy/AbstractIndirectionHandler.java,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -u -r1.1.2.3 -r1.1.2.4
--- AbstractIndirectionHandler.java 26 Sep 2005 23:57:44 -0000 1.1.2.3
+++ AbstractIndirectionHandler.java 28 Sep 2005 00:30:23 -0000 1.1.2.4
@@ -30,15 +30,13 @@
/**
* Abstract implementation for the indirection handler used by ojb's proxies.
- *
+ *
* @version $Id$
*/
public abstract class AbstractIndirectionHandler implements
IndirectionHandler
{
static final long serialVersionUID = -1993879565033755826L;
-
- /** Reference to the used PersistenceBroker */
- private transient PersistenceBrokerInternal _broker = null;
+
/** The key for acquiring the above broker */
private PBKey _brokerKey;
/** The real subject which this is hidden by the proxy */
@@ -51,7 +49,7 @@
/**
* Creates a new indirection handler for the indicated object.
- *
+ *
* @param brokerKey
* The key of the persistence broker
* @param id
@@ -65,7 +63,7 @@
/**
* Returns the identity of the subject.
- *
+ *
* @return The identity
*/
public Identity getIdentity()
@@ -75,7 +73,7 @@
/**
* Sets the identity of the subject of this indirection handler.
- *
+ *
* @param identity
*/
protected void setIdentity(Identity identity)
@@ -86,7 +84,7 @@
/**
* Returns the key of the persistence broker used by this indirection
* handler.
- *
+ *
* @return The broker key
*/
public PBKey getBrokerKey()
@@ -96,7 +94,7 @@
/**
* Sets the key of the persistence broker used by this indirection
handler.
- *
+ *
* @param brokerKey
* The broker key
*/
@@ -107,7 +105,7 @@
/**
* Adds a materialization listener.
- *
+ *
* @param listener
* The listener to add
*/
@@ -126,7 +124,7 @@
/**
* Removes a materialization listener.
- *
+ *
* @param listener
* The listener to remove
*/
@@ -179,65 +177,48 @@
}
}
- /**
- * Gets the persistence broker used by this indirection handler. If no
PBKey
- * is available a runtime exception will be thrown.
- *
- * @return a PersistenceBroker
- */
- protected synchronized PersistenceBrokerInternal getBroker() throws
PBFactoryException
- {
- PersistenceBrokerInternal broker;
-
- if (getBrokerKey() == null)
- {
- /*
- * arminw: if no PBKey is set we throw an exception,
because we
- * don't know which PB (connection) should be used.
- */
- throw new OJBRuntimeException("Can't find associated
PBKey. Need PBKey to obtain a valid"
- + "PersistenceBroker instance from
intern resources.");
- }
- // first try to use the current threaded broker to avoid
blocking
- broker =
PersistenceBrokerThreadMapping.currentPersistenceBroker(getBrokerKey());
- // current broker not found, create a intern new one
- if (broker == null)
- {
- if (_broker == null)
- {
- _broker = (PersistenceBrokerInternal)
PersistenceBrokerFactory.createPersistenceBroker(getBrokerKey());
- }
- broker = _broker;
+ /**
+ * Gets the persistence broker used by this indirection handler.
+ * If no PBKey is available a runtime exception will be thrown.
+ *
+ * @return a PersistenceBroker
+ */
+ protected TemporaryBrokerWrapper getBroker() throws PBFactoryException
+ {
+ PersistenceBrokerInternal broker;
+ boolean needsClose = false;
+
+ if (getBrokerKey() == null)
+ {
+ /*
+ arminw:
+ if no PBKey is set we throw an exception, because we don't
+ know which PB (connection) should be used.
+ */
+ throw new OJBRuntimeException("Can't find associated PBKey. Need
PBKey to obtain a valid" +
+ "PersistenceBroker instance from
intern resources.");
}
- return broker;
- }
-
- /**
- * Release the PersistenceBroker instance currently used.
- */
- protected void releaseBroker()
- {
- /*
- arminw:
- only close broker instance if we get it from PBF, this
- is the case when _broker is not null
- */
- if (_broker != null)
- {
- if(!_broker.isClosed()) _broker.close();
- _broker = null;
- }
- }
+ // first try to use the current threaded broker to avoid blocking
+ broker =
PersistenceBrokerThreadMapping.currentPersistenceBroker(getBrokerKey());
+ // current broker not found, create a intern new one
+ if ((broker == null) || broker.isClosed())
+ {
+ broker = (PersistenceBrokerInternal)
PersistenceBrokerFactory.createPersistenceBroker(getBrokerKey());
+ /** Specifies whether we obtained a fresh broker which we have
to close after we used it */
+ needsClose = true;
+ }
+ return new TemporaryBrokerWrapper(broker, needsClose);
+ }
/**
* [Copied from [EMAIL PROTECTED]
java.lang.reflect.InvocationHandler}]:<br/>
* Processes a method invocation on a proxy instance and returns the
result.
* This method will be invoked on an invocation handler when a method is
* invoked on a proxy instance that it is associated with.
- *
+ *
* @param proxy
* The proxy instance that the method was invoked on
- *
+ *
* @param method
* The <code>Method</code> instance corresponding to the
* interface method invoked on the proxy instance. The
declaring
@@ -245,7 +226,7 @@
* interface that the method was declared in, which may be a
* superinterface of the proxy interface that the proxy class
* inherits the method through.
- *
+ *
* @param args
* An array of objects containing the values of the arguments
* passed in the method invocation on the proxy instance, or
@@ -254,7 +235,7 @@
* appropriate primitive wrapper class, such as
* <code>java.lang.Integer</code> or
* <code>java.lang.Boolean</code>.
- *
+ *
* @return The value to return from the method invocation on the proxy
* instance. If the declared return type of the interface
method is
* a primitive type, then the value returned by this method
must be
@@ -268,7 +249,7 @@
* declared return type as described above, a
* <code>ClassCastException</code> will be thrown by the method
* invocation on the proxy instance.
- *
+ *
* @throws PersistenceBrokerException
* The exception to throw from the method invocation on the
* proxy instance. The exception's type must be assignable
@@ -283,7 +264,7 @@
* [EMAIL PROTECTED]
java.lang.reflect.UndeclaredThrowableException}
* containing the exception that was thrown by this method
will
* be thrown by the method invocation on the proxy instance.
- *
+ *
* @see java.lang.reflect.UndeclaredThrowableException
*/
public Object invoke(Object proxy, Method method, Object[] args)
@@ -352,13 +333,14 @@
// otherwise equals may return false.
if ("equals".equals(methodName) && args[0] != null)
{
+ TemporaryBrokerWrapper tmp = getBroker();
try
{
- args[0] =
getBroker().getProxyFactory().getRealObject(args[0]);
+ args[0] =
tmp.broker.getProxyFactory().getRealObject(args[0]);
}
finally
{
- releaseBroker();
+ tmp.close();
}
}
@@ -385,7 +367,7 @@
/**
* Returns the proxies real subject. The subject will be materialized if
* necessary.
- *
+ *
* @return The subject
*/
public Object getRealSubject() throws PersistenceBrokerException
@@ -412,14 +394,15 @@
/**
* Retrieves the real subject from the underlying RDBMS. Override this
* method if the object is to be materialized in a specific way.
- *
+ *
* @return The real subject of the proxy
*/
protected synchronized Object materializeSubject() throws
PersistenceBrokerException
{
- try
+ TemporaryBrokerWrapper tmp = getBroker();
+ try
{
- Object realSubject =
getBroker().getObjectByIdentity(_id);
+ Object realSubject =
tmp.broker.getObjectByIdentity(_id);
if (realSubject == null)
{
LoggerFactory.getLogger(IndirectionHandler.class).warn(
@@ -431,13 +414,13 @@
throw new PersistenceBrokerException(ex);
} finally
{
- releaseBroker();
+ tmp.close();
}
}
/**
* Determines whether the real subject already has been materialized.
- *
+ *
* @return <code>true</code> if the real subject has already been loaded
*/
public boolean alreadyMaterialized()
@@ -448,10 +431,41 @@
/**
* Generate a simple object that is serializable and placeholder for
* proxies.
- *
+ *
*/
private Object generateSerializableProxy()
{
return new
OJBSerializableProxy(getIdentity().getObjectsRealClass(), this);
}
+
+ //===================================================================
+ // inner class
+ //===================================================================
+ /**
+ * wrapper class for temporary used broker instances.
+ */
+ static final class TemporaryBrokerWrapper
+ {
+ /** Specifies whether we obtained a fresh broker which we have to
close after we used it */
+ boolean needsClose;
+ PersistenceBrokerInternal broker;
+
+ public TemporaryBrokerWrapper(PersistenceBrokerInternal broker,
boolean needsClose)
+ {
+ this.broker = broker;
+ this.needsClose = needsClose;
+ }
+
+ /**
+ * Cleanup the used broker instance, it's mandatory to call
+ * this method after use.
+ */
+ public void close()
+ {
+ if(needsClose)
+ {
+ broker.close();
+ }
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]