-
1. Re: ManyToOne OneToMany
mtpettyp Aug 8, 2007 5:22 PM (in response to jknotzke)More of a EJB3 question, but I think you need to change:
@OneToMany(mappedBy="workout", cascade=CascadeType.REMOVE) private List<Workout> workouts = new ArrayList<Workout>();
to@OneToMany(mappedBy="athlete", cascade=CascadeType.REMOVE) private List<Workout> workouts = new ArrayList<Workout>();
You need to specify the field in the Workout entity which maps back to this object. -
2. Re: ManyToOne OneToMany
wiberto Aug 8, 2007 5:33 PM (in response to jknotzke)What's the error message you are getting?
-
3. Re: ManyToOne OneToMany
fhh Aug 8, 2007 5:34 PM (in response to jknotzke)@OneToMany(mappedBy="workout", cascade=CascadeType.REMOVE) private List<Workout> workouts = new ArrayList<Workout>();
You propably mean mappedBy="athlete".
Regards
Felix -
4. Re: ManyToOne OneToMany
jknotzke Aug 8, 2007 10:25 PM (in response to jknotzke)Right.. That did it. Thanks.
Next bug.
Just to set the stage, an Athlete can have several workouts. I am able to create an athlete and it's stored in the DB. After which, I attempt to create a Workout. A workout however is created when a user uploads a CSV file of their workout.
I am able to parse this, load it into the Workout Entity bean. However, I want to be able to associate this with the athlete that was previously select.. Here is the code:@Stateless @Scope(SESSION) @Name("uploadWorkout") public class UploadWorkoutBean implements UploadWorkout { @Logger private Log log; @In Athlete athlete; @In(value = "uploadedWorkout", create = true) private UploadedWorkout uploadedWorkout; @In FacesMessages facesMessages; @PersistenceContext private EntityManager em; public void uploadWorkout() { // implement your business logic here log.info("uploadWorkout.uploadWorkout() action called"); log.info("Content Type is: " + uploadedWorkout.getContentType()); log.info("FileName is: " + uploadedWorkout.getFileName()); WorkoutReader workoutReader = new WorkoutReader(); ArrayList<Workout> workouts = workoutReader.readFile(uploadedWorkout.getUploadedFile()); Workout workout = null; // Stuff it into the DB for(int i=0; i< 1 ;i++) { workout = workouts.get(i); log.info(athlete.getLastName()); em.persist(workout); } facesMessages.add("uploadWorkout"); }
The error that is thrown is:Caused by: org.jboss.seam.RequiredException: In attribute requires non-null value: uploadWorkout.athlete at org.jboss.seam.Component.getValueToInject(Component.java:2153) at org.jboss.seam.Component.injectAttributes(Component.java:1583) at org.jboss.seam.Component.inject(Component.java:1404) at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:45) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106) at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:53) 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:597)
-
5. Re: ManyToOne OneToMany
samdoyle Aug 9, 2007 12:25 AM (in response to jknotzke)Didn't you specify the condition:
@NotNull private Athlete athlete;
In your workout class? I think in this case you need to make use of the Seam factory functionality. -
6. Re: ManyToOne OneToMany
fhh Aug 9, 2007 6:38 AM (in response to jknotzke)@In Athlete athlete;
You get the error message because athlete is not found in any context. You have to outject the athlete when it "selected" (not sure what you mean by that) so it is available in one of the Seam contexts.
Regards
Felix -
7. Re: ManyToOne OneToMany
jknotzke Aug 9, 2007 7:21 AM (in response to jknotzke)Hi everyone.. Thanks for all the replies so far. Sorry if these are noob questions but I'm really trying to get past this.. Ok. Here is what I have done:
@Stateless @Scope(SESSION) @Name("uploadWorkout") public class UploadWorkoutBean implements UploadWorkout { @Logger private Log log; @In @Out Athlete athlete; @In(value = "uploadedWorkout", create = true) private UploadedWorkout uploadedWorkout;
.. and here is the error07:17:58,024 ERROR [ExceptionFilter] exception root cause javax.faces.FacesException: #{uploadWorkout.uploadWorkout}: javax.ejb.EJBTransactionRolledbackException: In attribute requires non-null value: uploadWorkout.athlete at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:107) at javax.faces.component.UICommand.broadcast(UICommand.java:383) at org.ajax4jsf.framework.ajax.AjaxViewRoot.processEvents(AjaxViewRoot.java:180) at org.ajax4jsf.framework.ajax.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:158) at org.ajax4jsf.framework.ajax.AjaxViewRoot.processApplication(AjaxViewRoot.java:346) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:97) at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244) 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:82) at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:80) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:68) at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:68) at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:44) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:68) at org.ajax4jsf.framework.ajax.xmlfilter.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:127) at org.ajax4jsf.framework.ajax.xmlfilter.BaseFilter.doFilter(BaseFilter.java:277) at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:68) at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:68) at org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:68) at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:149) 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:157) 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:619) Caused by: javax.faces.el.EvaluationException: javax.ejb.EJBTransactionRolledbackException: In attribute requires non-null value: uploadWorkout.athlete at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:91) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:91) ... 45 more Caused by: javax.ejb.EJBTransactionRolledbackException: In attribute requires non-null value: uploadWorkout.athlete at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:87) at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130) at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:195) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77) at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:106) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:214) at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:184) at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:81) at $Proxy288.uploadWorkout(Unknown Source) 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:597) at org.jboss.seam.util.Reflections.invoke(Reflections.java:21) at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31) at org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:76) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56) at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:32) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106) at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54) at org.javassist.tmp.java.lang.Object_$$_javassist_6.uploadWorkout(Object_$$_javassist_6.java) 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:597) at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:328) at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:341) at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58) at org.jboss.el.parser.AstValue.invoke(AstValue.java:96) at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276) at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:77) ... 46 more
-
8. Re: ManyToOne OneToMany
david.spark Aug 9, 2007 7:37 AM (in response to jknotzke)One problem is that the @Out annotation should be in the code where the athlete was originally selected. How is the athlete that you want to upload the workout for selected?
-
9. Re: ManyToOne OneToMany
jknotzke Aug 9, 2007 8:02 AM (in response to jknotzke)"david.spark" wrote:
One problem is that the @Out annotation should be in the code where the athlete was originally selected. How is the athlete that you want to upload the workout for selected?
The athlete is selected via a xhtml page. I've been using seam-gen. So imagine the athleteList.xthml page. I merely added a link to the uploadWorkout page:<h:column> <f:facet name="header">Calendar</f:facet> <s:link id="athlete" value="Calendar" view="/workoutList.xhtml"> <f:param name="workoutId" value="#{workout.id}"/> <f:param name="athleteId" value="#{athlete.id}"/> </s:link> </h:column>
The @Out was placed in athlete.java
uploadWorkout.xhtml looks like this:<s:fileUpload id="inUploadFile" data="#{uploadedWorkout.uploadedFile}" fileName="#{uploadedWorkout.fileName}" contentType="#{uploadedWorkout.contentType}" styleClass="fileUploadInput" /> <div style="clear:both"/> </rich:panel> <div class="actionButtons"> <h:commandButton id="uploadWorkout" value="Upload Workout" action="#{uploadWorkout.uploadWorkout}"/>
-
10. Re: ManyToOne OneToMany
david.spark Aug 9, 2007 10:19 AM (in response to jknotzke)I don't use seam-gen much so can't really imagine that page :-)
It seems like you're passing the athleteID to workoutList.xhtml. That's not the same as passing an instance of athlete, so unless something happens in workoutList.xhtml to convert the ID back to an instance of Athlete there's no 'athlete' available to @In. What does workoutList.xhtml do with the ID?
What is athlete.java? If it's an entityBean then @Out won't do much there. -
11. Re: ManyToOne OneToMany
jknotzke Aug 9, 2007 10:48 AM (in response to jknotzke)"david.spark" wrote:
I don't use seam-gen much so can't really imagine that page :-)
It seems like you're passing the athleteID to workoutList.xhtml. That's not the same as passing an instance of athlete, so unless something happens in workoutList.xhtml to convert the ID back to an instance of Athlete there's no 'athlete' available to @In. What does workoutList.xhtml do with the ID?
What is athlete.java? If it's an entityBean then @Out won't do much there.
Ah ha, well i can confirm it's not doing much! ;-)
athlete.java is an Entity Bean.
Essentially, what I am trying to do is pass a particular athlete that was chosen via a web page to another webpage that then passes it to a statless session bean. You see creating a workout is not done via a form. It's done by parsing a csv file. The only user intervention is in uploading this csv file.
So I have an stateless session bean that uploads the file, parses it and then persists it.
The problem is that I need to associate the athlete with the workout. So i need a reference to the chosen athlete.
Any ideas ?
Thanks
J -
12. Re: ManyToOne OneToMany
david.spark Aug 9, 2007 11:35 AM (in response to jknotzke)OK so assuming that athleteList.xthml is correctly generating a list of athlete objects I would change your s:link to be something like:
<h:column> <f:facet name="header">Calendar</f:facet> <h:commandLink id="athlete" value="Calendar" action="#{uploadWorkout.selectAthlete(athlete)}"/> </h:column>
and create a corresponding method in the backing bean:public String selectAthlete(Athlete athlete) { this.athlete = athlete; return "/workoutList.xhtml"; }
The reason for using h:commandLink rather than s:link is that h:commandLink submits the form whereas s:link doesn't so the value isn't passed. There's no view attribute on h:commandLink so we have to navigate by returning the view ID from the method.
This should work, and you can also remove the @In annotation from athlete as it's not needed.
Hopefully this will do what you want :-) -
13. Re: ManyToOne OneToMany
jknotzke Aug 9, 2007 12:10 PM (in response to jknotzke)
Ah ha.. very cool. So I have to do it "manually".. Never thought of that..
Ok, one small problem which you alluded to: i can't see the link. I had to encompass the h:commandLink in a form (otherwise it would not deploy. The code now looks like:<h:form> <h:column> <f:facet name="header">Calendar</f:facet> <h:commandLink action="#{uploadWorkout.selectAthlete(athlete)}"> <h:outputText value="Calendar"/> </h:commandLink> </h:column> </h:form>
-
14. Re: ManyToOne OneToMany
jknotzke Aug 9, 2007 12:13 PM (in response to jknotzke)"jknotzke" wrote:
Ah ha.. very cool. So I have to do it "manually".. Never thought of that..
Ok, one small problem which you alluded to: i can't see the link. I had to encompass the h:commandLink in a form (otherwise it would not deploy. The code now looks like:
<h:form> <h:column> <f:facet name="header">Calendar</f:facet> <h:commandLink action="#{uploadWorkout.selectAthlete(athlete)}"> <h:outputText value="Calendar"/> </h:commandLink> </h:column> </h:form>
Actually, nevermind.. I fixed it myself.. And guess what.. It freaking works!
Thanks David and thanks to all who helped out. Phew!