OpenJPA
  1. OpenJPA
  2. OPENJPA-1001

java.lang.IndexOutOfBoundsException when executing attached test case

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.2.1
    • Fix Version/s: 1.2.3, 1.3.0, 2.0.0-beta2
    • Component/s: jdbc
    • Labels:
      None
    • Environment:
      Can reproduce on Max OS X and Linux

      Description

      I am hitting the following exception when executing the given test case:

      Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
      at java.util.ArrayList.RangeCheck(ArrayList.java:546)
      at java.util.ArrayList.get(ArrayList.java:321)
      at org.apache.openjpa.jdbc.sql.SQLBuffer.setParameters(SQLBuffer.java:615)
      at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:515)
      at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:471)
      at org.apache.openjpa.jdbc.sql.SelectImpl.prepareStatement(SelectImpl.java:463)
      at org.apache.openjpa.jdbc.sql.SelectImpl.execute(SelectImpl.java:379)
      at org.apache.openjpa.jdbc.sql.SelectImpl.execute(SelectImpl.java:325)
      at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.getInitializeStateResult(JDBCStoreManager.java:503)
      at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:322)
      at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:278)
      at org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:111)
      at org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
      at org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:894)
      at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:852)
      ... 53 more
      <openjpa-1.2.1-rexported nonfatal general error> org.apache.openjpa.persistence.PersistenceException: Index: 1, Size: 1
      at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:875)
      at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:774)
      at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.find(JDBCStoreManager.java:951)
      at org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy.load(RelationFieldStrategy.java:609)
      at org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:819)
      at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:688)
      at org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
      at org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
      at org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:2921)
      at org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:2999)
      at org.apache.openjpa.kernel.StateManagerImpl.fetchObjectField(StateManagerImpl.java:2242)
      at org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy.delete(RelationFieldStrategy.java:256)
      at org.apache.openjpa.jdbc.meta.FieldMapping.delete(FieldMapping.java:589)
      at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.delete(AbstractUpdateManager.java:238)
      at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.delete(AbstractUpdateManager.java:252)
      at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.populateRowManager(AbstractUpdateManager.java:143)
      at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:85)
      at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:72)
      at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:717)
      at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
      at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2010)
      at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1908)
      at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1679)
      at org.apache.openjpa.kernel.QueryImpl.isInMemory(QueryImpl.java:956)
      at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:796)
      at org.apache.openjpa.kernel.QueryImpl.deleteAll(QueryImpl.java:872)
      at org.apache.openjpa.kernel.QueryImpl.deleteAll(QueryImpl.java:868)
      at org.apache.openjpa.kernel.DelegatingQuery.deleteAll(DelegatingQuery.java:541)
      at org.apache.openjpa.persistence.QueryImpl.executeUpdate(QueryImpl.java:331)
      at org.apache.openjpa.persistence.test.PersistenceTestCase.clear(PersistenceTestCase.java:232)
      at org.apache.openjpa.persistence.test.PersistenceTestCase.clear(PersistenceTestCase.java:205)
      at org.apache.openjpa.persistence.test.SingleEMFTestCase.tearDown(SingleEMFTestCase.java:71)
      at junit.framework.TestCase.runBare(TestCase.java:130)

      ...

      1. TestIncompleteRelationship.java
        3 kB
        Richard Rak
      2. OPENJPA-1001.patch
        21 kB
        B.J. Reed
      3. IncompleteRelationshipSubclass.java
        1 kB
        Richard Rak
      4. IncompleteRelationshipParentEntity.java
        5 kB
        Richard Rak
      5. IncompleteRelationshipChildEntity.java
        5 kB
        Richard Rak

        Activity

        Hide
        Richard Rak added a comment -

        I've done some more digging around, and the issue appears to be:

        SelectImpl.wherePrimaryKey(ClassMapping mapping, Column[] toCols,
        Column[] fromCols, Object oid, JDBCStore store, PathJoins pj,
        SQLBuffer buf, List parmList)

        This method is adding the primary key values to the parameter list. It is adding a NULL value to the parameter list, and is also adding "IS NULL" to the SQLBuffer.

        Then, when SQLBuffer calls setParameters(PreparedStatement ps, List cacheParams), it is finding that NULL value in the cacheParams list, and is throwing the IndexOutOfBoundsException when attempting to find the column name for the null value.

        Show
        Richard Rak added a comment - I've done some more digging around, and the issue appears to be: SelectImpl.wherePrimaryKey(ClassMapping mapping, Column[] toCols, Column[] fromCols, Object oid, JDBCStore store, PathJoins pj, SQLBuffer buf, List parmList) This method is adding the primary key values to the parameter list. It is adding a NULL value to the parameter list, and is also adding "IS NULL" to the SQLBuffer. Then, when SQLBuffer calls setParameters(PreparedStatement ps, List cacheParams), it is finding that NULL value in the cacheParams list, and is throwing the IndexOutOfBoundsException when attempting to find the column name for the null value.
        Hide
        Michael Dick added a comment -

        Simply guarding for null when we add to the list appears to resolve the problem and it didn't break any other tests. The results look identical to what I get when running on trunk which has Pinaki's version of SQL caching.

        It seems to me that there's a better way to fix the problem, but I haven't been able to dig in and find it.

        Show
        Michael Dick added a comment - Simply guarding for null when we add to the list appears to resolve the problem and it didn't break any other tests. The results look identical to what I get when running on trunk which has Pinaki's version of SQL caching. It seems to me that there's a better way to fix the problem, but I haven't been able to dig in and find it.
        Hide
        Pinaki Poddar added a comment -

        > The results look identical to what I get when running on trunk which has Pinaki's version of SQL caching.
        Does that imply the test passed with 'Pinaki's version of SQL caching'?

        The test passed on trunk for me.

        If this test is failing with previous SQLCaching (not pinaki's version of SQL caching which is better be referred as Prepared Query caching – because that more accurately reflects what it is) that brings up again the long-standing issue with QuerySQLCache.

        Though Prepared Query Cache has no resemblance to QuerySQLCache in terms of its design and its solution approach – I still agreed to retain the same moniker to configure it because I saw it as a replacement for a potentially risky (and costly) mistake that has entered our released service stream.

        I am aware of the concerns/risks of backporting a rather large change such as Prepared Query Cache in a released service stream. But If Prepared Query Cache were not written by me, I would have voiced my opinion more strongly to backport it as a replacement for existing QuerySQLCache. The risk of regression with PQC changes are minimal both because of its design as well as it has been operation/tested in one way or other in different scenarios.

        Effectively, In my view (which can be accused of bias in this case), the cost of retaining existing QuerySQLCache in the service stream outweighs the risks of injecting PQC in the stream –

        Show
        Pinaki Poddar added a comment - > The results look identical to what I get when running on trunk which has Pinaki's version of SQL caching. Does that imply the test passed with 'Pinaki's version of SQL caching'? The test passed on trunk for me. If this test is failing with previous SQLCaching (not pinaki's version of SQL caching which is better be referred as Prepared Query caching – because that more accurately reflects what it is) that brings up again the long-standing issue with QuerySQLCache. Though Prepared Query Cache has no resemblance to QuerySQLCache in terms of its design and its solution approach – I still agreed to retain the same moniker to configure it because I saw it as a replacement for a potentially risky (and costly) mistake that has entered our released service stream. I am aware of the concerns/risks of backporting a rather large change such as Prepared Query Cache in a released service stream. But If Prepared Query Cache were not written by me, I would have voiced my opinion more strongly to backport it as a replacement for existing QuerySQLCache. The risk of regression with PQC changes are minimal both because of its design as well as it has been operation/tested in one way or other in different scenarios. Effectively, In my view (which can be accused of bias in this case), the cost of retaining existing QuerySQLCache in the service stream outweighs the risks of injecting PQC in the stream –
        Hide
        Michael Dick added a comment -

        Sorry I wasn't clear with my earlier remarks. The testcase passed for me with trunk, and also passed with a simple guard for null. I just haven't had a chance to dig deeper (don't want to just band aid a fix in).

        Pinaki, taking a closer look at Prepared Query Caching is on my ever growing list to things to do, but I don't want to sidetrack this issue any more than I already have

        Show
        Michael Dick added a comment - Sorry I wasn't clear with my earlier remarks. The testcase passed for me with trunk, and also passed with a simple guard for null. I just haven't had a chance to dig deeper (don't want to just band aid a fix in). Pinaki, taking a closer look at Prepared Query Caching is on my ever growing list to things to do, but I don't want to sidetrack this issue any more than I already have
        Hide
        B.J. Reed added a comment -

        This issue has been fixed in trunk with OPENJPA-703 revision 739123. Unfortunately, that commit was very large (> 60 files).

        I've been able to reduce the patch down to 5 files....seems that any more changes from this point break other JUnit test cases

        Mike, when committing this patch to 1.2.x, also commit the TestIncompleteRelationship test case and I suggest committing the test case to trunk as well.

        Show
        B.J. Reed added a comment - This issue has been fixed in trunk with OPENJPA-703 revision 739123. Unfortunately, that commit was very large (> 60 files). I've been able to reduce the patch down to 5 files....seems that any more changes from this point break other JUnit test cases Mike, when committing this patch to 1.2.x, also commit the TestIncompleteRelationship test case and I suggest committing the test case to trunk as well.

          People

          • Assignee:
            Michael Dick
            Reporter:
            Richard Rak
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development