Can you post the whole stack trace so we can see where the error is coming from.
14:23:31,971 INFO [AdminMaintainUser] Populating groups for User Doug. Currently 6 14:23:31,982 INFO [AdminMaintainUser] User Id is 14 14:23:32,002 ERROR [STDERR] Oct 9, 2007 2:23:32 PM com.sun.facelets.FaceletViewHandler handleRenderException SEVERE: Error Rendering View[/secure/admin/AdminMaintainUsers.xhtml] java.lang.IllegalArgumentException: Cannot convert com.locuslive.odyssey.entity.Groups@cc3e51 of type class com.locuslive.odyssey.entity.Groups to class com.locuslive.odyssey.entity.Groups_$$_javassist_548 at org.jboss.el.lang.ELSupport.coerceToType(ELSupport.java:358) at org.jboss.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:46) at org.jboss.seam.el.SeamExpressionFactory.coerceToType(SeamExpressionFactory.java:70) at com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.renderOption(SelectManyCheckboxListRenderer.java:275) at com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.encodeEnd(SelectManyCheckboxListRenderer.java:146) at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:833) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:896) at javax.faces.render.Renderer.encodeChildren(Renderer.java:137) at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:809) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:886) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:892) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:892) at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:577) at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108) at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:216) at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106) at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251) at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) at org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:44) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141) at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281) at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:150) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104) at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Thread.java:613)
If you can produce a runnable example showing this simply with no extra cruft, please report a jira issue so I can look :)
I've created a basic project illustrating this. I've attached it to the JIRA at http://jira.jboss.org/jira/browse/JBSEAM-2111.
I've attached the project built with Seam 2.0.0.CR2 and it raises the error. I've also attached it built with Seam 1.2.1.GA and the error doesn't happen. This explains why it has just started happening for me as I've only recently upgraded.
Many of us have come across this error. It seems to be caused by a flaw in the Directions for the JPA (which is Based on Hibernate) and Hibernate. They all assume you can use the proxy directly. You can't! The problem is direct use of a proxy object fails the GoF Pattern for proxies. Proxies REQUIRE an interface.
The issue is "Subject isNotA SubjectProxy".
Its not an EL issue. The AspectGenerated Proxy is following the GoF Proxy definition. The flaw is that everyone seems to be using the Proxy wrong. (Even his highness, Gavin King.) Read the books on the subject and the documentation and the forums. It is assumed that you can directly use the proxy asA subject; by definition this is an incorrect assumption.
Define a proper proxy-pattern it passes the "coerceToType" method from EL. Subj implements ISubj, Proxy implements ISubj. Therefore Subj isA ISubj and Proxy isA ISubj. Then when the coerceToType trys to make reconstitute the values in the ISubj it works because then the Proxy passes the critical isA test (Specifically isAssignableFrom())
ENOUGH TECH PAUL WHATS THE SOLUTION. (I know I say it my head)
QUICK AND DIRTY (REALLY DIRTY)
The quickest solution to this problem is to tell JPA or Hibernate to not use a Proxy. I know this causes serious issues: Less caching, dirty checks, lazy loading and all that lovely stuff.
The proper solution is "Design By Interface" and only reference the interface. Alas the Hibernate implementation has some mapping issues with this approach. (Cross mapping a storage solution via an interface can not be annotated currently, also the XML mappings seem to require double mapping of entities to the interfaces: note I am not sure on the latter)
These may be mitigated by defining the interface as the proxy
It sounds like you are saying that the problem is something fundamental with Hibernate??
I find it hard to believe that Seam/Hibernate doesn't handle this - it certainly did under Seam 1.2.1.GA. Can anyone offer a practical solution that fits in with Seam/Hibernate under Seam 2?
I am mainly saying that the implementation documentation leads people to the wrong conclusions. The example exercises all target direct use of the Proxy. This is incorrect for the GoF proxy pattern.
Seam handles some aspects of it for you; however, if you pass a Proxy AS A Subject to the View Layer through JSF; its lifecycle requires saving and reconstituting your objects. The coerceToType error occurs because the Proxy fails the to be converted to the Subject... because it is not one. This is correct. The problem is that you have to use a commonly implemented interface or tell the JPA/Hibernate/Ibatis et al. not to use the Auto-Proxy. Then it will build the actual Subject each time. Unfortunately, as I mentioned in my first posting on the topic, this seriously affects the caching paradigm.
Read GoF: Design Patterns. Proxy Pattern.
Use a common interface. (Eclipse can help you "Extract interfaces") Just read carefully into how to connect the interface to the mapped version. I mentioned that the annotation:
@org.hibernate.annotations.Proxy(proxyClass = myProxyInterface.class)
Does seem to function properly. I have not had the time to formally test this out. (on my todo list.)
Quick note: This occurs in all JSF implementations not just SEAM.( Which leverages JSF)
Interesting but still doesn't explain why it worked in Seam 1.2.1.GA and 1.3.0.ALPHA. I'll try @Proxy if my problems persist.
Interestingly, I went back and looked at my old revisions and found a prior version under Seam 1.3.0.ALPHA had the same problem. A compare in SVN identified the culprit as being one of the following JARS:
When I rolled these back this issue didn't occur again under Seam 1.3.0.ALPHA. I can't get the same result under Seam 2.0.0.CR2 but will be working on the assumption that one of these jars is the cause.
Without knowing the details of the assumption directly in the EL implementation and the interpretation of the JSF lifecycle its hard to tell.
How does one solve the problem completely? Well, thats the million dollar question :)
I suggest writing a clean JUnit test scenario that proves the problem. Then, extend the diagnosis to the main problem at hand. Personally, I know how one can get lost in the details. JPA and Hibernate have done a fine job, though I think the core of the issue is the common misuse of the Proxy.
If it worked in one version and not the latest, you may have been able to slip past a crack in the implementation that is now fixed.
Remember JSF impls changed between AS 4.0.5 and 4.2. The problem arises from mapping your ManyToOne as lazy. Unfortunately I don't think @Proxy will help as you will still be trying to coerce to a proxy.
Thanks Pete. Just tried changing the mapping to EAGER and it works fine. Much appreciated.
Or you can ommit the property entirely.
I would like to get this fixed properly - however as it stands either JSF or EL needs to be aware of javassist proxies (I can't see another solution).
Using @Proxy pointed to an the common ISubject interface does work. I will try to send a test case soon.
Turning off the proxy also works.
I do not have time to go into detail; however, look at the use of natural keys for the links for ManyToOne mappings. ProHibernate3 talks about it. Though only some discussion. This way the lazy-load of an object into a map can use the "natural key"-"machine-key" as key-value. Then lazy loading can load the object iff it has been selected and another transaction to the server occurs and the natural key can be displayed in selectItems as a <String, PK>.