1 2 Previous Next 16 Replies Latest reply on Aug 9, 2007 12:19 PM by David Spark

    ManyToOne OneToMany

    Justin F. Knotzke Newbie


      Hi,

      I am using the CVS trunk and I cannot get a ManyToOne relationship working. I get the following error when deploying:

      org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.techsolcom.powermanager.Workout.workout in com.techsolcom.powermanager.Athlete.workouts
      


      My Code looks like this: Athlete.java

       @OneToMany(mappedBy="workout", cascade=CascadeType.REMOVE)
       private List<Workout> workouts = new ArrayList<Workout>();
      
       public List<Workout> getWorkouts()
       {
       return workouts;
       }
      
       public void setWorkouts(List<Workout> workouts)
       {
       this.workouts = workouts;
       }
      
      


      ..and Workout.java looks like this


       @ManyToOne
       @NotNull
       private Athlete athlete;
      
       public Workout(Athlete athlete)
       {
       this.athlete = athlete;
       }
      
      
       Any ideas ? I noticed in some of the examples, like the ContactList example that there are entries in components.xml.. No idea if that's the problem. Thanks
      
      
      


        • 1. Re: ManyToOne OneToMany
          Mike Pettypiece Newbie

          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
            Jose Rubio Newbie

            What's the error message you are getting?

            • 3. Re: ManyToOne OneToMany
              fhh Expert

               

              @OneToMany(mappedBy="workout", cascade=CascadeType.REMOVE)
               private List<Workout> workouts = new ArrayList<Workout>();
              


              You propably mean mappedBy="athlete".

              Regards

              Felix

              • 4. Re: ManyToOne OneToMany
                Justin F. Knotzke Newbie

                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
                  Samuel Doyle Apprentice

                  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 Expert

                     

                    @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
                      Justin F. Knotzke Newbie

                      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 error


                      
                      07: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 Newbie

                        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
                          Justin F. Knotzke Newbie

                           

                          "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 Newbie

                            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
                              Justin F. Knotzke Newbie

                               

                              "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 Newbie

                                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
                                  Justin F. Knotzke Newbie


                                  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
                                    Justin F. Knotzke Newbie

                                     

                                    "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!


                                    1 2 Previous Next