Re: ClassCastException, Cayenne 2.0.4

From: Ian Boston (ie..fd.co.uk)
Date: Mon Sep 08 2008 - 04:18:20 EDT

  • Next message: Andrus Adamchik: "Re: ClassCastException, Cayenne 2.0.4"

    Fantastic, thank you.

    One last question:
    is this because Cayenne does introspection on the methods of the Db
    entity class ?

    Since setAddresses is part of the Person API, (so I cant change it) I
    assume that changing the name of the underlying attribute will also
    fix this ?

    Ian

    On 7 Sep 2008, at 20:30, Andrus Adamchik wrote:

    > 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.ensureCollec
    >>>> tionValueHolderSet(AbstractCollectionProperty.java:123)
    >>>> at
    >>>> org.apache.cayenne.property.AbstractCollectionProperty.injectValueH
    >>>> older(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.synchronizedObjectsFromDat
    >>>> aRows(ObjectResolver.java:97)
    >>>> at
    >>>> org.apache.cayenne.access.DataDomainQueryAction.interceptObjectConv
    >>>> ersion(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.getNewA
    >>>> ddress(PersonPopulate.java:336)
    >>>> at
    >>>> org.apache.shindig.social.opensocial.db.test.PersonPopulate.createP
    >>>> erson(PersonPopulate.java:63)
    >>>> at
    >>>> org.apache.shindig.social.opensocial.db.test.DbSmallTest.loadBuildD
    >>>> b(DbSmallTest.java:98)
    >>>> at
    >>>> org.apache.shindig.social.opensocial.db.test.DbSmallTest.testSimple
    >>>> Queries(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 : Mon Sep 08 2008 - 04:19:17 EDT