Cayenne
  1. Cayenne
  2. CAY-550

MSAccess adapter throw bogus hollow object exception

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: Undefined future
    • Fix Version/s: None
    • Component/s: Core Library
    • Labels:
      None
    • Environment:
      MSAccess adapter.

      Description

      I need to debug more, but these are my working notes.

      Log shows record found:

      INFO QueryLogger: SELECT t0.TREATASPEC_ACTIVE, t0.TREATASPEC_CRITID, t0.TREATASPEC_FIXEDCOST, t0.TREATASPEC_QTYPE, t0.treataspec_rolehastoclose, t0.TREATASPEC_VC1, t0.TREATASPEC_VC2, t0.TREATASPEC_VC2CRITID, t0.TREATASPEC_VC2FIXEDCOST, t0.TREATASPEC_VC2QTYPE, t0.TREATASPEC_VC3, t0.TREATASPEC_VC3CRITID, t0.TREATASPEC_VC3FIXEDCOST, t0.TREATASPEC_VC3QTYPE, t0.TREATASPEC_VC4, t0.TREATASPEC_VC4CRITID, t0.TREATASPEC_VC4FIXEDCOST, t0.TREATASPEC_VC4QTYPE, t0.TREATASPEC_VC5, t0.TREATASPECR_ID, t0.TREATASPEC_ID FROM TREAT_AREASPEC t0 WHERE t0.TREATASPEC_ID = ? [bind: '05 LagerAvvik pakking/klFeil merking på']
      INFO QueryLogger: === returned 1 row. - took 16 ms.
      INFO QueryLogger: +++ transaction committed.

      – exception thrown.

      org.objectstyle.cayenne.FaultFailureException: [v.1.2-dev May 9 2006] Error resolving fault for ObjectId: <ObjectId:TreatAreaspec, TREATASPEC_ID=05 LagerAvvik pakking/klFeil merking på> and state (hollow). Possible cause - matching row is missing from the database.

      1. objectidpatch.txt
        0.9 kB
        Øyvind Harboe
      2. trailingspacetestcase.txt
        12 kB
        Øyvind Harboe
      3. primkeyfaulttake2.txt
        10 kB
        Øyvind Harboe
      4. msaccessadapterwithtestcase.txt
        31 kB
        Øyvind Harboe
      5. msaccesspatch.txt
        39 kB
        Øyvind Harboe

        Activity

        Hide
        Øyvind Harboe added a comment -

        MS Access adapter work-in-progress, including a JUnit test for the WHERE "foo"="foo<space>" problem.

        Show
        Øyvind Harboe added a comment - MS Access adapter work-in-progress, including a JUnit test for the WHERE "foo"="foo<space>" problem.
        Hide
        Øyvind Harboe added a comment -

        More working notes to self.

        Tore Halset suggested that I could try SELECT * FROM AUTO_PK_SUPPORT as a workaround for the flaky autoPkTableExists(). Something along these lines:

        protected boolean autoPkTableExists(DataNode node) throws SQLException {
        Connection con = node.getDataSource().getConnection();
        try {
        Statement stat=con.createStatement();

        try

        { return stat.execute("SELECT * FROM AUTO_PK_SUPPORT"); }

        finally

        { stat.close(); }

        } catch (Exception e)

        { return false; }

        finally

        { // return connection to the pool con.close(); }

        }

        Show
        Øyvind Harboe added a comment - More working notes to self. Tore Halset suggested that I could try SELECT * FROM AUTO_PK_SUPPORT as a workaround for the flaky autoPkTableExists(). Something along these lines: protected boolean autoPkTableExists(DataNode node) throws SQLException { Connection con = node.getDataSource().getConnection(); try { Statement stat=con.createStatement(); try { return stat.execute("SELECT * FROM AUTO_PK_SUPPORT"); } finally { stat.close(); } } catch (Exception e) { return false; } finally { // return connection to the pool con.close(); } }
        Hide
        Øyvind Harboe added a comment -

        My cursory tests of HSQLDB, indicates that it will not yield a match for WHERE "foo"="foo<space>"

        Show
        Øyvind Harboe added a comment - My cursory tests of HSQLDB, indicates that it will not yield a match for WHERE "foo"="foo<space>"
        Hide
        Øyvind Harboe added a comment -

        I've now successfully run the testcase for this problem against the MSAccess adapter.

        However, the MSAccess adapter seems to be pretty flaky when it comes to checking for the existance of a table, which means that the code does not run out of the box due to problems with creating/dropping the AUTO_PK_SUPPORT table

        Show
        Øyvind Harboe added a comment - I've now successfully run the testcase for this problem against the MSAccess adapter. However, the MSAccess adapter seems to be pretty flaky when it comes to checking for the existance of a table, which means that the code does not run out of the box due to problems with creating/dropping the AUTO_PK_SUPPORT table
        Hide
        Øyvind Harboe added a comment -

        More work in progress on trying to put together a test case.

        Missing:

        1. I only tested this with HSQLDB so far. I haven't figured out how to run the JUnit test against MS Access yet.

        2. The HSQLDB picks up the extranous space and refuses to register such relationships. I may have to figure out how to disable foreign key constraints for this particular test case.

        Show
        Øyvind Harboe added a comment - More work in progress on trying to put together a test case. Missing: 1. I only tested this with HSQLDB so far. I haven't figured out how to run the JUnit test against MS Access yet. 2. The HSQLDB picks up the extranous space and refuses to register such relationships. I may have to figure out how to disable foreign key constraints for this particular test case.
        Hide
        Øyvind Harboe added a comment -

        NB! MS SQL server also gets bitten by this in my tests. This leads me to believe that HSQLDB also has this problem. I would like to have the testcase completed regardless of what happens.

        I believe your approach will work(i.e. it is adequate), but I don't think it is the correct way to handle this.

        Are there other cases where the WHERE clause as a different concept of equality than ObjectId, or is this the only one?

        Show
        Øyvind Harboe added a comment - NB! MS SQL server also gets bitten by this in my tests. This leads me to believe that HSQLDB also has this problem. I would like to have the testcase completed regardless of what happens. I believe your approach will work(i.e. it is adequate), but I don't think it is the correct way to handle this. Are there other cases where the WHERE clause as a different concept of equality than ObjectId, or is this the only one?
        Hide
        Andrus Adamchik added a comment -

        I still think that the standard facilities that I mentioned here should be adequate:

        http://objectstyle.org/cayenne/lists/cayenne-devel/2006/05/0122.html

        CharType handles JDBC CHAR trimming, as VARCHAR trimming has never been an issue by definition. So could you try a subclass of CharType for MSAccess:

        class MSAccessCharType extends CharType {
        MSAccessCharType()

        { super(true, false); }

        // override both 'materializeObject' versions to trim in both cases: "type == Types.CHAR" and "type == Types.VARCHAR"
        }

        Show
        Andrus Adamchik added a comment - I still think that the standard facilities that I mentioned here should be adequate: http://objectstyle.org/cayenne/lists/cayenne-devel/2006/05/0122.html CharType handles JDBC CHAR trimming, as VARCHAR trimming has never been an issue by definition. So could you try a subclass of CharType for MSAccess: class MSAccessCharType extends CharType { MSAccessCharType() { super(true, false); } // override both 'materializeObject' versions to trim in both cases: "type == Types.CHAR" and "type == Types.VARCHAR" }
        Hide
        Øyvind Harboe added a comment -

        Work in progress to implement testcase for problems with trailing space in references to primary keys.

        I'm struggling with twisting Cayenne's arm to introduce the space in the reference, but as soon as I've got that sorted the structure of the testcase should be fine(ignoring the things like comments, indenting, etc. that must obviously be fixed).

        Show
        Øyvind Harboe added a comment - Work in progress to implement testcase for problems with trailing space in references to primary keys. I'm struggling with twisting Cayenne's arm to introduce the space in the reference, but as soon as I've got that sorted the structure of the testcase should be fine(ignoring the things like comments, indenting, etc. that must obviously be fixed).
        Hide
        Øyvind Harboe added a comment -

        I don't have the Cayenne accumen to know whether this is the correct way to fix the problem, but it works on my rocket.

        Show
        Øyvind Harboe added a comment - I don't have the Cayenne accumen to know whether this is the correct way to fix the problem, but it works on my rocket.
        Hide
        Øyvind Harboe added a comment -

        I believe I've found the culprit:

        The primary key ends with a SPACE.

        The problem is basically that SQL will find the record, because "FOO<SPACE> " = "FOO" for WHERE clauses.

        Show
        Øyvind Harboe added a comment - I believe I've found the culprit: The primary key ends with a SPACE. The problem is basically that SQL will find the record, because "FOO<SPACE> " = "FOO" for WHERE clauses.
        Hide
        Øyvind Harboe added a comment -

        This problem also happens with primary keys that do not contain national characters, so that's not it.

        Show
        Øyvind Harboe added a comment - This problem also happens with primary keys that do not contain national characters, so that's not it.
        Hide
        Øyvind Harboe added a comment -

        This is not MSAccess specific. I tried the same w/MS SQL Server and saw the same problem.

        Show
        Øyvind Harboe added a comment - This is not MSAccess specific. I tried the same w/MS SQL Server and saw the same problem.
        Hide
        Øyvind Harboe added a comment -

        ObjectStore.resolveHollow(DataObject) line: 1015
        DataContext.prepareForAccess(Persistent, String) line: 1842
        TreatAreaspec(CayenneDataObject).readProperty(String) line: 238
        TreatAreaspec(_TreatAreaspec).getTreataspecVc1() line: 85

        At this point the object has been returned, but that isn't enough to get the objected out of the HOLLOW state...

        results =>

        [

        {<ObjectId:TreatAreaspec, TREATASPEC_ID=05 LagerAvvik pakking/klFeil merking på >; committed; [treataspecVc3=>null; treataspecActive=>Y; treataspecVc2=>Feil merking på produkt; treataspecVc4fixedcost=>null; treataspecVc2critid=>null; treataspecVc3fixedcost=>null; treataspecRolehastoclose=>Y; treataspecCritid=>null; treataspecVc4qtype=>null; treataspecVc2qtype=>null; treatAreaspeccorrectiveArray=>(..); treataspecVc5=>null; treataspecVc2fixedcost=>null; treataspecVc1=>Avvik pakking/klargjøring; treataspecQtype=>null; treataspecVc4=>null; treataspecVc3qtype=>null; treataspecVc4critid=>null; treataspecVc3critid=>null; treataspecFixedcost=>null; toTreatAreaspecroot=>?]}

        ]

        Show
        Øyvind Harboe added a comment - ObjectStore.resolveHollow(DataObject) line: 1015 DataContext.prepareForAccess(Persistent, String) line: 1842 TreatAreaspec(CayenneDataObject).readProperty(String) line: 238 TreatAreaspec(_TreatAreaspec).getTreataspecVc1() line: 85 At this point the object has been returned, but that isn't enough to get the objected out of the HOLLOW state... results => [ {<ObjectId:TreatAreaspec, TREATASPEC_ID=05 LagerAvvik pakking/klFeil merking på >; committed; [treataspecVc3=>null; treataspecActive=>Y; treataspecVc2=>Feil merking på produkt; treataspecVc4fixedcost=>null; treataspecVc2critid=>null; treataspecVc3fixedcost=>null; treataspecRolehastoclose=>Y; treataspecCritid=>null; treataspecVc4qtype=>null; treataspecVc2qtype=>null; treatAreaspeccorrectiveArray=>(..); treataspecVc5=>null; treataspecVc2fixedcost=>null; treataspecVc1=>Avvik pakking/klargjøring; treataspecQtype=>null; treataspecVc4=>null; treataspecVc3qtype=>null; treataspecVc4critid=>null; treataspecVc3critid=>null; treataspecFixedcost=>null; toTreatAreaspecroot=>?]} ]
        Hide
        Øyvind Harboe added a comment -

        The record above definitely exists and I believe the problem might not be MSAccess specific.

        This is a rather perverse database that is using space & national letters in the primary key, weee!!!!!

        However, there are other cases where national letters (Norwegian 'å') in the primary key does work. Note that the national letter('å') is the last char in the primary key here.

        TREATASPEC_ID above is (believe it or not) a primary key.

        Tomorrow I hope to try with the very latest from SVN(the build I ran is ca. a week or two old).

        Show
        Øyvind Harboe added a comment - The record above definitely exists and I believe the problem might not be MSAccess specific. This is a rather perverse database that is using space & national letters in the primary key, weee!!!!! However, there are other cases where national letters (Norwegian 'å') in the primary key does work. Note that the national letter('å') is the last char in the primary key here. TREATASPEC_ID above is (believe it or not) a primary key. Tomorrow I hope to try with the very latest from SVN(the build I ran is ca. a week or two old).

          People

          • Assignee:
            Unassigned
            Reporter:
            Øyvind Harboe
          • Votes:
            2 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:

              Development