I see. In 1.2 Cayenne supports field-based persistence (albeit only
on the remote client at the moment). As we move forward, this may
become the default way to store properties (especially in light of
JPA spec compliance). So the runtime has to work with both DataObject
and POJO classes. The problem seems to be in the attempt to combine
both approaches for the same entity class. Probably we shouldn't be
mixing them when compiling ClassDescriptors.
I'd appreciate a bug report - with a reproducible test case, I'll
take another look at how the ClassDescriptors are implemented.
Andrus
On Jun 28, 2006, at 2:07 PM, Robert Zeigler wrote:
> Found the issue.
> AssignmentTransaction has a one-to-many relationship named
> "studentResponses". It also had a private variable:
> private List studentResponses. In certain situations (described
> momentarily), it appears that the field accessor class is "seeing" the
> private variable instead of the relationship. When I changed the
> name of
> the private variable, the problem disappeared. I was also able to
> duplicate the issue in an entirely unrelated (and much simpler) data
> map. This seems like a bug to me; seems like FieldAccessor
> shouldn't be
> able to grab/use my private variables. :) If you want, I can open up a
> jira issue and attach a really simple map and bit of code that will
> illustrate the issue.
>
> In any event, here is the situation where the invalid access occurs:
> X has a to-many relationship to Y. Z also has a to-many
> relationship to Y.
> Y has a to-many relationship named k, and also has a private List k;
> declaration.
> xinstance, zinstance , and yinstance are instances of X, Z and Y,
> respectively, and xinstance and zinstance share a yinstance.
> X loads its list of Y via xinstance.getY(). xinstance does some
> processing that results in
> k's initialization in the shared yinstance. zinstance now does
> zinstance.getY() and attempts to perform some operation on the list
> (size(), get(0), iterator(), etc... something that forces cayenne to
> fault the toManyList). While processing the shared yinstance, cayenne
> will choke with a ClassCastException because it will see the private
> variable k (now initialized, eg, to an ArrayList) rather than the
> relationship with the same name.
>
> Apologies if the explanation is a bit opaque... again... I'll work
> up a
> trivial data map + code example that triggers the error.
>
> Robert
>
> Robert Zeigler wrote:
>> Didn't get back to this last night, sorry. Ok, I sat down and wrote a
>> quick test to call the same code, external of tapestry.
>> The code outside of tapestry didn't result in a class cast exception.
>> Instead, it resulted in an ExpressionException (unable to evaluate
>> assignment.name). Turns out that the assignment object doesn't
>> have a
>> "name" property (it's "title"). The thing that seems odd here is that
>> the code throws no exceptions with M5 (I suspect this has to do with
>> removing BeanUtils as a dependency?).
>>
>> Anyway... the lack of a ClassCastException says that something weird
>> must be happening in tapestry or my code somewhere. I'll keep
>> looking.
>> I don't define collection setters in the DO; neither my code nor
>> tapestry should be initializing the relationship, but I'll keep
>> digging
>> to see what I can find.
>>
>> Robert
>>
>>
>> Andrus Adamchik wrote:
>>
>>>> In poking around, I saw a place where if something was
>>>> transient, an ArrayList was returned... but I can't find it
>>>> again at the
>>>> moment; I'll look later tonight when I have a bit of time and
>>>> see if I
>>>> can find it again.
>>>>
>>> Let us know if you find those - this shouldn't happen in
>>> DataObjects.
>>> The code below looks clean, so the cause is somewhere else. Is it
>>> possible that Tapestry or the user code initializes the relationship
>>> list on its own? Do you define collection setters in your DO's
>>> (Cayenne does not by default)?
>>>
>>> Andrus
>>>
>>>
>>>
>>> On Jun 27, 2006, at 2:54 AM, Robert Zeigler wrote:
>>>
>>>
>>>> Hi all,
>>>>
>>>> Way back when 1.2B1 was released, I reported a weird fault
>>>> resolving
>>>> exception. I didn't have time then to look into it further. I
>>>> just tried
>>>> out cayenne 1.2RC2 and am still seeing the same weird behavior
>>>> (maybe
>>>> I'm doing something weird. ;). I do have time now to look into it
>>>> further, but am getting stuck before I can get started by a
>>>> separate
>>>> issue.
>>>>
>>>> My code:
>>>> public List getTransactionsForCourse(Course course) {
>>>> List ret = this.getAssignmentTransactions();
>>>> ret =
>>>> ExpressionFactory.matchExp
>>>> ("assignment.course.name",course.getName()).filterObjects(ret);
>>>>
>>>> List orderings = new ArrayList();
>>>> orderings.add(new Ordering("assignment.name",true));
>>>> orderings.add(new Ordering("scoreAsFloat",false));
>>>> Ordering.orderList(ret,orderings);
>>>> return ret;
>>>> }
>>>>
>>>> assignmentTransactions is a one to many relationship.
>>>>
>>>> Calling said code is resulting in the following exception:
>>>>
>>>> *
>>>> org.objectstyle.cayenne.property.AbstractCollectionProperty.ensureC
>>>> ollectionValueHolderSet(AbstractCollectionProperty.java:159)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.property.AbstractCollectionProperty.injectV
>>>> alueHolder(AbstractCollectionProperty.java:142)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.property.BaseClassDescriptor.injectValueHol
>>>> ders(BaseClassDescriptor.java:218)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.DataContext.localObject
>>>> (DataContext.java:1924)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.ObjectResolver.objectFromDataRow
>>>> (ObjectResolver.java:237)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.ObjectResolver.objectsFromDataRows
>>>> (ObjectResolver.java:155)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.ObjectResolver.synchronizedObjectsFr
>>>> omDataRows(ObjectResolver.java:134)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.DataDomainQueryAction.interceptObjec
>>>> tConversion(DataDomainQueryAction.java:373)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.DataDomainQueryAction.execute
>>>> (DataDomainQueryAction.java:151)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.DataDomain.onQuery
>>>> (DataDomain.java:766)
>>>>
>>>> *
>>>> org.objectstyle.cayenne.util.ObjectContextQueryAction.runQuery
>>>> (ObjectContextQueryAction.java:253)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.DataContextQueryAction.execute
>>>> (DataContextQueryAction.java:90)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.DataContext.onQuery
>>>> (DataContext.java:1422)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.DataContext.performQuery
>>>> (DataContext.java:1411)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.ToManyList.resolvedObjectList
>>>> (ToManyList.java:343)
>>>>
>>>>
>>>> *
>>>> org.objectstyle.cayenne.access.ToManyList.size(ToManyList.java:296)
>>>> *
>>>> org.objectstyle.cayenne.exp.Expression.filterObjects
>>>> (Expression.java:458)
>>>>
>>>>
>>>> * org.eledge.domain.User.getTransactionsForCourse(User.java:92)
>>>> * org.eledge.domain.User.getGradebookGradedResponses
>>>> (User.java:197)
>>>> *
>>>> org.eledge.domain.User.getGradedGradebookGradedResponses
>>>> (User.java:192)
>>>>
>>>> *
>>>> org.eledge.domain.User.getHasGradedGradebookGradedResponses
>>>> (User.java:188)
>>>>
>>>>
>>>> * sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>> *
>>>> sun.reflect.NativeMethodAccessorImpl.invoke
>>>> (NativeMethodAccessorImpl.java:39)
>>>>
>>>>
>>>> *
>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke
>>>> (DelegatingMethodAccessorImpl.java:25)
>>>>
>>>>
>>>> * java.lang.reflect.Method.invoke(Method.java:585)
>>>> * ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:491)
>>>> * ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:785)
>>>> * ognl.ObjectMethodAccessor.callMethod
>>>> (ObjectMethodAccessor.java:61)
>>>> * ognl.OgnlRuntime.callMethod(OgnlRuntime.java:819)
>>>> * ognl.ASTMethod.getValueBody(ASTMethod.java:75)
>>>> * ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
>>>> * ognl.SimpleNode.getValue(SimpleNode.java:210)
>>>> * ognl.ASTChain.getValueBody(ASTChain.java:109)
>>>> * ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
>>>> * ognl.SimpleNode.getValue(SimpleNode.java:210)
>>>> * ognl.Ognl.getValue(Ognl.java:333)
>>>> * ognl.Ognl.getValue(Ognl.java:310)
>>>> *
>>>> org.apache.tapestry.binding.ExpressionBinding.resolveProperty
>>>> (ExpressionBinding.java:201)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.binding.ExpressionBinding.getObject
>>>> (ExpressionBinding.java:194)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.binding.AbstractBinding.getBoolean
>>>> (AbstractBinding.java:77)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.param.BooleanParameterConnector.setParameter
>>>> (BooleanParameterConnector.java:51)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.param.ParameterManager.setParameters
>>>> (ParameterManager.java:105)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.prepareForRender
>>>> (AbstractComponent.java:898)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:853)
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.renderBody
>>>> (AbstractComponent.java:624)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.components.RenderBody.renderComponent
>>>> (RenderBody.java:45)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.renderBody
>>>> (AbstractComponent.java:624)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.components.RenderBody.renderComponent
>>>> (RenderBody.java:45)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.renderBody
>>>> (AbstractComponent.java:624)
>>>>
>>>>
>>>> * org.apache.tapestry.html.Body.renderComponent(Body.java:269)
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.renderBody
>>>> (AbstractComponent.java:624)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.components.RenderBody.renderComponent
>>>> (RenderBody.java:45)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.renderBody
>>>> (AbstractComponent.java:624)
>>>>
>>>>
>>>> * org.apache.tapestry.html.Shell.renderComponent(Shell.java:
>>>> 124)
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> *
>>>> org.apache.tapestry.BaseComponent.renderComponent
>>>> (BaseComponent.java:118)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> *
>>>> org.apache.tapestry.BaseComponent.renderComponent
>>>> (BaseComponent.java:118)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.renderBody
>>>> (AbstractComponent.java:624)
>>>>
>>>>
>>>> * org.mb.tapestry.base.IfBean.renderComponent(IfBean.java:83)
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> *
>>>> org.apache.tapestry.BaseComponent.renderComponent
>>>> (BaseComponent.java:118)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> *
>>>> org.apache.tapestry.BaseComponent.renderComponent
>>>> (BaseComponent.java:118)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.AbstractComponent.render
>>>> (AbstractComponent.java:857)
>>>>
>>>> * org.apache.tapestry.AbstractPage.renderPage
>>>> (AbstractPage.java:300)
>>>> *
>>>> org.apache.tapestry.engine.RequestCycle.renderPage
>>>> (RequestCycle.java:368)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.engine.AbstractEngine.renderResponse
>>>> (AbstractEngine.java:749)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.engine.PageService.service(PageService.java:77)
>>>> *
>>>> org.apache.tapestry.engine.AbstractEngine.service
>>>> (AbstractEngine.java:889)
>>>>
>>>>
>>>> * org.eledge.EledgeEngine.service(EledgeEngine.java:60)
>>>> *
>>>> org.apache.tapestry.ApplicationServlet.doService
>>>> (ApplicationServlet.java:198)
>>>>
>>>>
>>>> *
>>>> org.apache.tapestry.ApplicationServlet.doGet
>>>> (ApplicationServlet.java:159)
>>>>
>>>>
>>>> * javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
>>>> * javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
>>>> *
>>>> org.mortbay.jetty.servlet.ServletHolder.handle
>>>> (ServletHolder.java:428)
>>>>
>>>> *
>>>> org.mortbay.jetty.servlet.WebApplicationHandler
>>>> $CachedChain.doFilter(WebApplicationHandler.java:830)
>>>>
>>>>
>>>> *
>>>> org.eledge.OldEledgePagesFilter.doFilter
>>>> (OldEledgePagesFilter.java:64)
>>>>
>>>> *
>>>> org.mortbay.jetty.servlet.WebApplicationHandler
>>>> $CachedChain.doFilter(WebApplicationHandler.java:821)
>>>>
>>>>
>>>> *
>>>> org.mortbay.jetty.servlet.WebApplicationHandler.dispatch
>>>> (WebApplicationHandler.java:471)
>>>>
>>>>
>>>> *
>>>> org.mortbay.jetty.servlet.ServletHandler.handle
>>>> (ServletHandler.java:568)
>>>>
>>>> * org.mortbay.http.HttpContext.handle(HttpContext.java:1530)
>>>> *
>>>> org.mortbay.jetty.servlet.WebApplicationContext.handle
>>>> (WebApplicationContext.java:633)
>>>>
>>>>
>>>> * org.mortbay.http.HttpContext.handle(HttpContext.java:1482)
>>>> * org.mortbay.http.HttpServer.service(HttpServer.java:909)
>>>> * org.mortbay.http.HttpConnection.service
>>>> (HttpConnection.java:816)
>>>> *
>>>> org.mortbay.http.HttpConnection.handleNext(HttpConnection.java:982)
>>>> * org.mortbay.http.HttpConnection.handle(HttpConnection.java:
>>>> 833)
>>>> *
>>>> org.mortbay.http.SocketListener.handleConnection
>>>> (SocketListener.java:244)
>>>>
>>>>
>>>> * org.mortbay.util.ThreadedServer.handle(ThreadedServer.java:
>>>> 357)
>>>> * org.mortbay.util.ThreadPool$PoolThread.run(ThreadPool.java:
>>>> 534)
>>>>
>>>>
>>>> This is a tapestry (3.0.3) webapp, running with the
>>>> JettyLauncher. I've
>>>> done a clean recompile, but no good. I dug into the code, and it
>>>> looks
>>>> like ensureCollectionValueHolderSet is trying to cast an
>>>> ArrayList as a
>>>> ValueHolder. In poking around, I saw a place where if something
>>>> was
>>>> transient, an ArrayList was returned... but I can't find it
>>>> again at the
>>>> moment; I'll look later tonight when I have a bit of time and
>>>> see if I
>>>> can find it again. Anyway... thoughts? Cayenne bug? Something I've
>>>> screwed up?
>>>>
>>>> Robert
>>>>
>>>>
>>
>>
>
>
This archive was generated by hypermail 2.0.0 : Wed Jun 28 2006 - 10:14:41 EDT