4 Replies Latest reply on Jun 23, 2010 4:52 AM by Sean Wu

    FullTextEntityQuery

    benoit moraillon Newbie

      Hi,
      i'm seraching for a FullTextEntityQuery bean which could perform hibernate full
      text search as EntityQuery does with restriction.


      Does it exists ?


      Best Regards.



        • 1. Re: FullTextEntityQuery
          Florian Petersen Newbie

          Hi Benoit!
          Did you find out how to do it? To be precise i want to use some kind of EntityQuery to mix EJBQL and Lucene queries into one...
          Thanks a lot, best regards
          Flo

          • 2. Re: FullTextEntityQuery
            Bernard Labno Master

            Abstract base for quries :


            public abstract class FullTextSearchEntityQuery<T> extends EntityQuery<T> {
            
                private Long resultSize;
            
                public FullTextSearchEntityQuery() {
                    setEjbql("hehehe ! I'm cheating EntityQuery.validate() and others where query=#{search.query}");
                }
            
                /**
                 * Subclasses must return field names on which search should be conducted.
                 */
                protected abstract String[] getFields();
            
                @Override
                protected Query createQuery() {
                    parseEjbql();
                    evaluateAllParameters();
                    FullTextQuery query = ((FullTextEntityManager) getEntityManager()).createFullTextQuery(createLuceneQuery(Search.instance().getQuery(), getFields()), getEntityClass());
                    if (getFirstResult() != null) {
                        query.setFirstResult(getFirstResult());
                    }
                    if (getMaxResults() != null) {
                        query.setMaxResults(getMaxResults());
                    }
                    return query;
                }
            
                @Override
                public Long getResultCount() {
                    if (isAnyParameterDirty()) {
                        resultSize = (long) ((FullTextQuery) createQuery()).getResultSize();
                    }
                    return resultSize;
                }
            
                private org.apache.lucene.search.Query createLuceneQuery(String words, String[] fields) {
                    QueryParser parser = new MultiFieldQueryParser(fields, new SimpleAnalyzer());
                    org.apache.lucene.search.Query luceneQuery;
                    try {
                        luceneQuery = parser.parse(words);
                    }
                    catch (org.apache.lucene.queryParser.ParseException e) {
                        throw new IllegalArgumentException(
                                "Unable to parse search entry into a Lucene query", e);
                    }
                    return luceneQuery;
            
                }
            }



            And here we declare particular query :


            @Name("locationFullTextSearch")
            public class LocationFullTextSearch extends FullTextSearchEntityQuery<Location> {
            
                private String[] fields = new String[]{"name"};
            
            
                protected String[] getFields() {
                    return fields;
                }
            
            }




            Have you noticed Search.instance() in FullTextSearchEntityQuery ? This is it, but you can pass query string any other way.


            @Name("search")
            public class Search {
            
                @Logger
                private Log log;
                private String query;
            
            
                public static Search instance() {
                    return (Search) Component.getInstance(Search.class);
                }
            
                public String getQuery() {
                    return query;
                }
            
                public void setQuery(String query) {
                    if (query != null && !query.equals(this.query)) {
                        log.info("Query:#0", query);
                    }
                    this.query = query;
                }
            
            }

            • 3. Re: FullTextEntityQuery
              Florian Petersen Newbie
              Okay, so nothing ootb, but extending EntityQuery seems also straightforward to me. I hope there will be some more ootb integration in one of the next Seam releases...
              Thanks + regards
              • 4. Re: FullTextEntityQuery
                Sean Wu Newbie


                I do think you did not post all the code. You invoke getEntityClass() method in the createQuery(), but I can not find it in your code. I guess the reason you use a getEntityClass() method to get the class type hibernate search needs is due to the fact we can get the Entity Class type during runtime because we use a generic type <T> here. So, I guess you have a private field of Class<T> entity in your code to fix this problem.