IndexOutOfBoundsException in ObjectBuilder [message #518159] |
Wed, 03 March 2010 10:22 |
Ana Oleski Messages: 22 Registered: July 2009 |
Junior Member |
|
|
Hi,
we have a problem with eclipselink 2.0 in a multithreaded context.
ava.lang.IndexOutOfBoundsException: Index: 1, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:572)
at java.util.ArrayList.get(ArrayList.java:347)
at
org.eclipse.persistence.internal.descriptors.ObjectBuilder.extractPrimaryKeyFromRow
(ObjectBuilder.java:1882)
( Full stacktrace below)
After looking at the code, I think that the field primaryKeyClassifications (the arraylist in question) in ObjectBuilder is lazy-instantiated without synchronization and thus not threadsafe.
Our application performs a batchjob on all objects of type Account with a configurable degree of parallelism. Obviously we don't have any problems running it singlethreaded but we prefer the multithreaded version because it is faster.
So I have two questions:
- is it a synchronization bug?
- can I work around it by calling the getPrimaryKeyClassifications for all descriptors at the beginning of the program. What are the disadvantages, if any, of doing so.
Thanx,
Ana
--------
Full stacktrace:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:572)
at java.util.ArrayList.get(ArrayList.java:347)
at
org.eclipse.persistence.internal.descriptors.ObjectBuilder.extractPrimaryKeyFromRow
(ObjectBuilder.java:1882)
at
org.eclipse.persistence.internal.descriptors.ObjectBuilder.extractPrimaryKeyFromExpression
(ObjectBuilder.java:1780)
at
org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.checkCacheForObject
(ExpressionQueryMechanism.java:778)
at org.eclipse.persistence.queries.ReadObjectQuery.checkEarlyReturnImpl
(ReadObjectQuery.java:230)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkEarlyReturn
(ObjectLevelReadQuery.java:684)
at org.eclipse.persistence.queries.DatabaseQuery.execute
(DatabaseQuery.java:619)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute
(ObjectLevelReadQuery.java:958)
at org.eclipse.persistence.queries.ReadObjectQuery.execute
(ReadObjectQuery.java:399)
at
org.eclipse.persistence.internal.sessions.AbstractSession.internalExecuteQuery
(AbstractSession.java:2322)
at
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery
(AbstractSession.java:1225)
at
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery
(AbstractSession.java:1207)
at
org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate
(QueryBasedValueHolder.java:85)
at
org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate
(QueryBasedValueHolder.java:75)
at
org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue
(DatabaseValueHolder.java:83)
at
org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiateImpl
(UnitOfWorkValueHolder.java:161)
at
org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiate
(UnitOfWorkValueHolder.java:230)
at
org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue
(DatabaseValueHolder.java:83)
at
org.eclipse.persistence.internal.indirection.BasicIndirectionPolicy.getRealAttributeValueFromObject
(BasicIndirectionPolicy.java:251)
at
org.eclipse.persistence.mappings.ForeignReferenceMapping.getRealAttributeValueFromAttribute
(ForeignReferenceMapping.java:665)
at
org.eclipse.persistence.mappings.ObjectReferenceMapping.getRealAttributeValueFromAttribute
(ObjectReferenceMapping.java:284)
at
org.eclipse.persistence.mappings.DatabaseMapping.getRealAttributeValueFromObject
(DatabaseMapping.java:623)
at
org.eclipse.persistence.internal.expressions.QueryKeyExpression.valuesFromCollection
(QueryKeyExpression.java:929)
at
org.eclipse.persistence.internal.expressions.QueryKeyExpression.valueFromObject
(QueryKeyExpression.java:879)
at
org.eclipse.persistence.internal.expressions.QueryKeyExpression.valueFromObject
(QueryKeyExpression.java:845)
at
org.eclipse.persistence.internal.expressions.QueryKeyExpression.valueFromObject
(QueryKeyExpression.java:845)
at
org.eclipse.persistence.internal.expressions.RelationExpression.doesConform
(RelationExpression.java:83)
at
org.eclipse.persistence.internal.expressions.LogicalExpression.doesConform
(LogicalExpression.java:47)
at org.eclipse.persistence.expressions.Expression.doesConform
(Expression.java:1298)
at
org.eclipse.persistence.queries.ObjectLevelReadQuery.conformIndividualResult
(ObjectLevelReadQuery.java:835)
at org.eclipse.persistence.queries.ReadAllQuery.conformResult
(ReadAllQuery.java:335)
at
org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork
(ReadAllQuery.java:821)
at
org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery
(ReadAllQuery.java:464)
at
org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery
(ObjectLevelReadQuery.java:997)
at org.eclipse.persistence.queries.DatabaseQuery.execute
(DatabaseQuery.java:675)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute
(ObjectLevelReadQuery.java:958)
at org.eclipse.persistence.queries.ReadAllQuery.execute
(ReadAllQuery.java:432)
at
org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork
(ObjectLevelReadQuery.java:1021)
at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery
(UnitOfWorkImpl.java:2863)
at
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery
(AbstractSession.java:1225)
at
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery
(AbstractSession.java:1207)
at org.eclipse.persistence.descriptors.InterfacePolicy.selectAllObjects
(InterfacePolicy.java:222)
at
org.eclipse.persistence.descriptors.InterfacePolicy.selectAllObjectsUsingMultipleTableSubclassRead
(InterfacePolicy.java:242)
at
org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery
(ReadAllQuery.java:450)
at
org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery
(ObjectLevelReadQuery.java:997)
at org.eclipse.persistence.queries.DatabaseQuery.execute
(DatabaseQuery.java:675)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute
(ObjectLevelReadQuery.java:958)
at org.eclipse.persistence.queries.ReadAllQuery.execute
(ReadAllQuery.java:432)
at
org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork
(ObjectLevelReadQuery.java:1021)
at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery
(UnitOfWorkImpl.java:2863)
at
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery
(AbstractSession.java:1225)
at
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery
(AbstractSession.java:1207)
at
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery
(AbstractSession.java:1167)
at de.jdpe.bof.bes.query.pm.QueryManager.executeQuery
(QueryManager.java:187)
at de.bkm.bes.kontosystem.BoKontosystemQueryManager.gibKontoByVertrag
(BoKontosystemQueryManager.java:2706)
ObjectBuilder.java:
/** The types for the primary key fields, in same order as descriptor's primary key fields. */
protected List<Class> primaryKeyClassifications;
/**
* Extract primary key values from the specified row.
* null is returned if the row does not contain the key.
*/
public Vector extractPrimaryKeyFromRow(AbstractRecord databaseRow, AbstractSession session) {
List primaryKeyFields = this.descriptor.getPrimaryKeyFields();
List primaryKeyClassifications = getPrimaryKeyClassifications();
int size = primaryKeyFields.size();
Vector primaryKeyValues = new NonSynchronizedVector(size);
int numberOfNulls = 0;
// PERF: use index not enumeration
for (int index = 0; index < size; index++) {
DatabaseField field = (DatabaseField)primaryKeyFields.get(index);
// Ensure that the type extracted from the row is the same type as in the object.
Class classification = (Class)primaryKeyClassifications.get(index);
Object value = databaseRow.get(field);
if (value != null) {
if (value.getClass() != classification) {
value = session.getPlatform(this.descriptor.getJavaClass()).convertO bject(value, classification);
}
primaryKeyValues.addElement(value);
} else {
if(this.mayHaveNullInPrimaryKey) {
numberOfNulls++;
if(numberOfNulls < size) {
primaryKeyValues.addElement(null);
} else {
// Must have some non null elements. If all elements are null return null.
return null;
}
} else {
return null;
}
}
}
return primaryKeyValues;
}
/**
* Return primary key classifications.
* These are used to ensure a consistent type for the pk values.
*/
public List<Class>getPrimaryKeyClassifications() {
if (primaryKeyClassifications == null) {
List primaryKeyFields = this.descriptor.getPrimaryKeyFields();
List<Class> classifications = new ArrayList(primaryKeyFields.size());
for (int index = 0; index < primaryKeyFields.size(); index++) {
DatabaseMapping mapping = getPrimaryKeyMappings().get(index);
DatabaseField field = (DatabaseField)primaryKeyFields.get(index);
if (mapping != null) {
classifications.add(Helper.getObjectClass(mapping.getFieldCl assification(field)));
} else {
classifications.add(null);
}
primaryKeyClassifications = classifications;
}
}
return primaryKeyClassifications;
}
|
|
|
|
Powered by
FUDForum. Page generated in 0.03492 seconds