7 Replies Latest reply on Oct 29, 2009 3:18 AM by Nikolay Elenkov

    EntityManager is always NULL

    Charlie B Newbie

      Hi,


      I am new to Seam Framework, and im implementing a simple application with a few forms.
      I used seam-gen to get me started, and now I am adding a few of my own custom pages.


      The problem I am having is with the @In EntityManager entityManager injection into my action beans.


      If I create a new simple action bean, I can use the above line without any problems.
      However, if I have a simple bean that implements anything else, such as TreeNode , whenever I try to use entityManager, it always comes back NULL, and I cannot execute any SQL.


      Im not sure why this is. Is there anything im missing as to where you can/cannot inject @In EntityManager entityManager??


      I also noticed that on the seam-gen generated beans that extend EntityHome<T>, entityManager is also always NULL.


      Im sure there is a simple explanation for this...but I cannot find the answer.
      Can anyone offer any insight?


      Thanks in advance.


      Charlie

        • 1. Re: EntityManager is always NULL
          Nicklas Karlsson Master

          Show components.xml, your bean and how you are aquiring it (you won't get injection if you use new()). Anything in the logs?

          • 2. Re: EntityManager is always NULL
            Charlie B Newbie

            Thanks for the quick reply Nicklas.


            Here is my components.xml:




            <?xml version="1.0" encoding="UTF-8"?>
            <components xmlns="http://jboss.com/products/seam/components"
                        xmlns:core="http://jboss.com/products/seam/core"
                        xmlns:persistence="http://jboss.com/products/seam/persistence"
                        xmlns:drools="http://jboss.com/products/seam/drools"
                        xmlns:bpm="http://jboss.com/products/seam/bpm"
                        xmlns:security="http://jboss.com/products/seam/security"
                        xmlns:mail="http://jboss.com/products/seam/mail"
                        xmlns:web="http://jboss.com/products/seam/web"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xsi:schemaLocation=
                            "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
                             http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.2.xsd
                             http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.2.xsd
                             http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.2.xsd
                             http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.2.xsd
                             http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.2.xsd
                             http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.2.xsd
                             http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">
            
               <core:init debug="@debug@" jndi-pattern="@jndiPattern@"/>
            
               <core:manager concurrent-request-timeout="500"
                             conversation-timeout="120000"
                             conversation-id-parameter="cid"
                             parent-conversation-id-parameter="pid"/>
            
               <!-- Make sure this URL pattern is the same as that used by the Faces Servlet -->
               <web:hot-deploy-filter url-pattern="*.seam"/>
            
               <!-- If you are still using JBoss 4, uncomment this to have you PU started -->
               <!-- <persistence:entity-manager-factory name="entityManagerFactory"
                                  persistence-unit-name="koncentrator"
                                              installed="@seamBootstrapsPu@"/>-->
                 
               <persistence:managed-persistence-context name="entityManager" auto-create="true"
                                      entity-manager-factory="@seamEmfRef@"
                                  persistence-unit-jndi-name="@puJndiName@"/>
            
               <drools:rule-base name="securityRules">
                  <drools:rule-files><value>/security.drl</value></drools:rule-files>
               </drools:rule-base>
            
               <security:rule-based-permission-resolver security-rules="#{securityRules}"/>
            
               <security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true"/>
            
               <event type="org.jboss.seam.security.notLoggedIn">
                  <action execute="#{redirect.captureCurrentView}"/>
               </event>
               <event type="org.jboss.seam.security.loginSuccessful">
                  <action execute="#{redirect.returnToCapturedView}"/>
               </event>
            
               <mail:mail-session host="localhost" port="25"/>
            
               <!-- For use with jBPM pageflow or process management -->
               <!--
               <bpm:jbpm>
                  <bpm:process-definitions></bpm:process-definitions>
                  <bpm:pageflow-definitions></bpm:pageflow-definitions>
               </bpm:jbpm>
               -->
               
            </components>



            From my testing and reading, it seems that EntityManager is either NULL or not NULL depending on when and where a call to a bean property is made.


            I have a sample bean named SomeAction (see below). This has two simple list properties.
            groups is setup via a factory method, and rendered to view like so:




            <rich:dataGrid var="_group" value="#{groups}" columns="1">
                           <rich:panel>
                                <f:facet name="header">
                                     <h:outputText value="#{_group.id}" />
                                </f:facet>
                                <h:outputText  value="#{_group.descrption}" />
                           </rich:panel>
                      </rich:dataGrid> 



            While the sites list is retrieved through a 'get' method and rendered in the view like so:



            <rich:dataGrid var="_site" value="#{someAction.sites}" columns="1">
                           <rich:panel>
                                <f:facet name="header">
                                     <h:outputText value="#{_site.id}" />
                                </f:facet>
                                <h:outputText  value="#{_site.descrption}" />
                           </rich:panel>
                      </rich:dataGrid> 




            Groups is retrieved via entityManager without problems...however, when i try to get sites, entityManager is NULL.


            Most of my code is for test purposes...but im guessing the error of NULL has to do with the context/scope in which the entityManager is called.
            Is calling a property using a 'get' method, in a different context to using a @Factory method?


            Any info you can provide which I seem to have missed in the doco is much appreciated.


            Here is the SomeAction bean:



            package au.com.statewater.koncentrator.action;
            
            import java.util.List;
            
            import javax.persistence.EntityManager;
            
            import org.jboss.seam.ScopeType;
            import org.jboss.seam.annotations.Factory;
            import org.jboss.seam.annotations.In;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.annotations.Out;
            import org.jboss.seam.annotations.Scope;
            import org.jboss.seam.annotations.datamodel.DataModel;
            
            import au.com.statewater.koncentrator.model.Group;
            import au.com.statewater.koncentrator.model.Site;
            
            @Name("someAction")
            public class SomeAction {
                 
                 public SomeAction() {
                      setupSites();
                 }
                 
                 @In
                 private EntityManager entityManager;
                 
                 @Out
                 private List<Group> groups;
                 
                 @Out
                 private List<Site> sites;
                 
                 @Factory("groups")
                 public void setupGroups() {
                      groups = entityManager.createQuery("select g from Group g").getResultList();
                 }
                 
                 public void setupSites() {
                      sites = entityManager.createQuery("select s from Site s").getResultList();
                 }
                 
                 public List<Site> getSites() {
                      return this.sites;
                 }
            }





            Thanks for your help.
            Charlie





            • 3. Re: EntityManager is always NULL
              Nicklas Karlsson Master

              Well, you have the


              @In
              private EntityManager entityManager;
              



              which leads us to components.xml


                 <persistence:managed-persistence-context name="entityManager" auto-create="true"
                                        entity-manager-factory="@seamEmfRef@"
                                    persistence-unit-jndi-name="@puJndiName@"/>
              



              But there we have some build-scipt-markers @foo@ instead of real values. Have a look at a clean seam-genned project as how the SMPC is configured in the line EM -> EMF -> datasource.

              • 4. Re: EntityManager is always NULL
                Nikolay Elenkov Master

                Looks like it is null, because setupSites is called in the constructor. At that point injection has not happened yet, hence the error.
                You should do your initialization in the @Create method. Something like:


                public SomeAction() {
                  // no injection here, can't use EntityManager
                  //setupSites();
                }
                     
                @In
                private EntityManager entityManager;
                     
                ...
                
                @Create
                public void setupSites() {
                  sites = entityManager.createQuery("select s from Site s").getResultList();
                }
                
                

                • 5. Re: EntityManager is always NULL
                  Alex Skosyr Newbie

                  Do you have ejb-jar.xml file in you project (in the META-INF directory)?


                  It is necessary to define the Seam interceptor, that will make injection into your bean's field.


                  If you don't have it, you can get it in any examples, that present in Seam in example directory.

                  • 6. Re: EntityManager is always NULL
                    Charlie B Newbie

                    Thanks for your help and tips guys.


                    So it seems my problem is caused by the manner in which a method is called, or a attribute is initialized.


                    Is there any good place to have a read about injection, and the points in which it does, and does not occur?


                    Charlie


                    • 7. Re: EntityManager is always NULL
                      Nikolay Elenkov Master

                      The reference manual is always a good start: Bijection.
                      Also check 'Seam in Action'.