Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 463042: Concurrency issue with Case expression operator #1354

Closed
dazey3 opened this issue Nov 10, 2021 · 0 comments
Closed

Bug 463042: Concurrency issue with Case expression operator #1354

dazey3 opened this issue Nov 10, 2021 · 0 comments
Assignees
Labels
bug Something isn't working

Comments

@dazey3
Copy link
Contributor

dazey3 commented Nov 10, 2021

Linking to BZ #463042

Sample project that reproduces the issue. Sample contains 1 class, 1 persistence.xml (uses H2 in-mem DB) and 1 pom.xml (optional)

When using a NamedQuery that contains the 'CASE' operator, the query is no longer ThreadSafe.

The problem can easily be reproduced by firing a NamedQuery containing a case operator within multiple concurrent threads (see example attached).

I was not able to understand the actual problem, but somehow the org.eclipse.persistence.expressions.ListExpressionOperator is shared across threads and its 'numberOfItems' is modified concurrently which eventually leads to all kinds of problems (either ArrayIndexOutOfBoundsException or NullPointerException).

Here is one of the stacktrace I had:

java.lang.ArrayIndexOutOfBoundsException: 11
	at org.eclipse.persistence.expressions.ListExpressionOperator.getDatabaseStrings(ListExpressionOperator.java:75)
	at org.eclipse.persistence.expressions.ExpressionOperator.printCollection(ExpressionOperator.java:2170)
	at org.eclipse.persistence.internal.expressions.ArgumentListFunctionExpression.printSQL(ArgumentListFunctionExpression.java:99)
	at org.eclipse.persistence.internal.expressions.FunctionExpression.writeFields(FunctionExpression.java:717)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.writeFieldsFromExpression(SQLSelectStatement.java:2033)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.writeFieldsIn(SQLSelectStatement.java:2048)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1675)
	at org.eclipse.persistence.internal.databaseaccess.DatabasePlatform.printSQLSelectStatement(DatabasePlatform.java:3178)
	at org.eclipse.persistence.platform.database.H2Platform.printSQLSelectStatement(H2Platform.java:53)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:782)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:792)
	at org.eclipse.persistence.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:813)
	at org.eclipse.persistence.internal.queries.StatementQueryMechanism.setCallFromStatement(StatementQueryMechanism.java:390)
	at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareReportQuerySelectAllRows(ExpressionQueryMechanism.java:1696)
	at org.eclipse.persistence.queries.ReportQuery.prepareSelectAllRows(ReportQuery.java:1203)
	at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:744)
	at org.eclipse.persistence.queries.ReportQuery.prepare(ReportQuery.java:1071)
	at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:661)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:901)
	at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:613)
	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:867)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1127)
	at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:403)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1215)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1751)
	at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
	at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:469)
	at my.jpa.test.Department$1.call(Department.java:62)
	at my.jpa.test.Department$1.call(Department.java:1)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:745)

or this one:

java.lang.NullPointerException
	at java.io.Writer.write(Writer.java:157)
	at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.printString(ExpressionSQLPrinter.java:188)
	at org.eclipse.persistence.expressions.ExpressionOperator.printCollection(ExpressionOperator.java:2197)
	at org.eclipse.persistence.internal.expressions.ArgumentListFunctionExpression.printSQL(ArgumentListFunctionExpression.java:99)
	at org.eclipse.persistence.internal.expressions.FunctionExpression.writeFields(FunctionExpression.java:717)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.writeFieldsFromExpression(SQLSelectStatement.java:2033)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.writeFieldsIn(SQLSelectStatement.java:2048)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1675)
	at org.eclipse.persistence.internal.databaseaccess.DatabasePlatform.printSQLSelectStatement(DatabasePlatform.java:3178)
	at org.eclipse.persistence.platform.database.H2Platform.printSQLSelectStatement(H2Platform.java:53)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:782)
	at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:792)
	at org.eclipse.persistence.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:813)
	at org.eclipse.persistence.internal.queries.StatementQueryMechanism.setCallFromStatement(StatementQueryMechanism.java:390)
	at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareReportQuerySelectAllRows(ExpressionQueryMechanism.java:1696)
	at org.eclipse.persistence.queries.ReportQuery.prepareSelectAllRows(ReportQuery.java:1203)
	at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:744)
	at org.eclipse.persistence.queries.ReportQuery.prepare(ReportQuery.java:1071)
	at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:661)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:901)
	at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:613)
	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:867)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1127)
	at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:403)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1215)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1751)
	at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
	at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:469)
	at my.jpa.test.Department$1.call(Department.java:62)
	at my.jpa.test.Department$1.call(Department.java:1)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:745)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant