Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 366057

Summary: createNativeQuery(String).executeUpdate() for a JPQL SELECT statement does not throw an IllegalStateException
Product: z_Archived Reporter: Stephen DiMilla <stephen.dimilla>
Component: EclipselinkAssignee: Nobody - feel free to take it <nobody>
Status: CLOSED INVALID QA Contact:
Severity: enhancement    
Priority: P3 CC: christopher.delahunt, eclipselink.orm-inbox, guy.pelletier, lance.andersen, stephen.dimilla, tom.ware
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:

Description Stephen DiMilla CLA 2011-12-08 11:10:54 EST
Build Identifier: eclipselink-2.3.0.v20110604-r9504

Executing the following statement does not thrown an IllegalStateException as specified by the javadoc


        try {
            et.begin();

            System.out.println("Execute Query");
            em.createNativeQuery("Select * from ORDER1 o WHERE o.\"ID\" = '2' ").executeUpdate();
            System.out.println("IllegalStateException was not thrown");

        } catch (IllegalStateException ise) {
            // ok
        } catch (Exception e) {
            e.printStackTrace();
        }

Instead the following generated:

 Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
 Internal Exception: java.sql.SQLException: Statement.executeUpdate() cannot be called with a statement that returns a ResultSet.
 Error Code: 20000
 Call: Select * from ORDER1 o WHERE o."ID" = '2' 
 Query: DataModifyQuery(sql="Select * from ORDER1 o WHERE o."ID" = '2' ")
 	at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
 	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:840)
 	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
 	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:592)
 	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
 	at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1702)
 	at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:253)
 	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
 	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
 	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelectCall(DatasourceCallQueryMechanism.java:236)
 	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelect(DatasourceCallQueryMechanism.java:216)
 	at org.eclipse.persistence.queries.DataModifyQuery.executeDatabaseQuery(DataModifyQuery.java:85)
 	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:829)
 	at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:728)
 	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2863)
 	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1501)
 	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1483)
 	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1457)
 	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeUpdate(EJBQueryImpl.java:540)
 Caused by: java.sql.SQLException: Statement.executeUpdate() cannot be called with a statement that returns a ResultSet.
 	at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
 	at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
 	at org.apache.derby.client.am.PreparedStatement.executeUpdate(Unknown Source)
 	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:831)
 	... 30 more
 Caused by: org.apache.derby.client.am.SqlException: Statement.executeUpdate() cannot be called with a statement that returns a ResultSet.
 	at org.apache.derby.client.am.Statement.checkForAppropriateSqlMode(Unknown Source)
 	at org.apache.derby.client.am.PreparedStatement.flowExecute(Unknown Source)
 	at org.apache.derby.client.am.PreparedStatement.executeUpdateX(Unknown Source)

Reproducible: Always
Comment 1 Tom Ware CLA 2012-04-05 11:01:22 EDT
Updating target milestone.
Comment 2 Chris Delahunt CLA 2012-11-09 17:05:38 EST
Not a bug in the sense that the JPA specification only requires an IllegalStateException in the case that the query is a JPQL or Criteria query.  The native SQL calls were intentionally left out so providers do not have to parse the SQL directly, and instead rely on the database/drivers handling of the statement.  In this case, it causes a runtime exception

In this case though, the exception could be wrapped in an IllegalStateException or other javax.persistence.PersistenceException instead of a native EclipseLinkException.  Changing this to an enhancement to be looked at in a future release
Comment 3 Tom Ware CLA 2013-02-08 13:59:23 EST
Closing.  The JPA spec does not intend us to parse Native SQL, nor do we have any plans to do so.
Comment 4 Eclipse Webmaster CLA 2022-06-09 10:23:55 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink