7 Replies Latest reply on Jul 25, 2007 11:05 AM by Brian Smith

    Bijection clarification

    Brian Smith Apprentice

      Would it be correct to say that bijection (@In, @Out) is strictly for passing components between the jsf and ejb/pojo layer? Can bijection be used to pass components from sfsb to sfsb? Or should I rely on passing the component as a parameter to a method call to the second ejb (sfsb) from the first?

      I know this is very broad but right now I am under the impression that bijection is just shoving my components out into some magical place with @In and calling them back out with @Out. This "magical place" being reachable from both the jsf and ejb layers. I am just looking for some futher understanding on what is going on and the intended purpose(s) of bijection.

        • 1. Re: Bijection clarification
          Monkey Den Master

          The most basic description is that @In and @Out just replaces the glue code you have to write to get things out of some context (Session, Request, Application and, in Seam, Conversation scopes). Rather than having:

          String param = request.getSession().get("param");

          you have:

          @In(scope=ScopeType.SESSION)
          String param;

          Be careful though. I realized (sort of late) that bijection apparently happens for value-binding method calls too, so if you're injection a lot, you will pay a price in RENDER_RESPONSE. In our case, we had a huge form with many validation error messages from the resource bundle.

          • 2. Re: Bijection clarification
            Monkey Den Master

            BTW, to answer your question, passing from sfsb to sfsb works the same way. There is some context in between which has the value you're injecting, making it available to any Seam component who is interested in it.

            • 3. Re: Bijection clarification
              Brian Smith Apprentice

              Ok, what I am struggling with is I have a component, Address, that is just a POJO, not an entity. It is submitted via a form. It's inject into sfsb A which then outjects it. By the time sfsb B comes along, the Address component is null. Both A and B exist in a long running conversation. Address never even shows up on the seam debug page.

              Thanks for your help.

              • 4. Re: Bijection clarification
                Brian Smith Apprentice

                Ok, this is weird. I had Address declared like this

                //sfsb A
                
                @In(required=false)
                @Out(required=false)
                private Address address
                
                


                and Address kept nulling or falling out of scope more likley

                when I changed it to this

                //sfsb A
                
                @In(required=false)
                @Out(scope=ScopeType.CONVERSATION, required=false)
                private Address address
                
                


                it all works.

                I thought that components shared the same state as the sfsb which was Conversation by default.

                I am using Seam 1.3 Alpha


                • 5. Re: Bijection clarification
                  Monkey Den Master

                  This is still a gray area for me. I have not seen a clear and complete description of the implied scopes. Does it default to:

                  The scope of the bijected component, if any?
                  The bean which is injecting it?
                  Conversation unless specified otherwise?
                  Find in any scope?

                  Thus far, I have always specified a scope for @Out, to be clear, but outside of that personal style, it's trial and error.

                  • 6. Re: Bijection clarification
                    Brian Smith Apprentice

                    Ok, I am still having problems with Address getting injected into my second sfsb

                    Here is what is going on

                    A form is submitted to sfsb "addressLocator" via an actionListener on the a4j:commandButton

                    <h:form id="addressSearch_Form">
                     <h:panelGrid columns="2">
                     //Form inputs here bound to address fields
                     </h:panelGrid>
                     <a4j:commandButton actionListener="#{addressLocator.findAddressByAddress}"
                     value="#{messages['AddressLookup.search']}"
                     reRender="searchResults"/>
                    
                    ...searchResults here....
                    
                     <h:panelGrid columns="1" rendered="#{address != null}">
                     <h:outputText value="Address Not Found?"/>
                     <h:commandLink value="Create a Service Request with the address you entered above" action="createRequestFromAddress"/>
                     </h:panelGrid>
                    </form>


                    Here is the my first sfsb "AddressLocator"
                    @Stateful
                    @Name("addressLocator")
                    @Scope(ScopeType.CONVERSATION)
                    @SuppressWarnings("unchecked")
                    public class AddressLocatorAction implements AddressLocator {
                    
                     @In
                     private EntityManager entityManager;
                    
                     @In(required=false)
                     @Out(scope=ScopeType.CONVERSATION, required=false)
                     private Address address;
                    
                    
                     public AddressLocatorAction() {
                     }
                    
                     public void findAddressByAddress(ActionEvent event) {
                     //Uses address for query, address has value here
                     }


                    after a dataTable "searchResults" is reRendered, the commandLink is pressed which calls requestManager.createRequestFromAddress()

                    @Stateful
                    @Name("requestManager")
                    @Scope(ScopeType.CONVERSATION)
                    public class RequestManagerAction implements com.stlouiscity.csb.ejb.action.RequestManager {
                    
                     @In
                     private EntityManager entityManager;
                    
                     @In
                     private Address address;
                    
                    
                     public RequestManagerAction() {
                     }
                    
                     public void createRequestFromAddress() {
                     serviceRequest = new ServiceRequest();
                    
                     //This is a different address instance than was outjected
                     // by addressLocatorAction, fields are null
                     serviceRequest.setAddress(address);
                     }


                    The address component that is outjected from addressLocator is not the same instance that is injected into requestManager. I can see the orginal address component on the seam debug page but a different instance belongs to serviceRequest on the debug page. This is taking place in the scope of a long running conversation being managed by a jpdl pageflow.

                    Thanks again.

                    Thanks again.

                    • 7. Re: Bijection clarification
                      Brian Smith Apprentice

                      Ok got it working. It turns out Seam Bijection was not the culprit. I was trying to use an Embedded class in more than one entity, which I found out is a bad thing. I have not been able to find any documentation that says you can't do this but I'll leave that for a post on the Hibernate boards. Thanks again.