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 ar...@apache.org on 2006/07/15 16:20:27 UTC
svn commit: r422231 [1/4] - in /db/ojb/trunk/src/java/org/apache/ojb/broker:
./ accesslayer/ accesslayer/sql/ cache/ core/ locking/ metadata/
metadata/fieldaccess/
Author: arminw
Date: Sat Jul 15 07:20:25 2006
New Revision: 422231
URL: http://svn.apache.org/viewvc?rev=422231&view=rev
Log:
merge trunk with 1.0.x
Modified:
db/ojb/trunk/src/java/org/apache/ojb/broker/ContainerHelper.java
db/ojb/trunk/src/java/org/apache/ojb/broker/Identity.java
db/ojb/trunk/src/java/org/apache/ojb/broker/IdentityFactory.java
db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/SqlBasedReportQueryRsIterator.java
db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlUpdateStatement.java
db/ojb/trunk/src/java/org/apache/ojb/broker/cache/MaterializationCache.java
db/ojb/trunk/src/java/org/apache/ojb/broker/cache/SessionCacheImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java
db/ojb/trunk/src/java/org/apache/ojb/broker/core/IdentityFactoryImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerAbstractImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryDefaultImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerHandle.java
db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java
db/ojb/trunk/src/java/org/apache/ojb/broker/core/ValueContainer.java
db/ojb/trunk/src/java/org/apache/ojb/broker/locking/IsolationLevels.java
db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockIsolation.java
db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockIsolationManager.java
db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockManager.java
db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockManagerCommonsImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockManagerInMemoryImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockManagerRemoteImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockManagerServlet.java
db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/ClassDescriptor.java
db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/CollectionDescriptor.java
db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/fieldaccess/AnonymousPersistentField.java
db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentField.java
db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldAutoProxyImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldBase.java
db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldDirectImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldDynaBeanImpl.java
db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/fieldaccess/PersistentFieldIntrospectorImpl.java
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/ContainerHelper.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/ContainerHelper.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/ContainerHelper.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/ContainerHelper.java Sat Jul 15 07:20:25 2006
@@ -47,6 +47,7 @@
import org.apache.ojb.broker.cache.SessionCache;
import org.apache.ojb.broker.core.IdentityFactoryImpl;
import org.apache.ojb.broker.core.PBPoolConfiguration;
+import org.apache.ojb.broker.core.PersistenceBrokerAbstractImpl;
import org.apache.ojb.broker.core.PersistenceBrokerFactoryDefaultImpl;
import org.apache.ojb.broker.core.PersistenceBrokerFactoryIF;
import org.apache.ojb.broker.core.PersistenceBrokerImpl;
@@ -62,6 +63,8 @@
import org.apache.ojb.broker.core.proxy.ProxyFactoryJDKImpl;
import org.apache.ojb.broker.core.proxy.SetProxy;
import org.apache.ojb.broker.core.proxy.SetProxyDefaultImpl;
+import org.apache.ojb.broker.lob.LobHelper;
+import org.apache.ojb.broker.lob.LobHelperImpl;
import org.apache.ojb.broker.locking.LockManager;
import org.apache.ojb.broker.locking.LockManagerInMemoryImpl;
import org.apache.ojb.broker.locking.LockManagerRemoteImpl;
@@ -117,11 +120,17 @@
MetadataManager.class.getName() + ".usingSerializedRepository");
_translationMap.put("serializedRepositoryPath",
MetadataManager.class.getName() + ".serializedRepositoryPath");
+ _translationMap.put("RepositoryPersistorClass",
+ MetadataManager.class.getName() + ".repositoryPersistorClass");
_translationMap.put("PersistenceBrokerFactoryClass",
PersistenceBrokerFactoryIF.class.getName() + ".class");
_translationMap.put("PersistenceBrokerClass",
PersistenceBroker.class.getName() + ".class");
+ _translationMap.put("TxCheck",
+ PersistenceBrokerAbstractImpl.class.getName() + ".txCheck");
+ _translationMap.put("BrokerLeakDetection",
+ PersistenceBrokerImpl.class.getName() + ".brokerLeakDetection");
_translationMap.put("maxActive",
PBPoolConfiguration.class.getName() + ".maxActive");
@@ -166,6 +175,10 @@
IdentityFactory.class.getName() + ".class");
_translationMap.put("ObjectFactoryClass",
ObjectFactory.class.getName() + ".class");
+ _translationMap.put("LobHelperClass",
+ LobHelper.class.getName() + ".class");
+ _translationMap.put("LobAutoRefresh",
+ LobHelper.class.getName() + ".lobAutoRefresh");
_translationMap.put("SessionCacheClass",
SessionCache.class.getName() + ".class");
@@ -194,8 +207,6 @@
ImplementationExt.class.getName() + ".impliciteWriteLocks");
_translationMap.put("Ordering",
ImplementationExt.class.getName() + ".ordering");
- _translationMap.put("NoteUserOrder",
- ImplementationExt.class.getName() + ".noteUserOrder");
_translationMap.put("LockManagerOdmgClass",
org.apache.ojb.odmg.locking.LockManager.class.getName() + ".class");
_translationMap.put("DListClass",
@@ -244,6 +255,9 @@
container.ensureImplementationClass(ConnectionFactory.class, ConnectionFactoryPooledImpl.class);
container.ensureImplementationClass(ConnectionManagerIF.class, ConnectionManagerImpl.class);
container.ensureImplementationClass(IdentityFactory.class, IdentityFactoryImpl.class);
+ container.ensureImplementationClass(LobHelper.class, LobHelperImpl.class);
+ // todo: is this needed, register a a normal class?
+ //container.ensureImplementationClass(RepositoryPersistor.class, RepositoryPersistor.class);
container.ensureImplementationClass(Implementation.class, ImplementationImpl.class);
container.ensureImplementationClass(JdbcAccess.class, JdbcAccessImpl.class);
container.ensureImplementationClass(LockManager.class, LockManagerInMemoryImpl.class);
@@ -313,6 +327,7 @@
if (url == null)
{
+ log.info("No success load resource '" + path +"', try to load OJB's properties as file");
url = (new File(path)).toURL();
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/Identity.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/Identity.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/Identity.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/Identity.java Sat Jul 15 07:20:25 2006
@@ -49,11 +49,15 @@
* <li>
* an array of all primary key value objects
* </li>
+ * <li>
+ * a flag which indicates whether this is a <em>transient Identity</em>
+ * (identity of a non-persistent, "new" object) or a <em>persistent Identity</em> (identity object
+ * of a persistent, "already written to datastore" object).
+ * </li>
* </ul>
* <p>
- * If in the metadata of an persistent capable object class the attribute <em>autoincrement</em>
- * is set true, new primary key values will be automatic assigned to the given object passed as
- * constructor argument.
+ * To create <code>Identity</code> objects it's strongly recommended to use the {@link IdentityFactory}, because
+ * in future releases of OJB the <code>Identity</code> constructors will be no longer reachable or forbidden to use.
* </p>
* <p>
* NOTE: An <em>Identity</em> object must be unique
@@ -62,34 +66,37 @@
* </p>
* @see org.apache.ojb.broker.IdentityFactory
- * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
* @version $Id$
*/
public class Identity implements Serializable
{
- static final long serialVersionUID = 3182285550574178710L;
+ /** Unique id for serialization purposes. */
+ private static final long serialVersionUID = 3182285550574178710L;
+
+ private static final int IS_TRANSIENT = 3;
+ private static final int IS_PERMANENT = 17;
/**
- * used for hashCode calculation.
+ * Used for hashCode calculation.
*/
private static final int iConstant = 37;
/**
- * the top-level Class of the identified object<br>
- * ie: an Interface
+ * The top-level Class of the identified object, ie. an interface.
*/
private Class m_objectsTopLevelClass;
/**
- * the real Class of the identified object<br>
- * ie: the implementing Class
+ * The real Class of the identified object, ie. the implementing class.
*/
private Class m_objectsRealClass = null;
/**
- * The ordered list of primary key values maintaining the objects identity in the underlying RDBMS
+ * The ordered list of primary key values maintaining the objects identity in the underlying RDBMS.
*/
private Object[] m_pkValues;
+ private final int isTransient;
+
/*
the hashcode of different objects has to be unique across different
JVM and have to be the same for the same object in different JVM.
@@ -102,26 +109,39 @@
private transient Integer m_hashCode;
/**
- * creates an Identity from a class and the objects primary key values.
+ * For internal use only!
+ */
+ protected Identity()
+ {
+ isTransient = IS_TRANSIENT;
+ }
+
+ /**
+ * For internal use only!. Creates an em from a class and the objects primary key values.
* used for the definition of proxies.
+ * <br/>
+ * OJB user have to use {@link IdentityFactory} to create object identity.
+ *
*
* @param realClass the concrete class of the object, or null if not known.
* @param topLevel the highest persistence-capable class or
* interface (in the inheritance hierarchy) that the identified object is an instance of
* @param pkValues (unique across the extents !)
+ * @param isTransient If <em>true</em>
*/
- public Identity(final Class realClass, final Class topLevel, final Object[] pkValues)
+ public Identity(final Class realClass, final Class topLevel, final Object[] pkValues, final boolean isTransient)
{
m_objectsTopLevelClass = topLevel;
m_objectsRealClass = realClass;
m_pkValues = pkValues;
+ this.isTransient = isTransient ? IS_TRANSIENT : IS_PERMANENT;
checkForPrimaryKeys(null);
}
/**
- * Creates an identity object for the given class descriptor by reading the field values from
- * the given map.
- *
+ * For internal use only! Creates an identity object for the given class
+ * descriptor by reading the field values from the given map.
+ *
* @param targetClass The target class descriptor
* @param topLevel The highest persistence-capable class
* @param fields The fields to use for building the identity
@@ -137,18 +157,54 @@
}
m_objectsTopLevelClass = topLevel;
- m_objectsRealClass = targetClass.getClassOfObject();
+ m_objectsRealClass = targetClass.isMappedToTable() ? targetClass.getClassOfObject() : null;
m_pkValues = values;
+ this.isTransient = IS_PERMANENT;
+ checkForPrimaryKeys(null);
+ }
+
+ /**
+ * For internal use only! Creates an Identity from a class and the objects primary key values.
+ * used for the definition of proxies.
+ * <br/>
+ * OJB user have to use {@link IdentityFactory} to create object identity.
+ *
+ * @param realClass the concrete class of the object, or null if not known.
+ * @param topLevel the highest persistence-capable class or
+ * interface (in the inheritance hierarchy) that the identified object is an instance of
+ * @param pkValues (unique across the extents !)
+ */
+ public Identity(final Class realClass, final Class topLevel, final Object[] pkValues)
+ {
+ m_objectsTopLevelClass = topLevel;
+ m_objectsRealClass = realClass;
+ m_pkValues = pkValues;
+ this.isTransient = IS_PERMANENT;
checkForPrimaryKeys(null);
}
+ /**
+ * Constructor for internal use. Use {@link IdentityFactory} to create an object identity.
+ *
+ * @param objectToIdentitify The object for which to create the identity
+ * @param targetBroker The persistence broker
+ */
public Identity(final Object objectToIdentitify, final PersistenceBroker targetBroker)
{
+ this.isTransient = IS_PERMANENT;
init(objectToIdentitify, targetBroker, null);
}
+ /**
+ * Constructor for internal use. Use {@link IdentityFactory} to create an object identity.
+ *
+ * @param objectToIdentitify The object for which to create the identity
+ * @param targetBroker The persistence broker
+ * @param cld The class descriptor
+ */
public Identity(final Object objectToIdentitify, final PersistenceBroker targetBroker, final ClassDescriptor cld)
{
+ this.isTransient = IS_PERMANENT;
init(objectToIdentitify, targetBroker, cld);
}
@@ -157,36 +213,38 @@
if(objectToIdentify == null) throw new OJBRuntimeException("Can't create Identity for 'null'-object");
try
{
- //IndirectionHandler handler = ProxyHelper.getIndirectionHandler(objectToIdentify);
final IndirectionHandler handler = targetBroker.getConfiguration().getOjb().getProxyFactory().getIndirectionHandler(objectToIdentify);
- if (handler != null)
- {
- final Identity sourceOID = handler.getIdentity();
- m_objectsTopLevelClass = sourceOID.m_objectsTopLevelClass;
- m_objectsRealClass = sourceOID.m_objectsRealClass;
- m_pkValues = sourceOID.m_pkValues;
- }
- else
+ synchronized(objectToIdentify)
{
- if (cld == null)
+ if (handler != null)
{
- cld = targetBroker.getClassDescriptor(objectToIdentify.getClass());
+ final Identity sourceOID = handler.getIdentity();
+ m_objectsTopLevelClass = sourceOID.m_objectsTopLevelClass;
+ m_objectsRealClass = sourceOID.m_objectsRealClass;
+ m_pkValues = sourceOID.m_pkValues;
}
-
- // identities must be unique accross extents !
- m_objectsTopLevelClass = targetBroker.getTopLevelClass(objectToIdentify.getClass());
- m_objectsRealClass = objectToIdentify.getClass();
-
- // BRJ: definitely do NOT convertToSql
- // conversion is done when binding the sql-statement
- final BrokerHelper helper = targetBroker.serviceBrokerHelper();
- final ValueContainer[] pkValues = helper.getKeyValues(cld, objectToIdentify, false);
- if (pkValues == null || pkValues.length == 0)
+ else
{
- throw createException("Can't extract PK value fields", objectToIdentify, null);
+ if (cld == null)
+ {
+ cld = targetBroker.getClassDescriptor(objectToIdentify.getClass());
+ }
+
+ // identities must be unique accross extents !
+ m_objectsTopLevelClass = targetBroker.getTopLevelClass(objectToIdentify.getClass());
+ m_objectsRealClass = objectToIdentify.getClass();
+
+ // BRJ: definitely do NOT convertToSql
+ // conversion is done when binding the sql-statement
+ final BrokerHelper helper = targetBroker.serviceBrokerHelper();
+ final ValueContainer[] pkValues = helper.getValuesForObject(cld.getPkFields(), objectToIdentify, false, true);
+ if (pkValues == null || pkValues.length == 0)
+ {
+ throw createException("Can't extract PK value fields", objectToIdentify, null);
+ }
+ m_pkValues = helper.extractValueArray(pkValues);
}
- m_pkValues = helper.extractValueArray(pkValues);
}
checkForPrimaryKeys(objectToIdentify);
@@ -202,8 +260,11 @@
}
/**
- * Factory method that returns an Identity object from the given
- * byte array - see {@link #serialize}.
+ * Factory method that returns an Identity object created from a serializated representation.
+ *
+ * @param anArray The serialized representation
+ * @return The identity
+ * @see {@link #serialize}.
* @deprecated
*/
public static Identity fromByteArray(final byte[] anArray) throws PersistenceBrokerException
@@ -213,10 +274,10 @@
// a GZIPInputStream and then deserialize by reading from the ObjectInputStream
try
{
- ByteArrayInputStream bais = new ByteArrayInputStream(anArray);
- GZIPInputStream gis = new GZIPInputStream(bais);
- ObjectInputStream ois = new ObjectInputStream(gis);
- Identity result = (Identity) ois.readObject();
+ final ByteArrayInputStream bais = new ByteArrayInputStream(anArray);
+ final GZIPInputStream gis = new GZIPInputStream(bais);
+ final ObjectInputStream ois = new ObjectInputStream(gis);
+ final Identity result = (Identity) ois.readObject();
ois.close();
gis.close();
bais.close();
@@ -229,11 +290,21 @@
}
/**
- * Return the top-level class of the real
- * subject (means class name of a base class,
+ * Determines whether the identity is transient.
+ *
+ * @return <code>true</code> if the identity is transient
+ */
+ public boolean isTransient()
+ {
+ return isTransient == IS_TRANSIENT;
+ }
+
+ /**
+ * Returns the top-level class of the real subject (base class,
* base interface denoted in the repository or
- * objects real class name if none top-level was found)
+ * objects real class if no top-level was found).
*
+ * @return The top level class
*/
public Class getObjectsTopLevelClass()
{
@@ -241,7 +312,9 @@
}
/**
- * Return the "real" Class of the real subject
+ * Return the "real" class of the real subject.
+ *
+ * @return The real class
*/
public Class getObjectsRealClass()
{
@@ -249,7 +322,9 @@
}
/**
- * Set the objects real class
+ * Set the real class of the subject.
+ *
+ * @param objectsRealClass The real class
*/
public void setObjectsRealClass(final Class objectsRealClass)
{
@@ -257,8 +332,11 @@
}
/**
- * Return a serialized Identity as byte[].
+ * Return the serialized form of this Identity.
+ *
+ * @return The serialized representation
* @see #fromByteArray
+ * @deprecated
*/
public byte[] serialize() throws PersistenceBrokerException
{
@@ -299,6 +377,7 @@
buf.append(m_pkValues[i]);
}
buf.append("}");
+ if(isTransient == IS_TRANSIENT) buf.append("-transient");
m_stringRepresentation = buf.toString();
}
return m_stringRepresentation;
@@ -308,8 +387,9 @@
/**
* OJB can handle only classes that declare at least one primary key attribute,
* this method checks this condition.
- * @exception ClassNotPersistenceCapableException thrown if no primary key is
- * specified for the objects class
+ *
+ * @param realObject The real object to check
+ * @throws ClassNotPersistenceCapableException thrown if no primary key is specified for the objects class
*/
protected void checkForPrimaryKeys(final Object realObject) throws ClassNotPersistenceCapableException
{
@@ -324,8 +404,9 @@
}
/**
- * return the list of Primary Key Values of the real subject
- * @return Object[]
+ * Returns the primary key values of the real subject.
+ *
+ * @return The pk values
*/
public Object[] getPrimaryKeyValues()
{
@@ -333,8 +414,7 @@
}
/**
- * Compare this Identity object to any other object. This comparison is delegated
- * to the super-class.
+ * {@inheritDoc}
*/
public boolean equals(final Object obj)
{
@@ -344,7 +424,7 @@
if (obj instanceof Identity)
{
final Identity id = (Identity) obj;
- result = m_objectsTopLevelClass.equals(id.m_objectsTopLevelClass);
+ result = m_objectsTopLevelClass.equals(id.m_objectsTopLevelClass) && isTransient == id.isTransient;
if(result)
{
final Object[] otherPkValues = id.m_pkValues;
@@ -369,12 +449,7 @@
}
/**
- * Calculate a hashcode for this Identity. The Hashcode should be
- * equal for Identities where Identity.equals() returns true. Therefore
- * all primary key values that return a hashcode depending on its content
- * (this is assumed for String and Number) are taken into account. Additionally
- * the hashCode() of the top-level class name of this Identity is representing
- * is taken into account.
+ * {@inheritDoc}
*/
public int hashCode()
{
@@ -385,7 +460,7 @@
*/
if(m_hashCode == null)
{
- int iTotal = 17;
+ int iTotal = isTransient;
Object obj;
for (int i = 0; i < m_pkValues.length; i++)
{
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/IdentityFactory.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/IdentityFactory.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/IdentityFactory.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/IdentityFactory.java Sat Jul 15 07:20:25 2006
@@ -1,5 +1,20 @@
package org.apache.ojb.broker;
+/* Copyright 2002-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import org.apache.ojb.broker.metadata.ClassDescriptor;
/**
@@ -14,14 +29,13 @@
* </ul>
* NOTE:
* <br/>
- * It is possible to assign new created objects
- * with a valid UID before they are written to database - more info see {@link org.apache.ojb.broker.Identity}.
- * This should be
- * used with care, because not all {@link org.apache.ojb.broker.util.sequence.SequenceManager}
- * implementations return the "real" UID value before the object was stored (e.g. when database based
- * Identity columns are used, a temporary placeholder is returned).
+ * It is possible to create transient {@link Identity} objects for transient,
+ * "new created" persistence capable objects. But keep in mind that this transient
+ * {@link Identity} object is only valid till the persistence capable object was written
+ * to datastore. After this the {@link Identity} have to be renewed by calling
+ * <code>IdentityFactory.buildIdentity(...)</code> again (then the transient Identity
+ * will be replaced by the persistent Identity).
*
- * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
* @version $Id$
*/
public interface IdentityFactory
@@ -30,8 +44,8 @@
* Build a unique {@link org.apache.ojb.broker.Identity} for the given
* persistence capable object.
*
- * @param obj The object to build the {@link Identity} for.
- * @return The a new created <em>Identity</em> object.
+ * @param obj The object to build the {@link Identity} for
+ * @return The new <em>Identity</em> object
*/
Identity buildIdentity(Object obj);
@@ -39,10 +53,9 @@
* Build a unique {@link org.apache.ojb.broker.Identity} for the given
* persistence capable object.
*
- * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the
- * object.
- * @param obj The object to build the {@link Identity} for.
- * @return The a new created <em>Identity</em> object.
+ * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the object
+ * @param obj The object to build the {@link Identity} for
+ * @return The new <em>Identity</em> object.
*/
Identity buildIdentity(ClassDescriptor cld, Object obj);
@@ -51,27 +64,32 @@
* for the given primary key values (composite PK's) of a
* persistence capable object.
*
- * @param realClass The class of the associated object.
- * @param topLevelClass The top-level class of the associated object.
- * @param pkFieldName The field names of the PK fields.
- * @param pkValues The PK values.
- * @return The a new created <em>Identity</em> object.
+ * @param realClass The class of the associated object
+ * @param topLevelClass The top-level class of the associated object
+ * @param pkFieldName The field names of the PK fields
+ * @param pkValues The PK values
+ * @return The new <em>Identity</em> object
*/
Identity buildIdentity(Class realClass, Class topLevelClass, String[] pkFieldName, Object[] pkValues);
/**
- * Convenience method for
- * {@link #buildIdentity(java.lang.Class, java.lang.Class, java.lang.String[], java.lang.Object[])}
+ * Convenience shortcut method for
+ * {@link #buildIdentity(java.lang.Class, java.lang.Class, java.lang.String[], java.lang.Object[])}.
+ *
+ * @param realClass The class of the associated object
+ * @param pkFieldName The field names of the PK fields
+ * @param pkValues The PK values
+ * @return The new <em>Identity</em> object
*/
- Identity buildIdentity(Class realClass, String[] fieldName, Object[] pkValues);
+ Identity buildIdentity(Class realClass, String[] pkFieldName, Object[] pkValues);
/**
* Convenience method for persistent objects with single primary key.
* NOTE: Do not use for objects with composed PK!
*
- * @param realClass The class of the associated object.
- * @param pkValue The PK value.
- * @return The a new created <em>Identity</em> object.
+ * @param realClass The class of the associated object
+ * @param pkValue The PK value
+ * @return The new <em>Identity</em> object
* @see #buildIdentity(java.lang.Class, java.lang.String[], java.lang.Object[])
*/
Identity buildIdentity(Class realClass, Object pkValue);
@@ -79,12 +97,13 @@
/**
* Create a new {@link Identity} object based on given arguments - NOTE: There
* will be no check to resolve the order of the PK values. This method expect
- * the correct order.
+ * the correct order based on the declaration of the {@link org.apache.ojb.broker.metadata.FieldDescriptor}
+ * in the mapping file.
*
- * @param realClass The class of the associated object.
- * @param topLevelClass The top-level class of the associated object.
- * @param pkValues The PK values.
- * @return The a new created <em>Identity</em> object.
+ * @param realClass The class of the associated object
+ * @param topLevelClass The top-level class of the associated object
+ * @param pkValues The PK values
+ * @return The new <em>Identity</em> object
*/
Identity buildIdentity(Class realClass, Class topLevelClass, Object[] pkValues);
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/SqlBasedReportQueryRsIterator.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/SqlBasedReportQueryRsIterator.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/SqlBasedReportQueryRsIterator.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/SqlBasedReportQueryRsIterator.java Sat Jul 15 07:20:25 2006
@@ -21,11 +21,11 @@
import org.apache.ojb.broker.PersistenceBrokerException;
import org.apache.ojb.broker.PersistenceBrokerInternal;
import org.apache.ojb.broker.metadata.JdbcTypesHelper;
+import org.apache.ojb.broker.metadata.JdbcType;
/**
* ReporQueryRsIterator based on SQL-Statement
*
- * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
* @version $Id$
*/
public class SqlBasedReportQueryRsIterator extends SqlBasedRsIterator
@@ -65,8 +65,9 @@
try
{
int jdbcType = rsMetaData.getColumnType(i + 1);
- Object item = JdbcTypesHelper.getObjectFromColumn(getRsAndStmt().m_rs, new Integer(jdbcType), i + 1);
- result[i] = item;
+ JdbcType type = JdbcTypesHelper.getJdbcTypeByTypesIndex(new Integer(jdbcType));
+ //Object item = JdbcTypesHelper.getObjectFromColumn(getRsAndStmt().m_rs, new Integer(jdbcType), i + 1);
+ result[i] = type.getObjectFromColumn(getRsAndStmt().m_rs, i + 1);
}
catch (SQLException e)
{
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlUpdateStatement.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlUpdateStatement.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlUpdateStatement.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/SqlUpdateStatement.java Sat Jul 15 07:20:25 2006
@@ -23,7 +23,6 @@
/**
* Model an UPDATE Statement
*
- * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
* @version $Id$
*/
public class SqlUpdateStatement extends SqlPkStatement
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/cache/MaterializationCache.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/cache/MaterializationCache.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/cache/MaterializationCache.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/cache/MaterializationCache.java Sat Jul 15 07:20:25 2006
@@ -29,14 +29,13 @@
* materialized objects to higher level caches this class act as a temporary storage
* for unmaterialized (new read or refreshed) objects.
*
- * @author <a href="mailto:arminw@apache.org">Armin Waibel</a>
* @version $Id$
*/
class MaterializationCache
{
private static Logger log = LoggerFactory.getLogger(MaterializationCache.class);
- private static final int INITIAL_CAPACITY = 75;
+ private static final int INITIAL_CAPACITY = 100;
private HashMap objectBuffer;
private boolean enabledReadCache;
@@ -51,6 +50,17 @@
}
/**
+ * Returns <em>true</em> if the cache is enabled.
+ *
+ * @return The cache state.
+ * @see #enableMaterializationCache()
+ */
+ public boolean isEnabledMaterializationCache()
+ {
+ return enabledReadCache;
+ }
+
+ /**
* For internal use only! Helper method to guarantee that only full materialized objects
* will be pushed to the application cache regardless if an local PB transaction
* is running or not. When a complex object is materialized there will be
@@ -71,6 +81,8 @@
}
/**
+ * Disable the cache.
+ *
* @see #enableMaterializationCache()
*/
public void disableMaterializationCache()
@@ -101,6 +113,12 @@
}
}
+ /**
+ * Lookup an object from cache.
+ *
+ * @param oid The {@link org.apache.ojb.broker.Identity} object.
+ * @return The cached {@link ObjectEntry} or <em>null</em>.
+ */
public ObjectEntry lookup(Identity oid)
{
ObjectEntry result = null;
@@ -111,16 +129,29 @@
return result;
}
+ /**
+ * Evict the specified object from cache.
+ *
+ * @param oid The {@link org.apache.ojb.broker.Identity} object.
+ */
public void evict(Identity oid)
{
objectBuffer.remove(oid);
}
+ /**
+ * Evict the cache.
+ */
public void evictAll()
{
objectBuffer.clear();
}
+ /**
+ * Evict all objects of the specified (top-level) class.
+ *
+ * @param topLevelClass
+ */
public void evict(Class topLevelClass)
{
Iterator it = objectBuffer.keySet().iterator();
@@ -135,6 +166,12 @@
}
}
+ /**
+ * Put the object to cache - if the cache is enabled.
+ *
+ * @param entry The object to cache.
+ * @see #enableMaterializationCache()
+ */
public void cache(SessionEntry entry)
{
if(enabledReadCache)
@@ -143,6 +180,10 @@
}
}
+ /**
+ * Push all cached objects to the session cache, if the
+ * specified cache level is higher then {@link SessionCache.LEVEL_MATERIALIZE}.
+ */
private void pushObjects()
{
Iterator it = objectBuffer.values().iterator();
@@ -158,16 +199,14 @@
}
}
+ /**
+ * Reset the whole cache.
+ */
public void reset()
{
if(log.isDebugEnabled()) log.debug("Reset materialization cache");
invokeCounter = 0;
enabledReadCache = false;
objectBuffer.clear();
- }
-
- public boolean isEnabledMaterializationCache()
- {
- return enabledReadCache;
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/cache/SessionCacheImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/cache/SessionCacheImpl.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/cache/SessionCacheImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/cache/SessionCacheImpl.java Sat Jul 15 07:20:25 2006
@@ -312,6 +312,9 @@
}
finally
{
+ /*
+ todo: Shall we really evict the session cache on commit of tx or shall we make this configurable?
+ */
evictAll(LEVEL_SESSION);
}
}
@@ -373,8 +376,7 @@
/**
- * @author <a href="mailto:arminw@apache.org">Armin Waibel</a>
- * @version $Id$
+ * This class wraps the cached object.
*/
static final class SessionEntryImpl implements SessionEntry
{
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java Sat Jul 15 07:20:25 2006
@@ -34,6 +34,7 @@
import org.apache.ojb.broker.TransactionAbortedException;
import org.apache.ojb.broker.TransactionInProgressException;
import org.apache.ojb.broker.TransactionNotInProgressException;
+import org.apache.ojb.broker.lob.LobHelper;
import org.apache.ojb.broker.accesslayer.CollectionCreationContext;
import org.apache.ojb.broker.accesslayer.ConnectionManagerIF;
import org.apache.ojb.broker.accesslayer.JdbcAccess;
@@ -154,9 +155,6 @@
return getBroker().getReferenceBroker();
}
- /**
- * @see org.apache.ojb.broker.PersistenceBrokerInternal#refreshRelationships(java.lang.Object, org.apache.ojb.broker.metadata.ClassDescriptor)
- */
public void refreshRelationships(Object obj, ClassDescriptor cld)
{
getBroker().refreshRelationships(obj, cld);
@@ -363,6 +361,11 @@
public IdentityFactory serviceIdentity()
{
return getBroker().serviceIdentity();
+ }
+
+ public LobHelper serviceLobHelper()
+ {
+ return getBroker().serviceLobHelper();
}
public void fireBrokerEvent(PersistenceBrokerEvent event)
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/IdentityFactoryImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/IdentityFactoryImpl.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/IdentityFactoryImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/IdentityFactoryImpl.java Sat Jul 15 07:20:25 2006
@@ -1,47 +1,163 @@
package org.apache.ojb.broker.core;
+/* Copyright 2002-2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Map;
+
+import org.apache.commons.collections.map.ReferenceIdentityMap;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.ojb.broker.Identity;
import org.apache.ojb.broker.IdentityFactory;
-import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.PBStateEvent;
+import org.apache.ojb.broker.PBStateListener;
import org.apache.ojb.broker.PersistenceBrokerException;
+import org.apache.ojb.broker.PersistenceBrokerInternal;
+import org.apache.ojb.broker.core.proxy.IndirectionHandler;
import org.apache.ojb.broker.metadata.ClassDescriptor;
+import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
import org.apache.ojb.broker.metadata.FieldDescriptor;
+import org.apache.ojb.broker.util.BrokerHelper;
+import org.apache.ojb.broker.util.sequence.SequenceManager;
+import org.apache.ojb.broker.util.sequence.SequenceManagerTransientImpl;
/**
- * @see org.apache.ojb.broker.IdentityFactory
- *
- * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
+ * Implementation class for {@link org.apache.ojb.broker.IdentityFactory}.
+ *
* @version $Id$
+ * @see org.apache.ojb.broker.IdentityFactory
*/
-public class IdentityFactoryImpl implements IdentityFactory
+public class IdentityFactoryImpl implements IdentityFactory, PBStateListener
{
- private PersistenceBroker broker;
+ private PersistenceBrokerInternal broker;
+ //private final Map persistentIdentityMap;
+ private final Map transientIdentityMap;
+ private final SequenceManager transientSequenceManager;
- public IdentityFactoryImpl(PersistenceBroker broker)
+ public IdentityFactoryImpl(PersistenceBrokerInternal broker)
{
this.broker = broker;
+ this.transientIdentityMap = new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD, false);
+ /*
+ TODO: Introduce cache for persistent object Identity objects, as long as user can use the direct
+ constructor call of Identity class we can run into problems when an object is stored/deleted/stored in
+ the same PB-tx, because then the PK of the object can change (e.g. when DB identity columns are used)
+ but the cached Identity object will always be the same when the Identity object is requested by the
+ IdentityFactory
+ */
+ //this.persistentIdentityMap = new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD, true);
+ this.transientSequenceManager = new SequenceManagerTransientImpl(broker);
+ broker.addListener(this, true);
}
/**
- * @see org.apache.ojb.broker.IdentityFactory#buildIdentity(java.lang.Object)
+ * This methods creates a new transient (if at least one PK field is 'null') or persistent
+ * (if the PK fields are populated) {@link org.apache.ojb.broker.Identity} instance. If the specified object
+ * is transient and former call for the same object returns already a transient Identity, the same transient
+ * Identity object will be returned.
*/
- public Identity buildIdentity(Object obj)
+ protected Identity createTransientOrRealIdentity(ClassDescriptor cld, final Object objOrProxy)
{
- return new Identity(obj, broker);
- }
+ if(objOrProxy == null) throw new NullPointerException("Can't create Identity for 'null'-object");
+ Identity result = null;
+ Class topLevelClass = null;
+ Class realClass = null;
+ Object[] pks = null;
+ try
+ {
+ final IndirectionHandler handler = broker.getProxyFactory().getIndirectionHandler(objOrProxy);
+ if(handler != null)
+ {
+ result = handler.getIdentity();
+ }
+ else
+ {
+ //result = (Identity) persistentIdentityMap.get(objOrProxy);
+ if(result == null)
+ {
+ // now we are sure that the specified object is not a proxy
+ realClass = objOrProxy.getClass();
+ topLevelClass = broker.getTopLevelClass(objOrProxy.getClass());
+ if(cld == null)
+ {
+ cld = broker.getClassDescriptor(objOrProxy.getClass());
+ }
+ BrokerHelper helper = broker.serviceBrokerHelper();
- /**
- * @see org.apache.ojb.broker.IdentityFactory#buildIdentity(java.lang.Object)
+ FieldDescriptor[] fields = cld.getPkFields();
+ pks = new Object[fields.length];
+ FieldDescriptor fld;
+ for(int i = 0; i < fields.length; i++)
+ {
+ fld = fields[i];
+ /*
+ we check all PK fields for 'null'-values
*/
- public Identity buildIdentity(ClassDescriptor cld, Object obj)
+ Object value = fld.getPersistentField().get(objOrProxy);
+ if(helper.representsNull(fld, value))
+ {
+ result = (Identity) transientIdentityMap.get(objOrProxy);
+ if(result == null)
+ {
+ pks[i] = transientSequenceManager.getUniqueValue(fld);
+ result = new Identity(realClass, topLevelClass, pks, true);
+ //if(activeTx) objectToIdentityMap.put(objOrProxy, result);
+ transientIdentityMap.put(objOrProxy, result);
+ }
+ break;
+ }
+ else
+ {
+ pks[i] = value;
+ }
+ }
+ if(result == null)
+ {
+ result = new Identity(realClass, topLevelClass, pks, false);
+ //persistentIdentityMap.put(objOrProxy, result);
+ }
+ }
+ }
+ }
+ catch(ClassNotPersistenceCapableException e)
+ {
+ throw e;
+ }
+ catch(Exception e)
+ {
+ throw createException(e, "Can not init Identity for given object.", objOrProxy, topLevelClass, realClass, pks);
+ }
+ return result;
+ }
+
+ /** @see org.apache.ojb.broker.IdentityFactory#buildIdentity(Object) */
+ public Identity buildIdentity(final Object obj)
{
- return new Identity(obj, broker, cld);
+ return createTransientOrRealIdentity(broker.getClassDescriptor(broker.getProxyFactory().getRealClass(obj)), obj);
}
- /**
- * @see org.apache.ojb.broker.IdentityFactory#buildIdentity(java.lang.Class, java.lang.Class, java.lang.String[], java.lang.Object[])
- */
- public Identity buildIdentity(Class realClass, Class topLevelClass, String[] pkFieldNames, Object[] pkValues)
+ /** @see org.apache.ojb.broker.IdentityFactory#buildIdentity(Object) */
+ public Identity buildIdentity(final ClassDescriptor cld, final Object obj)
+ {
+ return createTransientOrRealIdentity(cld, obj);
+ }
+
+ /** @see org.apache.ojb.broker.IdentityFactory#buildIdentity(Class, Class, String[], Object[]) */
+ public Identity buildIdentity(final Class realClass, final Class topLevelClass, final String[] pkFieldNames, final Object[] pkValues)
{
Object[] orderedPKValues = pkValues;
if(pkValues == null)
@@ -61,29 +177,38 @@
FieldDescriptor[] flds = broker.getClassDescriptor(realClass).getPkFields();
if(!isOrdered(flds, pkFieldNames))
{
- orderedPKValues = reorderPKValues(flds, pkFieldNames, pkValues);
+ orderedPKValues = reorderFieldValues(flds, pkFieldNames, pkValues);
}
}
-
- return buildIdentity(realClass, topLevelClass, orderedPKValues);
+ return new Identity(realClass, topLevelClass, orderedPKValues);
}
- private Object[] reorderPKValues(FieldDescriptor[] flds, String[] pkFieldNames, Object[] pkValues)
+ /**
+ * This method orders the specified field values based on the
+ * specified {@link org.apache.ojb.broker.metadata.FieldDescriptor}.
+ *
+ * @param flds The {@link org.apache.ojb.broker.metadata.FieldDescriptor} array.
+ * @param fieldNames The field names.
+ * @param fieldValues The field values.
+ * @return The ordered field values.
+ */
+ private Object[] reorderFieldValues(final FieldDescriptor[] flds, final String[] fieldNames, final Object[] fieldValues)
{
String fieldName;
- Object[] orderedPKValues = new Object[flds.length];
- for (int i = 0; i < flds.length; i++)
+ Object[] orderedValues = new Object[flds.length];
+ for(int i = 0; i < flds.length; i++)
{
fieldName = flds[i].getPersistentField().getName();
- int realPosition = findFieldName(pkFieldNames, fieldName);
- orderedPKValues[i] = pkValues[realPosition];
+ int realPosition = findIndexForName(fieldNames, fieldName);
+ orderedValues[i] = fieldValues[realPosition];
}
- return orderedPKValues;
+ return orderedValues;
}
- private int findFieldName(String[] fieldNames, String searchName)
+ /** Find the index of the specified name in field name array. */
+ private int findIndexForName(String[] fieldNames, String searchName)
{
- for (int i = 0; i < fieldNames.length; i++)
+ for(int i = 0; i < fieldNames.length; i++)
{
if(searchName.equals(fieldNames[i]))
{
@@ -94,9 +219,7 @@
"' in given array of field names");
}
- /**
- * Checks length and compare order of field names with declared PK fields in metadata.
- */
+ /** Checks length and compare order of field names with declared PK fields in metadata. */
private boolean isOrdered(FieldDescriptor[] flds, String[] pkFieldNames)
{
if((flds.length > 1 && pkFieldNames == null) || flds.length != pkFieldNames.length)
@@ -106,7 +229,7 @@
(pkFieldNames != null ? pkFieldNames.length : 0));
}
boolean result = true;
- for (int i = 0; i < flds.length; i++)
+ for(int i = 0; i < flds.length; i++)
{
FieldDescriptor fld = flds[i];
result = result && fld.getPersistentField().getName().equals(pkFieldNames[i]);
@@ -114,27 +237,105 @@
return result;
}
- /**
- * @see org.apache.ojb.broker.IdentityFactory#buildIdentity(java.lang.Class, java.lang.String[], java.lang.Object[])
- */
- public Identity buildIdentity(Class realClass, String[] pkFieldNames, Object[] pkValues)
+ /** @see org.apache.ojb.broker.IdentityFactory#buildIdentity(Class, String[], Object[]) */
+ public Identity buildIdentity(final Class realClass, final String[] pkFieldNames, final Object[] pkValues)
{
return buildIdentity(realClass, broker.getTopLevelClass(realClass), pkFieldNames, pkValues);
}
- /**
- * @see org.apache.ojb.broker.IdentityFactory#buildIdentity(java.lang.Class, java.lang.String[], java.lang.Object[])
- */
- public Identity buildIdentity(Class realClass, Class topLevelClass, Object[] pkValues)
+ /** @see org.apache.ojb.broker.IdentityFactory#buildIdentity(Class, String[], Object[]) */
+ public Identity buildIdentity(final Class realClass, final Class topLevelClass, final Object[] pkValues)
{
return new Identity(realClass, topLevelClass, pkValues);
}
-
+
+ /** @see org.apache.ojb.broker.IdentityFactory#buildIdentity(Class, Object) */
+ public Identity buildIdentity(final Class realClass, final Object pkValue)
+ {
+ return buildIdentity(realClass, (String[]) null, new Object[]{pkValue});
+ }
+
/**
- * @see org.apache.ojb.broker.IdentityFactory#buildIdentity(java.lang.Class, java.lang.Object)
+ * Helper method which supports creation of proper error messages.
+ *
+ * @param ex An exception to include or <em>null</em>.
+ * @param message The error message or <em>null</em>.
+ * @param objectToIdentify The current used object or <em>null</em>.
+ * @param topLevelClass The object top-level class or <em>null</em>.
+ * @param realClass The object real class or <em>null</em>.
+ * @param pks The associated PK values of the object or <em>null</em>.
+ * @return The generated exception.
*/
- public Identity buildIdentity(Class realClass, Object pkValue)
+ private PersistenceBrokerException createException(final Exception ex, String message, final Object objectToIdentify, Class topLevelClass, Class realClass, Object[] pks)
+ {
+ final String eol = SystemUtils.LINE_SEPARATOR;
+ StringBuffer msg = new StringBuffer();
+ if(message == null)
+ {
+ msg.append("Unexpected error: ");
+ }
+ else
+ {
+ msg.append(message).append(" :");
+ }
+ if(topLevelClass != null) msg.append(eol).append("objectTopLevelClass=").append(topLevelClass.getName());
+ if(realClass != null) msg.append(eol).append("objectRealClass=").append(realClass.getName());
+ if(pks != null) msg.append(eol).append("pkValues=").append(ArrayUtils.toString(pks));
+ if(objectToIdentify != null) msg.append(eol).append("object to identify: ").append(objectToIdentify);
+ if(ex != null)
+ {
+ // add causing stack trace
+ Throwable rootCause = ExceptionUtils.getRootCause(ex);
+ if(rootCause != null)
+ {
+ msg.append(eol).append("The root stack trace is --> ");
+ String rootStack = ExceptionUtils.getStackTrace(rootCause);
+ msg.append(eol).append(rootStack);
+ }
+
+ return new PersistenceBrokerException(msg.toString(), ex);
+ }
+ else
+ {
+ return new PersistenceBrokerException(msg.toString());
+ }
+ }
+
+ //===================================================================
+ // PBStateListener interface
+ //===================================================================
+ public void afterBegin(PBStateEvent event)
+ {
+ }
+
+ public void afterCommit(PBStateEvent event)
+ {
+ if(transientIdentityMap.size() > 0) transientIdentityMap.clear();
+ }
+
+ public void afterRollback(PBStateEvent event)
+ {
+ if(transientIdentityMap.size() > 0) transientIdentityMap.clear();
+ }
+
+ public void beforeClose(PBStateEvent event)
+ {
+ if(transientIdentityMap.size() > 0) transientIdentityMap.clear();
+ }
+
+ public void beforeRollback(PBStateEvent event)
+ {
+ }
+
+ public void afterOpen(PBStateEvent event)
+ {
+ }
+
+ public void beforeBegin(PBStateEvent event)
+ {
+ }
+
+ public void beforeCommit(PBStateEvent event)
{
- return buildIdentity(realClass, (String[]) null, new Object[]{pkValue});
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerAbstractImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerAbstractImpl.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerAbstractImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerAbstractImpl.java Sat Jul 15 07:20:25 2006
@@ -1,6 +1,6 @@
package org.apache.ojb.broker.core;
-/* Copyright 2003-2004 The Apache Software Foundation
+/* Copyright 2003-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,9 @@
* limitations under the License.
*/
+import java.util.Collections;
+import java.util.List;
+
import org.apache.ojb.broker.PBLifeCycleEvent;
import org.apache.ojb.broker.PBLifeCycleListener;
import org.apache.ojb.broker.PBListener;
@@ -23,6 +26,7 @@
import org.apache.ojb.broker.PersistenceBrokerEvent;
import org.apache.ojb.broker.PersistenceBrokerException;
import org.apache.ojb.broker.PersistenceBrokerInternal;
+import org.apache.ojb.broker.util.IdentityArrayList;
import org.apache.ojb.broker.util.logging.LoggerFactory;
/**
@@ -33,41 +37,42 @@
* @see org.apache.ojb.broker.PBLifeCycleListener
* @see org.apache.ojb.broker.PersistenceBrokerAware
* @see org.apache.ojb.broker.PBStateListener
- *
- * @author Created by Charles on 12-Sep-2002 08:04:47
- * @author Armin Waibel
* @version $Id$
*/
public abstract class PersistenceBrokerAbstractImpl implements PersistenceBrokerInternal
{
- private static final PBStateListener[] NO_STATE_LISTENERS = new PBStateListener[0];
- private static final PBLifeCycleListener[] NO_LIFECYCLE_LISTENERS = new PBLifeCycleListener[0];
-
+ /** Returns <em>true</em> if PB-transaction check is enabled. */
private boolean txCheck;
+ /*
+ PB instances are single threaded used, but we use synchronization here to
+ avoid problems with the JVM Finalizer thread - more details see issue
+ OJB-114 in JIRA
+ */
+
+ /**
+ * List containing all permanent {@link org.apache.ojb.broker.PBStateListener}
+ * instances.
+ */
+ private final List permanentStateListeners = Collections.synchronizedList(new IdentityArrayList());
+
+ /**
+ * List containing all temporary {@link org.apache.ojb.broker.PBStateListener}
+ * instances.
+ */
+ private final List temporaryStateListeners = Collections.synchronizedList(new IdentityArrayList());
+
/**
- * Array containing all permanent {@link org.apache.ojb.broker.PBStateListener}
+ * List containing all permanent {@link org.apache.ojb.broker.PBLifeCycleListener}
* instances.
*/
- private PBStateListener[] permanentStateListeners = NO_STATE_LISTENERS;
+ private List permanentLifeCycleListeners = Collections.synchronizedList(new IdentityArrayList(100));
- /**
- * Array containing all temporary {@link org.apache.ojb.broker.PBStateListener}
- * instances.
- */
- private PBStateListener[] temporaryStateListeners = NO_STATE_LISTENERS;
-
- /**
- * Array containing all permanent {@link org.apache.ojb.broker.PBLifeCycleListener}
- * instances.
- */
- private PBLifeCycleListener[] permanentLifeCycleListeners = NO_LIFECYCLE_LISTENERS;
-
- /**
- * Array containing all temporary {@link org.apache.ojb.broker.PBLifeCycleListener}
- * instances.
- */
- private PBLifeCycleListener[] temporaryLifeCycleListeners = NO_LIFECYCLE_LISTENERS;
+ /**
+ * List containing all temporary {@link org.apache.ojb.broker.PBLifeCycleListener}
+ * instances.
+ */
+ private List temporaryLifeCycleListeners = Collections.synchronizedList(new IdentityArrayList(100));
/**
* Returns <em>true</em> if the development checks are enabled.
@@ -97,169 +102,99 @@
this.txCheck = txCheck;
}
- /**
- * @see org.apache.ojb.broker.PersistenceBroker#addListener(PBListener listener)
- */
+ /** @see org.apache.ojb.broker.PersistenceBroker#addListener(PBListener listener) */
public void addListener(PBListener listener) throws PersistenceBrokerException
{
addListener(listener, false);
}
- /**
- * @see org.apache.ojb.broker.PersistenceBroker#addListener(PBListener listener, boolean permanent)
- */
+ /** @see org.apache.ojb.broker.PersistenceBroker#addListener(PBListener listener, boolean permanent) */
public void addListener(PBListener listener, boolean permanent) throws PersistenceBrokerException
{
- if (listener instanceof PBStateListener)
+ if(listener instanceof PBStateListener)
+ {
+ if(permanent)
+ {
+ if(!permanentStateListeners.contains(listener))
+ {
+ permanentStateListeners.add(listener);
+ }
+ }
+ else
+ {
+ if(!temporaryStateListeners.contains(listener))
+ {
+ temporaryStateListeners.add(listener);
+ }
+ }
+ }
+
+ if(listener instanceof PBLifeCycleListener)
{
- if (permanent)
- {
- if (!contains(permanentStateListeners, listener))
- {
- PBStateListener[] newListeners = new PBStateListener[permanentStateListeners.length + 1];
- System.arraycopy(permanentStateListeners, 0, newListeners, 0, permanentStateListeners.length);
- newListeners[newListeners.length - 1] = (PBStateListener) listener;
- permanentStateListeners = newListeners;
- }
- }
- else
- {
- if (!contains(temporaryStateListeners, listener))
- {
- PBStateListener[] newListeners = new PBStateListener[temporaryStateListeners.length + 1];
- System.arraycopy(temporaryStateListeners, 0, newListeners, 0, temporaryStateListeners.length);
- newListeners[newListeners.length - 1] = (PBStateListener) listener;
- temporaryStateListeners = newListeners;
- }
- }
- }
-
- if (listener instanceof PBLifeCycleListener)
- {
- if (permanent)
- {
- if (!contains(permanentLifeCycleListeners, listener))
- {
- PBLifeCycleListener[] newListeners = new PBLifeCycleListener[permanentLifeCycleListeners.length + 1];
- System.arraycopy(permanentLifeCycleListeners, 0, newListeners, 0, permanentLifeCycleListeners.length);
- newListeners[newListeners.length - 1] = (PBLifeCycleListener) listener;
- permanentLifeCycleListeners = newListeners;
- }
- }
- else
- {
- if (!contains(temporaryLifeCycleListeners, listener))
- {
- PBLifeCycleListener[] newListeners = new PBLifeCycleListener[temporaryLifeCycleListeners.length + 1];
- System.arraycopy(temporaryLifeCycleListeners, 0, newListeners, 0, temporaryLifeCycleListeners.length);
- newListeners[newListeners.length - 1] = (PBLifeCycleListener) listener;
- temporaryLifeCycleListeners = newListeners;
- }
- }
+ if(permanent)
+ {
+ if(!permanentLifeCycleListeners.contains(listener))
+ {
+ permanentLifeCycleListeners.add(listener);
+ }
+ }
+ else
+ {
+ if(!temporaryLifeCycleListeners.contains(listener))
+ {
+ temporaryLifeCycleListeners.add(listener);
+ }
+ }
}
}
- /**
- * @see org.apache.ojb.broker.PersistenceBroker#removeListener(PBListener listener)
- */
+ /** @see org.apache.ojb.broker.PersistenceBroker#removeListener(PBListener listener) */
public void removeListener(PBListener listener) throws PersistenceBrokerException
{
- if (listener instanceof PBStateListener)
+ if(listener instanceof PBStateListener)
{
- if (contains(permanentStateListeners, listener))
- {
- PBStateListener[] newListeners = new PBStateListener[permanentStateListeners.length - 1];
- int pos = 0;
-
- for (int i = 0; i < permanentStateListeners.length; i++)
- {
- if (permanentStateListeners[i] != listener)
- {
- newListeners[pos++] = permanentStateListeners[i];
- }
- }
- permanentStateListeners = newListeners;
- }
-
- if (contains(temporaryStateListeners, listener))
- {
- PBStateListener[] newListeners = new PBStateListener[temporaryStateListeners.length - 1];
- int pos = 0;
-
- for (int i = 0; i < temporaryStateListeners.length; i++)
- {
- if (temporaryStateListeners[i] != listener)
- {
- newListeners[pos++] = temporaryStateListeners[i];
- }
- }
- temporaryStateListeners = newListeners;
- }
- }
-
- if (listener instanceof PBLifeCycleListener)
- {
- if (contains(permanentLifeCycleListeners, listener))
- {
- PBLifeCycleListener[] newListeners = new PBLifeCycleListener[permanentLifeCycleListeners.length - 1];
- int pos = 0;
-
- for (int i = 0; i < permanentLifeCycleListeners.length; i++)
- {
- if (permanentLifeCycleListeners[i] != listener)
- {
- newListeners[pos++] = permanentLifeCycleListeners[i];
- }
- }
- permanentLifeCycleListeners = newListeners;
- }
-
- if (contains(temporaryLifeCycleListeners, listener))
- {
- PBLifeCycleListener[] newListeners = new PBLifeCycleListener[temporaryLifeCycleListeners.length - 1];
- int pos = 0;
-
- for (int i = 0; i < temporaryLifeCycleListeners.length; i++)
- {
- if (temporaryLifeCycleListeners[i] != listener)
- {
- newListeners[pos++] = temporaryLifeCycleListeners[i];
- }
- }
- temporaryLifeCycleListeners = newListeners;
- }
- }
- }
-
- protected boolean contains(PBListener[] listeners, PBListener listener)
- {
- for (int i = listeners.length - 1; i >= 0; i--)
- {
- if (listeners[i] == listener) return true;
- }
+ permanentStateListeners.remove(listener);
+ temporaryStateListeners.remove(listener);
+ }
- return false;
- }
+ if(listener instanceof PBLifeCycleListener)
+ {
+ permanentLifeCycleListeners.remove(listener);
+ temporaryLifeCycleListeners.remove(listener);
+ }
+ }
- /**
- * @see org.apache.ojb.broker.PersistenceBroker#removeAllListeners(boolean)
- */
+ /** @see org.apache.ojb.broker.PersistenceBroker#removeAllListeners(boolean) */
public void removeAllListeners(boolean permanent) throws PersistenceBrokerException
{
- if (permanent)
+ if(permanent)
{
// remove permanent listeners as well
- permanentStateListeners = NO_STATE_LISTENERS;
- permanentLifeCycleListeners = NO_LIFECYCLE_LISTENERS;
+ permanentStateListeners.clear();
+ // this could be huge, thus simply replace instance
+ if(permanentLifeCycleListeners.size() > 10000)
+ {
+ permanentLifeCycleListeners = Collections.synchronizedList(new IdentityArrayList(100));
+ }
+ else
+ {
+ permanentLifeCycleListeners.clear();
+ }
}
- temporaryStateListeners = NO_STATE_LISTENERS;
- temporaryLifeCycleListeners = NO_LIFECYCLE_LISTENERS;
+ temporaryStateListeners.clear();
+ // this could be huge, thus simply replace instance
+ if(temporaryLifeCycleListeners.size() > 10000)
+ {
+ temporaryLifeCycleListeners = Collections.synchronizedList(new IdentityArrayList(100));
+ }
+ else
+ {
+ temporaryLifeCycleListeners.clear();
+ }
}
- /**
- * @see org.apache.ojb.broker.PersistenceBroker#removeAllListeners()
- */
+ /** @see org.apache.ojb.broker.PersistenceBroker#removeAllListeners() */
public void removeAllListeners() throws PersistenceBrokerException
{
removeAllListeners(false);
@@ -267,68 +202,71 @@
public void fireBrokerEvent(PersistenceBrokerEvent event)
{
- if (event instanceof PBLifeCycleEvent)
- {
- fireBrokerEvent((PBLifeCycleEvent) event);
- }
- else if (event instanceof PBStateEvent)
- {
- fireBrokerEvent((PBStateEvent) event);
- }
- else
- {
- LoggerFactory.getDefaultLogger().error(
- PersistenceBrokerAbstractImpl.class.getName() + ": Unkown PersistenceBrokerEvent was fired " + event);
- }
+ if(event instanceof PBLifeCycleEvent)
+ {
+ fireBrokerEvent((PBLifeCycleEvent) event);
+ }
+ else if(event instanceof PBStateEvent)
+ {
+ fireBrokerEvent((PBStateEvent) event);
+ }
+ else
+ {
+ LoggerFactory.getDefaultLogger().error(
+ PersistenceBrokerAbstractImpl.class.getName() + ": Unkown PersistenceBrokerEvent was fired " + event);
+ }
}
- public void fireBrokerEvent(PBLifeCycleEvent event)
+ public void fireBrokerEvent(PBLifeCycleEvent event)
{
- if (event.getPersitenceBrokerAware() != null)
+ if(event.getPersitenceBrokerAware() != null)
{
// first we do the persistent object callback
performCallBack(event);
}
- // copy array references so they can't change in the middle of iteration
- PBLifeCycleListener[] permanent = permanentLifeCycleListeners;
- PBLifeCycleListener[] temporary = temporaryLifeCycleListeners;
-
// now we notify the listeners
- for (int i = permanent.length - 1; i >= 0; i--)
+ synchronized(permanentLifeCycleListeners)
{
- notifiyObjectLifeCycleListener(permanent[i], event);
+ for(int i = permanentLifeCycleListeners.size() - 1; i >= 0; i--)
+ {
+ notifiyObjectLifeCycleListener((PBLifeCycleListener) permanentLifeCycleListeners.get(i), event);
+ }
}
- for (int i = temporary.length - 1; i >= 0; i--)
+ synchronized(temporaryLifeCycleListeners)
{
- notifiyObjectLifeCycleListener(temporary[i], event);
+ for(int i = temporaryLifeCycleListeners.size() - 1; i >= 0; i--)
+ {
+ notifiyObjectLifeCycleListener((PBLifeCycleListener) temporaryLifeCycleListeners.get(i), event);
+ }
}
}
- public void fireBrokerEvent(PBStateEvent event)
+ public void fireBrokerEvent(PBStateEvent event)
{
- // copy array references so they can't change in the middle of iteration
- PBStateListener[] permanent = permanentStateListeners;
- PBStateListener[] temporary = temporaryStateListeners;
-
- // now we notify the listeners
- for (int i = permanent.length - 1; i >= 0; i--)
- {
- notifiyStateListener(permanent[i], event);
- }
+ synchronized(permanentStateListeners)
+ {
+ for(int i = permanentStateListeners.size() - 1; i >= 0; i--)
+ {
+ notifiyStateListener((PBStateListener) permanentStateListeners.get(i), event);
+ }
+ }
- for (int i = temporary.length - 1; i >= 0; i--)
- {
- notifiyStateListener(temporary[i], event);
- }
+ synchronized(temporaryStateListeners)
+ {
+ for(int i = temporaryStateListeners.size() - 1; i >= 0; i--)
+ {
+ notifiyStateListener((PBStateListener) temporaryStateListeners.get(i), event);
+ }
+ }
}
private void performCallBack(PBLifeCycleEvent event)
{
// Check for null
- if (event.getPersitenceBrokerAware() == null) return;
- switch (event.getEventType().typeId())
+ if(event.getPersitenceBrokerAware() == null) return;
+ switch(event.getEventType().typeId())
{
case PBLifeCycleEvent.TYPE_AFTER_LOOKUP:
event.getPersitenceBrokerAware().afterLookup(event.getTriggeringBroker());
@@ -356,7 +294,7 @@
private void notifiyStateListener(PBStateListener listener, PBStateEvent stateEvent)
{
- switch (stateEvent.getEventType().typeId())
+ switch(stateEvent.getEventType().typeId())
{
case PBStateEvent.KEY_BEFORE_COMMIT:
listener.beforeCommit(stateEvent);
@@ -387,7 +325,7 @@
private void notifiyObjectLifeCycleListener(PBLifeCycleListener listener, PBLifeCycleEvent lifeEvent)
{
- switch (lifeEvent.getEventType().typeId())
+ switch(lifeEvent.getEventType().typeId())
{
case PBLifeCycleEvent.TYPE_AFTER_LOOKUP:
listener.afterLookup(lifeEvent);
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryDefaultImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryDefaultImpl.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryDefaultImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerFactoryDefaultImpl.java Sat Jul 15 07:20:25 2006
@@ -1,6 +1,6 @@
package org.apache.ojb.broker.core;
-/* Copyright 2003-2004 The Apache Software Foundation
+/* Copyright 2003-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerHandle.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerHandle.java?rev=422231&r1=422230&r2=422231&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerHandle.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerHandle.java Sat Jul 15 07:20:25 2006
@@ -1,8 +1,5 @@
package org.apache.ojb.broker.core;
-import org.apache.ojb.broker.PersistenceBrokerException;
-import org.apache.ojb.broker.PersistenceBrokerInternal;
-
/* Copyright 2003-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,8 +14,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+import org.apache.ojb.broker.PersistenceBrokerException;
+import org.apache.ojb.broker.PersistenceBrokerInternal;
+
+/**
+ * A handle wraps a real (pooled) PB instance.
+ * In addition this class does set itself as current
+ * broker instance in {@link PersistenceBrokerThreadMapping#setCurrentPersistenceBroker}
+ * when instantiate and unset on broker close call.
+ *
+ * @version $Id$
+ */
public class PersistenceBrokerHandle extends DelegatingPersistenceBroker
{
+ private Boolean closed;
+
/**
* Constructor for the handle, set itself in
* {@link PersistenceBrokerThreadMapping#setCurrentPersistenceBroker}
@@ -31,7 +42,11 @@
public boolean isClosed()
{
- return super.isClosed();
+ if(closed == null)
+ {
+ closed = super.isClosed() ? Boolean.TRUE : Boolean.FALSE;
+ }
+ return closed.booleanValue();
}
public boolean isInTransaction() throws PersistenceBrokerException
@@ -50,6 +65,7 @@
try
{
PersistenceBrokerThreadMapping.unsetCurrentPersistenceBroker(getPBKey(), this);
+ closed = Boolean.TRUE;
super.close();
}
finally
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org