Re: ClassCastException, Cayenne 2.0.4

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Sun Sep 07 2008 - 15:30:58 EDT

  • Next message: Ian Boston: "Re: ClassCastException, Cayenne 2.0.4"

    I think I found it.

    DbPerson.java:

      public void setAddresses(List<Address> addresses) {
          setList(ADDRESSES_PROPERTY, addresses, getAddresses(),
    addressFactory);
      }

    It should be

      public void setAddresses(List<DbPersonAddress> addresses) {
          setList(ADDRESSES_PROPERTY, addresses, getAddresses(),
    addressFactory);
      }

    I.e. ADDRESSES_PROPERTY points to DbPersonAddress, not Address entity,
    and use of generic DataObject API hides this fact from compiler.

    (BTW, Cayenne 3.0 (still alpha) is a bit more explicit in its generics
    support. So for instance 'getAddresses' method would had a signature
    of "public List<DbPersonAddress> getAddresses()", hinting to a type
    mismatch.)

    HTH,
    Andrus

    On Sep 7, 2008, at 9:22 PM, Ian Boston wrote:
    > On 7 Sep 2008, at 15:17, Andrus Adamchik wrote:
    >
    >> Hi Ian,
    >>
    >> I just checked out the code from the repo and used the model to
    >> create a local DB and a local test project. This seems to work for
    >> me with the test data that I inserted manually:
    >>
    >> Expression e = ExpressionFactory.matchExp(
    >> DbAddress.POSTAL_CODE_PROPERTY, "01111");
    >> SelectQuery sq = new SelectQuery(DbAddress.class, e);
    >>
    >> List<DbAddress> results = context.performQuery(sq);
    >> assertEquals(1, results.size());
    >> List<DbPersonAddress> joins = results.get(0).getPerson();
    >> assertEquals(1, joins.size());
    >>
    >> results = context.performQuery(sq);
    >> assertNotNull(results);
    >>
    >> This works for me. Glancing through your code, other than matching
    >> an int against varchar property (POSTAL_CODE_PROPERTY) I don't see
    >> any problems either.
    >>
    >>
    >>> DbAddress does have a toMany property called "person" which
    >>> connects to DbPerson
    >>>
    >>> However the DbPerson does not implement a ValueHolder (hence the
    >>> classcast exception).
    >>> DbAddress also 2 other 1 to many relationships (ie its shared).
    >>
    >> Not according to the mapping from SVN. DbAddress.person points to a
    >> list of DbPersonAddress objects. List (ToManyList) is a ValueHolder.
    >
    >
    > hmm,
    > DbAddress.addressOrgnanization should point to DbOrganizationAddress
    > that points to DbOrganization
    > DbAddress.personLocation should point to DbPerson
    >
    > thats what I meant by shared (ie the table and potentially records
    > are shared between organizations, people and person locations), not
    > very clear sorry.
    >
    >>
    >> But I may be missing something in my own test setup... So what are
    >> the prerequisites to run DbSmallTest?? I ran Maven from the "social-
    >> db" folder, but it complained about some missing dependencies. How
    >> do I bootstrap the local Maven repo for that?
    >>
    >
    > Ahh sorry I should have said, you need to pull Shindig and build
    > that, as this implements the SPI inside Shindig.
    >
    >
    > svn co http://svn.apache.org/repos/asf/incubator/shindig/trunk
    > cd trunk
    > mvn clean install
    >
    > That should get the jars into the repo, they are not yet released
    > anywhere.
    >
    >
    > BTW, The other odd thing is that it works for some of the DbAddress
    > objects but always fails on this one in the test, I have had a look
    > at the DB and everything looks connected.
    >
    > Thanks,
    > Ian
    >
    >
    >
    >
    >
    >> Thanks,
    >> Andrus
    >>
    >>
    >>
    >> On Sep 5, 2008, at 8:37 PM, Ian Boston wrote:
    >>
    >>> Hi,
    >>>
    >>>
    >>> Has anyone seen the exception below before ?
    >>>
    >>> I have traced the code and found that:
    >>>
    >>> in the AbstractCollectionProperty which is a ToManyListProperty
    >>> the accessor is a property called "person"
    >>> and the owner.objectClass is a DbAddress
    >>>
    >>> DbAddress does have a toMany property called "person" which
    >>> connects to DbPerson
    >>>
    >>> However the DbPerson does not implement a ValueHolder (hence the
    >>> classcast exception).
    >>> DbAddress also 2 other 1 to many relationships (ie its shared).
    >>>
    >>> and DbAddress does not have any setPerson(List<DbPerson> x)
    >>> methods or any properties that relate to person.
    >>> DbPerson does have a setAddresses (note the plural)
    >>>
    >>> -------------------------------------------------
    >>>
    >>> The code that generates the failure is https://source.sakaiproject.org/contrib/tfd/trunk/social-db/
    >>> and the test class that causes it is DbSmallTest.java
    >>>
    >>> Other DbAddress objects have been saved to the DB and this is on a
    >>> query of an address object as you will see from the
    >>> PersonPopulate.getNewAddress() entry point
    >>>
    >>>
    >>> I did look through the lists but couldn't find anything, so any
    >>> pointers would be most helpful (I am certain its something I am
    >>> doing wrong)
    >>>
    >>> Thanks
    >>> Ian
    >>>
    >>>
    >>>
    >>> java.lang.ClassCastException:
    >>> org.apache.shindig.social.opensocial.model.db.DbPerson
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .property
    >>> .AbstractCollectionProperty
    >>> .ensureCollectionValueHolderSet(AbstractCollectionProperty.java:123)
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .property
    >>> .AbstractCollectionProperty
    >>> .injectValueHolder(AbstractCollectionProperty.java:106)
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .property
    >>> .BaseClassDescriptor.injectValueHolders(BaseClassDescriptor.java:
    >>> 182)
    >>> at
    >>> org.apache.cayenne.access.DataContext.localObject(DataContext.java:
    >>> 1897)
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .access.ObjectResolver.objectFromDataRow(ObjectResolver.java:199)
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .access.ObjectResolver.objectsFromDataRows(ObjectResolver.java:117)
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .access
    >>> .ObjectResolver
    >>> .synchronizedObjectsFromDataRows(ObjectResolver.java:97)
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .access
    >>> .DataDomainQueryAction
    >>> .interceptObjectConversion(DataDomainQueryAction.java:319)
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .access.DataDomainQueryAction.execute(DataDomainQueryAction.java:
    >>> 116)
    >>> at org.apache.cayenne.access.DataDomain.onQuery(DataDomain.java:
    >>> 746)
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .util
    >>> .ObjectContextQueryAction.runQuery(ObjectContextQueryAction.java:
    >>> 217)
    >>> at
    >>> org
    >>> .apache
    >>> .cayenne
    >>> .access.DataContextQueryAction.execute(DataContextQueryAction.java:
    >>> 54)
    >>> at org.apache.cayenne.access.DataContext.onQuery(DataContext.java:
    >>> 1395)
    >>> at
    >>> org
    >>> .apache.cayenne.access.DataContext.performQuery(DataContext.java:
    >>> 1384)
    >>> at
    >>> org
    >>> .apache
    >>> .shindig
    >>> .social
    >>> .opensocial
    >>> .db.test.PersonPopulate.getNewAddress(PersonPopulate.java:336)
    >>> at
    >>> org
    >>> .apache
    >>> .shindig
    >>> .social
    >>> .opensocial
    >>> .db.test.PersonPopulate.createPerson(PersonPopulate.java:63)
    >>> at
    >>> org
    >>> .apache
    >>> .shindig
    >>> .social
    >>> .opensocial.db.test.DbSmallTest.loadBuildDb(DbSmallTest.java:98)
    >>> at
    >>> org
    >>> .apache
    >>> .shindig
    >>> .social
    >>> .opensocial.db.test.DbSmallTest.testSimpleQueries(DbSmallTest.java:
    >>> 72)
    >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    >>> at
    >>> sun
    >>> .reflect
    >>> .NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    >>> at
    >>> sun
    >>> .reflect
    >>> .DelegatingMethodAccessorImpl
    >>> .invoke(DelegatingMethodAccessorImpl.java:25)
    >>> at java.lang.reflect.Method.invoke(Method.java:585)
    >>> at junit.framework.TestCase.runTest(TestCase.java:168)
    >>> at junit.framework.TestCase.runBare(TestCase.java:134)
    >>> at junit.framework.TestResult$1.protect(TestResult.java:110)
    >>> at junit.framework.TestResult.runProtected(TestResult.java:128)
    >>> at junit.framework.TestResult.run(TestResult.java:113)
    >>> at junit.framework.TestCase.run(TestCase.java:124)
    >>> at junit.framework.TestSuite.runTest(TestSuite.java:232)
    >>> at junit.framework.TestSuite.run(TestSuite.java:227)
    >>> at
    >>> org
    >>> .junit
    >>> .internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:81)
    >>> at
    >>> org
    >>> .eclipse
    >>> .jdt
    >>> .internal
    >>> .junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
    >>> at
    >>> org
    >>> .eclipse
    >>> .jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    >>> at
    >>> org
    >>> .eclipse
    >>> .jdt
    >>> .internal
    >>> .junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    >>> at
    >>> org
    >>> .eclipse
    >>> .jdt
    >>> .internal
    >>> .junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    >>> at
    >>> org
    >>> .eclipse
    >>> .jdt
    >>> .internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:
    >>> 386)
    >>> at
    >>> org
    >>> .eclipse
    >>> .jdt
    >>> .internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:
    >>> 196)
    >>>
    >>>
    >>
    >
    >



    This archive was generated by hypermail 2.0.0 : Sun Sep 07 2008 - 15:31:37 EDT