8 Replies Latest reply on Jun 14, 2010 9:55 AM by sean.tozer

    Adding a field from another table in the search panel

    anitha.nagani.raj.gmail.com
      Hello

      I have generated a seam application using seam gen. I have two tables site and location. Site is at the higher level in the hierarchy.I have a field 'name' in location table. I want to include this name field from location table in site search filter and search according to that. How to do this?


      My site.java looks like this
      public class Site implements java.io.Serializable {
      private Set<Location> locations = new HashSet<Location>(0);

      public Site(Set<Location> locations {
      this.locations = locations;
      }

      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "site")
      public Set<Location> getLocations() {
                return this.locations;
           }

           public void setLocations(Set<Location> locations) {
                this.locations = locations;
           }
      }
        • 1. Re: Adding a field from another table in the search panel
          anitha.nagani.raj.gmail.com
          Ok.. now i added few things in my java file, .xhtml file and .xml file

          SiteList.java:

          public Site getSite(){
               site.setLocations(locations);
               return site;
          }


          private Set<Location> locations;

          public Location getLocations()
          {
               return (Location) this.locations;
          }
          public Location setLocations(Location locations)
          {
               return (Location) (this.locations=(Set<Location>) locations);
          }

          Here is my restriction for that field in SiteList.java
          "lower(site.locationlocationId) like(concat(#{siteList.locations.locationId}, '%'))"

          SiteList.xhtml:
          <s:decorate template="layout/edit.xhtml">
                      <ui:define name="label">Location Name</ui:define>
                      <h:inputText id="locationName" value="#{siteList.locations.locationId}"/>
                      </s:decorate>

          SiteList.page.xml:
          <param name="locationName" value="#{siteList.locations.locationId}"/>


          Now, if i click on search button on then the debug page says
          "/SiteList.xhtml @41,86 value="#{siteList.locations.locationId}": Target Unreachable, 'locations' returned null on 'org.domain.user.session.SiteList_$$_javassist_seam_3'"



          What changes should i make to get rid of that error?
          • 2. Re: Adding a field from another table in the search panel
            sean.tozer

            Well, there's a few initial issues I see. For instance, calling a method setLocations(..) generally implies that you'll be setting locations to something, not that you'll be returning a set of locations. That'll be a maintenance nightmare if you stick with that convention.


            You also seem to be confusing sets with instances. The locations variable is a set of locations, but in getLocations, you try to cast it to an instance of a location by using (Location). getLocations should really return a Set<Location>, since that's what it is. At best, that method will only ever return a class cast exception as written.


            As a first pass, I'd change to something more like this:



            SiteList.java:

            public Site getSite(){
            site.setLocations(locations);
            return site;
            }

            private Set<Location> locations;

            public Set<Location> getLocations()
            {
            return this.locations;
            }

            public void setLocations(Set<Location> locations)
            {
            this.locations = locations);
            }


            I think there's still a fair number of underlying issues here, though, but that should at least be a start.

            • 3. Re: Adding a field from another table in the search panel
              sean.tozer

              Sorry, formatting got eaten. I just noticed as well that getSite() had a completely unrelated side-effect of setting the location of the site. Don't do that. It's a getter, all it should do is get.


              SiteList.java: 
              
              public Site getSite()
              { 
                  return site; 
              } 
              
              private Set<Location> locations; 
              
              public Set<Location> getLocations() 
              { 
                  return this.locations; 
              } 
              
              public void setLocations(Set<Location> locations) 
              { 
                  this.locations = locations); 
              }



              • 4. Re: Adding a field from another table in the search panel
                sean.tozer

                I also kind of suspect that


                lower(site.locationlocationId) like(concat(#{siteList.locations.locationId}, '%'))


                isn't going to work as a restriction, because what you're looking for is actually part of a separate table. You might be able to get the EntityQuery to figure out something like that, but I haven't actually tried. I've only used EntityQueries for very simple cases, and then I've gone to lucene searches for everything more complicated.


                You could always try writing the sql query manually and just returning the result set.

                • 5. Re: Adding a field from another table in the search panel
                  anitha.nagani.raj.gmail.com

                  Thanks for the reply Sean,


                  I'll look into what you have said and get back to you.

                  • 6. Re: Adding a field from another table in the search panel
                    bking007

                    Anitha,


                    Were you able to resolve the search functionality issue. I have encountered the similar issue like you. I am stuck at the point where I need to add another field from a related table in the search filter. I think it is possible using JPA entitymanager object, but if we use that, then we cannot use Seam entityquery methods like resultcount, paginated, etc in xhtml page. Pls lemme know!

                    • 7. Re: Adding a field from another table in the search panel
                      anitha.nagani.raj.gmail.com

                      Hi, Even i'm not able to solve this issue. Anybody please help.

                      • 8. Re: Adding a field from another table in the search panel
                        sean.tozer

                        Here's an example of a search I've got in my code, for doing a lookup. It performs a match on two fields in the root object as well as a field in an associated object (synonym in this case).


                             private String queryString = "select a from Allele a left join fetch a.accessions left join a.synonyms syn " +
                                  "WHERE a.name like :name OR a.symbol like :symbol OR syn.synonym like :synonym";



                             
                        @SuppressWarnings("unchecked")
                             public List getAlleles() {
                                  System.out.println("Getting Alleles");
                                  String searchString = Faces.var("searchString", String.class);
                             
                                  Query query = MGIEntityManager.createQuery(queryString);
                                  query.setParameter("name", "%" + searchString + "%");
                                  query.setParameter("symbol", "%" + searchString + "%");
                                  query.setParameter("synonym", "%" + searchString + "%");
                                  List results = query.getResultList();
                                  return results;
                             }
                        



                        If you really wanted to use an EntityQuery object of some kind, you could override the parsing method in your subclass. I think it should be getRenderedEjbql, but I'm not sure about that. I haven't tried it.


                        Of course, returning a List would still get you access to .size() and associated methods. It'd get you a start.