Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    SQL cursor state not valid error with custom operation binding

    I have a custom operation binding with customSQL that issues an UPDATE to the database. In some cases the update results in no records affected, which is a legitimate condition, but the operation fails with a "cursor state not valid" message. Here is an example from the log.
    Code:
    update IPPOHDR
    set HSTS='R', HRNO=HRNO+1
    where HONO in (
    	select HONO
    	from ProductionOrder
    	join ProductionLine on ProductionOrder.id=ProductionLine.parentId
    	join ProductionDelivery on ProductionLine.id=ProductionDelivery.parentId	
    	join ProductionDestination on ProductionDelivery.id=ProductionDestination.parentId
    	join IPPOHDR on ProductionDestination.controlNum = HONO
    	where ProductionOrder.id = 34
    	and HSTS in ('R','A')
    ) on db: iptsfili threw exception: java.sql.SQLException: Cursor state not valid. - assuming stale connection and retrying query.
    Our db server is an IBM iSeries so I researched the error and found that this error occurs when you don't have a resultset (e.g. when you run an update statement or a stored proc that does not return a resultset), but you call rs.next()

    I can run the same SQL statement directly and get no error. So it seems that the SQLDataSource code is calling rs.next() and getting the error. Is there another approach I could take that might avoid this?

    #2
    Can you show the whole server log? We need to see what phase of processing is hitting this error.

    Comment


      #3
      Here is the full log. The client sends a "revise" request to the server. The server first does a fetch, then calls the custom operation which tries to do the UPDATE.
      Code:
      === 2012-05-22 13:24:44,280 [l0-4] INFO  RequestContext - URL: '/ipgui/sc/IDACall', User-Agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0': Moz (Gecko) with Accept-Encoding header
      === 2012-05-22 13:24:44,290 [l0-4] INFO  IpIDACall - Performing 1 operation(s)
      === 2012-05-22 13:24:44,292 [l0-4] WARN  Validation - [builtinApplication.revise] No such type 'currency', not processing field value at /ProductionOrder/cost
      === 2012-05-22 13:24:44,293 [l0-4] WARN  Validation - [builtinApplication.revise] No such type 'currency', not processing field value at /ProductionOrder/retail
      === 2012-05-22 13:24:44,299 [l0-4] INFO  SQLDataSource - [builtinApplication.revise, builtinApplication.null] Performing fetch operation with
      	criteria: {id:34}	values: {id:34}
      === 2012-05-22 13:24:44,300 [l0-4] INFO  SQLDataSource - [builtinApplication.revise, builtinApplication.null] derived query: SELECT $defaultSelectClause FROM 
      				ProductionOrder 
      				LEFT JOIN IPMRVEN on ProductionOrder.vendorId=IPMRVEN.VVEN
      				LEFT JOIN ProductionContact as vendorContact on ProductionOrder.vContactId=vendorContact.id
      				LEFT JOIN BuyingAgent on ProductionOrder.bAgentId=BuyingAgent.id
      				LEFT JOIN ProductionContact as buyingAgentContact on ProductionOrder.bContactId=buyingAgentContact.id
      				LEFT JOIN InspectionAgent on ProductionOrder.iAgentId=InspectionAgent.id
      				LEFT JOIN ProductionContact as inspectionAgentContact on ProductionOrder.iContactId=inspectionAgentContact.id
      			 WHERE $defaultWhereClause
      === 2012-05-22 13:24:44,301 [l0-4] INFO  SQLDataSource - [builtinApplication.revise, builtinApplication.null] Executing SQL query on 'iptsfili': SELECT BuyingAgent.name AS BuyingAgent_name, IPMRVEN.VNAM AS IPMRVEN_VNAM, ProductionOrder.approve1By AS InitialApprovalBy, ProductionOrder.bankAddr1, ProductionOrder.bankAddr2, ProductionOrder.bankCity, ProductionOrder.bankCntry AS bankCountry, ProductionOrder.bankName, ProductionOrder.bankPost AS bankPostCode, ProductionOrder.bankState, ProductionOrder.bicNumber, ProductionOrder.bContactId AS buyAgentContactId, ProductionOrder.bAgentId AS buyAgentId, ProductionOrder.buyerId, buyingAgentContact.name AS buyingAgentContact_name, ProductionOrder.controlNum, ProductionOrder.cost, ProductionOrder.createdBy, ProductionOrder.createdOn, ProductionOrder.currency, ProductionOrder.division, ProductionOrder.exchRate, ProductionOrder.factoryId, ProductionOrder.approve2By AS finalApprovalBy, ProductionOrder.approve2On AS finalApprovalOn, ProductionOrder.id, ProductionOrder.approve1On AS initialApprovalOn, ProductionOrder.iContactId AS inspectionAgentContactId, inspectionAgentContact.name AS inspectionAgentContact_name, ProductionOrder.iAgentId AS inspectionAgentId, ProductionOrder.iRequired AS inspectionRequired, ProductionOrder.lastEditBy, ProductionOrder.lastEdited AS lastEditedOn, ProductionOrder.lockedBy, ProductionOrder.lockedOn, ProductionOrder.orderDate, ProductionOrder.origin, ProductionOrder.originalCost, ProductionOrder.originalRetail, ProductionOrder.originalUnits, ProductionOrder.payMethId AS payMethodId, ProductionOrder.payTerm, ProductionOrder.retail, ProductionOrder.revApprBy AS revisionApprovalBy, ProductionOrder.revApprOn AS revisionApprovalOn, ProductionOrder.ssnYear AS seasonYear, ProductionOrder.shipPortId, ProductionOrder.shipTermId, ProductionOrder.status, ProductionOrder.tolMsg AS toleranceMsg, ProductionOrder.tranModeId AS transportModeId, ProductionOrder.units, ProductionOrder.vContactId AS vendorContactId, vendorContact.name AS vendorContact_name, ProductionOrder.vendorId, ProductionOrder.vendorTkts AS vendorTickets, ProductionOrder.zone FROM 
      				ProductionOrder 
      				LEFT JOIN IPMRVEN on ProductionOrder.vendorId=IPMRVEN.VVEN
      				LEFT JOIN ProductionContact as vendorContact on ProductionOrder.vContactId=vendorContact.id
      				LEFT JOIN BuyingAgent on ProductionOrder.bAgentId=BuyingAgent.id
      				LEFT JOIN ProductionContact as buyingAgentContact on ProductionOrder.bContactId=buyingAgentContact.id
      				LEFT JOIN InspectionAgent on ProductionOrder.iAgentId=InspectionAgent.id
      				LEFT JOIN ProductionContact as inspectionAgentContact on ProductionOrder.iContactId=inspectionAgentContact.id
      			 WHERE (ProductionOrder.id='34')
      === 2012-05-22 13:24:44,890 [l0-4] INFO  SQLDriver - [builtinApplication.revise, builtinApplication.null] Executing SQL query on 'iptsfili': SELECT BuyingAgent.name AS BuyingAgent_name, IPMRVEN.VNAM AS IPMRVEN_VNAM, ProductionOrder.approve1By AS InitialApprovalBy, ProductionOrder.bankAddr1, ProductionOrder.bankAddr2, ProductionOrder.bankCity, ProductionOrder.bankCntry AS bankCountry, ProductionOrder.bankName, ProductionOrder.bankPost AS bankPostCode, ProductionOrder.bankState, ProductionOrder.bicNumber, ProductionOrder.bContactId AS buyAgentContactId, ProductionOrder.bAgentId AS buyAgentId, ProductionOrder.buyerId, buyingAgentContact.name AS buyingAgentContact_name, ProductionOrder.controlNum, ProductionOrder.cost, ProductionOrder.createdBy, ProductionOrder.createdOn, ProductionOrder.currency, ProductionOrder.division, ProductionOrder.exchRate, ProductionOrder.factoryId, ProductionOrder.approve2By AS finalApprovalBy, ProductionOrder.approve2On AS finalApprovalOn, ProductionOrder.id, ProductionOrder.approve1On AS initialApprovalOn, ProductionOrder.iContactId AS inspectionAgentContactId, inspectionAgentContact.name AS inspectionAgentContact_name, ProductionOrder.iAgentId AS inspectionAgentId, ProductionOrder.iRequired AS inspectionRequired, ProductionOrder.lastEditBy, ProductionOrder.lastEdited AS lastEditedOn, ProductionOrder.lockedBy, ProductionOrder.lockedOn, ProductionOrder.orderDate, ProductionOrder.origin, ProductionOrder.originalCost, ProductionOrder.originalRetail, ProductionOrder.originalUnits, ProductionOrder.payMethId AS payMethodId, ProductionOrder.payTerm, ProductionOrder.retail, ProductionOrder.revApprBy AS revisionApprovalBy, ProductionOrder.revApprOn AS revisionApprovalOn, ProductionOrder.ssnYear AS seasonYear, ProductionOrder.shipPortId, ProductionOrder.shipTermId, ProductionOrder.status, ProductionOrder.tolMsg AS toleranceMsg, ProductionOrder.tranModeId AS transportModeId, ProductionOrder.units, ProductionOrder.vContactId AS vendorContactId, vendorContact.name AS vendorContact_name, ProductionOrder.vendorId, ProductionOrder.vendorTkts AS vendorTickets, ProductionOrder.zone FROM 
      				ProductionOrder 
      				LEFT JOIN IPMRVEN on ProductionOrder.vendorId=IPMRVEN.VVEN
      				LEFT JOIN ProductionContact as vendorContact on ProductionOrder.vContactId=vendorContact.id
      				LEFT JOIN BuyingAgent on ProductionOrder.bAgentId=BuyingAgent.id
      				LEFT JOIN ProductionContact as buyingAgentContact on ProductionOrder.bContactId=buyingAgentContact.id
      				LEFT JOIN InspectionAgent on ProductionOrder.iAgentId=InspectionAgent.id
      				LEFT JOIN ProductionContact as inspectionAgentContact on ProductionOrder.iContactId=inspectionAgentContact.id
      			 WHERE (ProductionOrder.id='34')
      === 2012-05-22 13:24:45,532 [l0-4] INFO  DSResponse - [builtinApplication.revise, builtinApplication.null] DSResponse: List with 1 items
      === 2012-05-22 13:24:45,554 [l0-4] INFO  SQLDataSource - [builtinApplication.revise, builtinApplication.startRevision] Performing custom operation with
      	criteria: {id:34}	values: 0 valueSets
      === 2012-05-22 13:24:45,560 [l0-4] INFO  SQLDataSource - [builtinApplication.revise, builtinApplication.startRevision] Executing SQL query on 'iptsfili': update IPPOHDR
      				set HSTS='R', HRNO=HRNO+1
      				where HONO in (
      				select HONO
      				from ProductionOrder
      				join ProductionLine on ProductionOrder.id=ProductionLine.parentId
      				join ProductionDelivery on ProductionLine.id=ProductionDelivery.parentId	
      				join ProductionDestination on ProductionDelivery.id=ProductionDestination.parentId
      				join IPPOHDR on ProductionDestination.controlNum = HONO
      				where ProductionOrder.id = 34
      				and HSTS in ('R','A'))
      === 2012-05-22 13:24:46,138 [l0-4] INFO  SQLDriver - [builtinApplication.revise, builtinApplication.startRevision] Executing SQL query on 'iptsfili': update IPPOHDR
      				set HSTS='R', HRNO=HRNO+1
      				where HONO in (
      				select HONO
      				from ProductionOrder
      				join ProductionLine on ProductionOrder.id=ProductionLine.parentId
      				join ProductionDelivery on ProductionLine.id=ProductionDelivery.parentId	
      				join ProductionDestination on ProductionDelivery.id=ProductionDestination.parentId
      				join IPPOHDR on ProductionDestination.controlNum = HONO
      				where ProductionOrder.id = 34
      				and HSTS in ('R','A'))
      === 2012-05-22 13:24:48,421 [l0-4] INFO  SQLDriver - [builtinApplication.revise, builtinApplication.startRevision] Execute of select: update IPPOHDR
      				set HSTS='R', HRNO=HRNO+1
      				where HONO in (
      				select HONO
      				from ProductionOrder
      				join ProductionLine on ProductionOrder.id=ProductionLine.parentId
      				join ProductionDelivery on ProductionLine.id=ProductionDelivery.parentId	
      				join ProductionDestination on ProductionDelivery.id=ProductionDestination.parentId
      				join IPPOHDR on ProductionDestination.controlNum = HONO
      				where ProductionOrder.id = 34
      				and HSTS in ('R','A')) on db: iptsfili threw exception: java.sql.SQLException: Cursor state not valid. - assuming stale connection and retrying query.
      === 2012-05-22 13:24:49,866 [l0-4] WARN  RequestContext - dsRequest.execute() failed: 
      java.sql.SQLException: Cursor state not valid.
      	at com.ibm.as400.access.JDError.throwSQLException(JDError.java:405)
      	at com.ibm.as400.access.JDError.throwSQLException(JDError.java:377)
      	at com.ibm.as400.access.AS400JDBCStatement.executeQuery(AS400JDBCStatement.java:2154)
      	at org.apache.commons.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)
      	at com.isomorphic.sql.SQLDriver.getTransformedResults(SQLDriver.java:376)
      	at com.isomorphic.sql.SQLDriver.executeQuery(SQLDriver.java:628)
      	at com.isomorphic.sql.SQLDataSource.executeNativeQuery(SQLDataSource.java:391)
      	at com.isomorphic.sql.SQLDataSource.executeNativeQuery(SQLDataSource.java:385)
      	at com.isomorphic.sql.SQLDataSource.SQLExecute(SQLDataSource.java:1322)
      	at com.isomorphic.sql.SQLDataSource.processRequest(SQLDataSource.java:293)
      	at com.isomorphic.sql.SQLDataSource.executeCustom(SQLDataSource.java:253)
      	at com.isomorphic.datasource.DataSource.execute(DataSource.java:1309)
      	at com.islandpacific.gui.server.customDataSource.IpDataSource.execute(IpDataSource.java:161)
      	at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:725)
      	at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658)
      	at com.isomorphic.application.AppBase.execute(AppBase.java:491)
      	at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:1948)
      	at com.islandpacific.gui.server.purchasing.productionorder.ProductionOrderDS.reviseOrder(ProductionOrderDS.java:267)
      	at com.islandpacific.gui.server.purchasing.productionorder.ProductionOrderDS.executeUpdate(ProductionOrderDS.java:112)
      	at com.isomorphic.datasource.DataSource.execute(DataSource.java:1295)
      	at com.islandpacific.gui.server.customDataSource.IpDataSource.execute(IpDataSource.java:161)
      	at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:725)
      	at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658)
      	at com.isomorphic.application.AppBase.execute(AppBase.java:491)
      	at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:1948)
      	at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:199)
      	at com.islandpacific.gui.server.customDataSource.IpIDACall.handleDSRequest(IpIDACall.java:70)
      	at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:156)
      	at com.islandpacific.gui.server.customDataSource.IpIDACall.processRPCTransaction(IpIDACall.java:41)
      	at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:121)
      	at com.isomorphic.servlet.IDACall.doPost(IDACall.java:73)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
      	at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1097)
      	at com.islandpacific.gui.server.GWTCacheControlFilter.doFilter(GWTCacheControlFilter.java:44)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
      	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
      	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      	at com.islandpacific.gui.security.IpConcurrentSessionFilter.doFilter(IpConcurrentSessionFilter.java:55)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
      	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
      	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
      	at com.isomorphic.servlet.CompressionFilter.doFilter(CompressionFilter.java:259)
      	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
      	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
      	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
      	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
      	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
      	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
      	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
      	at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
      	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
      	at org.mortbay.jetty.Server.handle(Server.java:324)
      	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
      	at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
      	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
      	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
      	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
      	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
      	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
      === 2012-05-22 13:24:49,886 [l0-4] INFO  Compression - /ipgui/sc/IDACall: 144 -> 130 bytes

      Comment


        #4
        Looking at this part of the stack:

        Code:
               at com.isomorphic.sql.SQLDataSource.executeCustom(SQLDataSource.java:253)
               at com.isomorphic.datasource.DataSource.execute(DataSource.java:1309)
        It looks like you must be creating a DSRequest server-side with operationType "custom". Any reason you are doing this instead of operationType "update" (since that's the actual SQL operation involved)? It looks like we're assuming that a "custom" operation will return a JDBC ResultSet that may be empty, but not broken (throws Exception from RS.next()).

        Comment


          #5
          No good reason for "custom" instead of "update". I changed it to an update and added canSyncCache="false" since I don't want the cache sync fetch to occur. That fixed it. Thanks!

          Comment

          Working...
          X