NullPointerException in QueryKeyExpression.getQueryKeyOrNull [message #551953] |
Tue, 10 August 2010 09:31 |
Ana Oleski Messages: 22 Registered: July 2009 |
Junior Member |
|
|
We have this NullPointerException that only happens when several threads execute some batchjob on an AIX with 16 processors.
java.lang.NullPointerException
at
org.eclipse.persistence.internal.expressions.QueryKeyExpression.getQueryKeyOrNull(QueryKeyExpression.java:472)
Full stacktrace below. Happens when we execute a ReadAllQuery with a simple selection criteria, expressionbuilder.get(attributeName).equal(value)
I stress this, it only happens in production when lots of threads start doing the same thing for all objects of class A. For instance all accounts are updated with interest rates.
Our application uses eclipselink native API. The ServerSession is instantiated
based on an project.xml, for each transaction we acquire a ClientSession and subsequently a UnitOfWork, execute the readAllQuery on the uow, do stuff, commit the transaction. Everything works fine except for the batchjobs
I've looked at the code and I think it can only be a weird threadrace
public QueryKey getQueryKeyOrNull() {
if (!hasQueryKey) {
return null;
}
// Oct 19, 2000 JED
// Added try/catch. This was throwing a NPE in the following case
// expresssionBuilder.get("firstName").get("bob")
//moved by Gordon Yorke to cover validate and normalize
if (getContainingDescriptor() == null) {
throw QueryException.invalidQueryKeyInExpression(getName());
}
if (queryKey == null) {
// //NPE here
queryKey = getContainingDescriptor().getQueryKeyNamed(getName());
if (queryKey == null) {
hasQueryKey = false;
}
}
return queryKey;
}
getContainingDescriptor() calls getDescriptor() either on ObjectExpression, on ExpressionBuilder or on MapEntryExpression. ObjectExpression is the superclass and the method looks like this
public ClassDescriptor getDescriptor() {
if (isAttribute()) {
return null;
}
if (descriptor == null) {
// Look first for query keys, then mappings. Ultimately we should have query keys
// for everything and can dispense with the mapping part.
ForeignReferenceQueryKey queryKey = (ForeignReferenceQueryKey)getQueryKeyOrNull();
if (queryKey != null) {
descriptor = getSession().getDescriptor(queryKey.getReferenceClass());
return convertToCastDescriptor(descriptor, getSession());
}
if (getMapping() == null) {
throw QueryException.invalidQueryKeyInExpression(this);
}
// We assume this is either a foreign reference or an aggregate mapping
descriptor = getMapping().getReferenceDescriptor();
if (getMapping().isVariableOneToOneMapping()) {
throw QueryException.cannotQueryAcrossAVariableOneToOneMapping(getMapping(), descriptor);
}
convertToCastDescriptor(descriptor, getSession());
}
return descriptor;
}
descriptor is a transient member variable of the ObjectExpression class.
I think it might help to make it at least volatile. Or maybe the whole method should be synchronized.
Anyway, I've already filed about 5 months ago a bug for this problem: https://bugs.eclipse.org/bugs/show_bug.cgi?id=305112.
I'm writing in the forum because I would really like an workaround until the bug is hopefully fixed. Some way to trigger this method after login but before the threads start doing their work.
I'd be grateful for any suggestions,
Ana
java.lang.NullPointerException
at org.eclipse.persistence.internal.expressions.QueryKeyExpression.getQueryKeyOrNull(QueryKeyExpression.java:472)
at org.eclipse.persistence.internal.expressions.QueryKeyExpression.isAttribute(QueryKeyExpression.java:538)
at org.eclipse.persistence.internal.expressions.RelationExpression.isObjectComparison(RelationExpression.java:449)
at org.eclipse.persistence.internal.expressions.RelationExpression.doValuesConform(RelationExpression.java:160)
at org.eclipse.persistence.internal.expressions.RelationExpression.doesConform(RelationExpression.java:134)
at org.eclipse.persistence.expressions.Expression.doesConform(Expression.java:1314)
at org.eclipse.persistence.internal.identitymaps.IdentityMapManager.getAllFromIdentityMap(IdentityMapManager.java:483)
at org.eclipse.persistence.internal.sessions.IdentityMapAccessor.getAllFromIdentityMap(IdentityMapAccessor.java:305)
at org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getAllFromIdentityMap(UnitOfWorkIdentityMapAccessor.java:91)
at org.eclipse.persistence.internal.sessions.IdentityMapAccessor.getAllFromIdentityMap(IdentityMapAccessor.java:281)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.scanForConformingInstances(UnitOfWorkImpl.java:4682)
at org.eclipse.persistence.queries.ReadAllQuery.conformResult(ReadAllQuery.java:252)
at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:706)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:420)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1074)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:736)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1034)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:380)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1112)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2909)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1291)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1273)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1233)
at de.jdpe.bof.bes.query.pm.SimpleQueryManager.performComparisonQuery(SimpleQueryManager.java:336)
selectionCriteria=
Relation operator [ = ]
Query Key kontonummer
Base de.bkm.bes.kontosystem.konto.hauptbuch.BoHauptbuchkonto
Constant 101000
[Updated on: Tue, 10 August 2010 09:34] Report message to a moderator
|
|
|
|
|
Re: NullPointerException in QueryKeyExpression.getQueryKeyOrNull [message #555420 is a reply to message #551953] |
Thu, 26 August 2010 14:30 |
|
The is an Expression cache, it can be disabled on your descriptor sing,
descriptor.getQueryManager().setExpressionQueryCacheMaxSize( 0);
Please try this to see if this is the issue.
Also can you please try turning conforming off, does this resolve the issue?
If the query is always the same, you should convert it to a named query, this will be more efficient, and probably also resolve the issue. Can you please try this.
James : Wiki : Book : Blog : Twitter
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03532 seconds