5 Replies Latest reply on Feb 12, 2009 4:36 AM by Monkey Den

    Exending EntityQuery

    Monkey Den Master

      I have 4 different persistence contexts in my application, and I'm extending EntityQuery for each of them so I can override getPersistenceContextName().  I was getting an IllegalStateException from this method:


      @Create
         public void validate()
         {
            if ( getEjbql()==null )
            {
               throw new IllegalStateException("ejbql is null");
            }
         }




      1. I wasn't aware that Seam invoked @Create methods recursively.

      2. This bit of code forces me to override getEjbql() because it doesn't give me a chance to call setEjbql().



      Is it necessary to have this restriction on @Create?  Why not call validate on getResultList(), getSingleResult(), etc.?


      Thanks

        • 1. Re: Exending EntityQuery
          Monkey Den Master

          Also, can someone tell me why the @Factory method isn't being executed in this class?  The functional goal is to, at app startup, outject a static list (suffixes) to application context.  It appears that Seam is ignoring the annotations in this class.  Note that StaticQueryController is a subclass of EntityQuery and only overrides getPersistenceContextName().  I suspect something in the EntityQuery or Query is interfering.


          I get this error:


          Caused by: org.jboss.seam.RequiredException: @Out attribute requires non-null value: suffixList.suffixes




          @Startup
          @Name("suffixList")
          @Scope(ScopeType.APPLICATION)
          public class SuffixList extends StaticQueryController<Suffix> {
          
              private static final String EJBQL = "SELECT s FROM Suffix s";
          
              @Out(scope=ScopeType.APPLICATION)
              private List<Suffix> suffixes;
          
              @Factory("suffixes")
              public void load() {
                  suffixes = Collections.unmodifiableList(getResultList());
                  log.debug("Found #0 suffixes", suffixes.size());
              }
          
              @Override
              public String getEjbql(){
                  return SuffixList.EJBQL;
              }
          
              public SuffixList() {
                  setEjbql(EJBQL);
                  setOrder("id");
              }
          }
          



          Thanks

          • 2. Re: Exending EntityQuery
            Stuart Douglas Master

            Not sure about the first question.
            With the second question you are mixing @Out and @Factory. I think what you really want is @Unwrap. As it is the load() method will only be called if someone requests the value of suffixes either via EL or @In(create=true). Try this:



            @Startup
            @Name("suffixes")
            @Scope(ScopeType.APPLICATION)
            public class SuffixList extends StaticQueryController<Suffix> {
            
                private static final String EJBQL = "SELECT s FROM Suffix s";
            
            
                @Unwrap
                public List<Suffix> load() {
                    return Collections.unmodifiableList(getResultList());
                    //log.debug("Found #0 suffixes", suffixes.size());
                }
            
                @Override
                public String getEjbql(){
                    return SuffixList.EJBQL;
                }
            
                public SuffixList() {
                    setEjbql(EJBQL);
                    setOrder("id");
                }
            }
            
            


            • 3. Re: Exending EntityQuery
              Monkey Den Master
              I think what you really want is @Unwrap.

              Hi Stuart,
              Thanks for the response.  That's how I originally expected @Unwrap would behave.  There is one problem with that, however.  What actually happens is the wrapper class is outjected to the specified scope, not the result of the @Unwrap method.  Use of the @Unwrap annotation implies that you are not interested in the wrapper class.  I would find my expected behavior of @Unwrap to be very useful.  Maybe it's a bug, maybe it's a feature request.

              • 4. Re: Exending EntityQuery
                Stuart Douglas Master

                The simple way is to put an @Create method on you bean and manually stuff it into the application context (I think it is something like Contexts.getApplicationContext.set()). You could also create another application scoped @Startup component that tries to inject suffixes with create=true. Either way don't worry about the @Out annotation.

                • 5. Re: Exending EntityQuery
                  Monkey Den Master

                  I tried the former, but the issue I mentioned in the original post precludes this.  The Query class (parent of EntityQuery) steals the @Create annotation, simply to validate the ejbql property.  Seam does not allow multiple @Create methods in the hierarchy. 


                  I was already considering the latter suggestion and ended up going with it.  However, the expected behavior I mentioned above would have been much more slick.  Thanks for spending the time.