11 Replies Latest reply on Jan 21, 2008 10:56 AM by neilac333

    Seam with Hibernate Search

      I am using Hibernate Search in my Seam web application. All my unit tests and integration tests (using SeamTest), which are quite rigorous, are passing with flying colors. I should note that the tests are of two categories:

      1) My use of the Hibernate Search libraries outside of any container
      2) My use of Seam components that coordinate getting parameters and results to and from mock versions of my HS code

      Nowhere do I perform an integration test of Seam components with the real HS implementation. Perhaps I should have since when I try to use the functionality in my actual application, I get the following:

      java.lang.ClassCastException: org.jboss.seam.persistence.FullTextHibernateSessionProxy
       at org.hibernate.search.impl.FullTextSessionImpl.<init>(FullTextSessionImpl.java:70)
       at org.hibernate.search.Search.createFullTextSession(Search.java:21)
       at org.hibernate.search.jpa.impl.FullTextEntityManagerImpl.getFullTextSession(FullTextEntityManagerImpl.java:37)
       at org.hibernate.search.jpa.impl.FullTextEntityManagerImpl.createFullTextQuery(FullTextEntityManagerImpl.java:60)
       at persistence.search.SearchImpl.getAdvancedSearchResults(SearchImpl.java:185)
       at jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown Source)
       at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown Source)
       at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
       at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
       at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:31)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
       at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:46)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
       at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
       at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106)
       at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:155)
       at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:91)
       at persistence.search.SearchImpl_$$_javassist_1.getAdvancedSearchResults()Ljava.util.List;(SearchImpl_$$_javassist_1.java:???)
       at web.SearchAction.doAdvancedSearch(SearchAction.java:186)
       at jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown Source)
       at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown Source)
       at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
       at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
      


      What is interesting to me is that FullTextHibernateSessionProxy is a Seam class not part of the Hibernate Search library. According to this

      http://docs.jboss.com/seam/2.0.0.GA/api/org/jboss/seam/persistence/HibernateSessionProxy.html

      ...it looks like the class implements org.hibernate.Session. However, look here:

      http://anonsvn.jboss.org/repos/hibernate/search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java

      If I am correct, the instance of FullTextHibernateSessionProxy is being cast to org.hibernate.classic.Session, EventSource, and SessionImplementor while FullTextHibernateSessionProxy implements org.hibernate.Session, SessionImplementor, and not EventSource at all.

      Is my analysis correct? If so, is this a bug in the way Seam and HS collaborate? Most importantly, how can I work around this before I fall too far behind?

      Thanks for any insight.

        • 1. Re: Seam with Hibernate Search
          pmuir

          But FullTextHibernateSessionProxy implements FullTextSession, which does extend the classic Session.

          Post the code you are using to inject the session.

          • 2. Re: Seam with Hibernate Search

            I've run into this problem a while ago. I don't recall how I solved this. (Just trying to recall ->) this is reported on on HS forum or it's JIRA (cannot access these sites at this moment to provide concrete points, servers overloaded?) and is caused by behind-the-scene casting against an unimplemented interface. That's all I recall. Search there, make a postback to Pete, please.

            • 3. Re: Seam with Hibernate Search

              First off, I am using JPA powered by Hibernate rather than Hibernate itself. The following represents what I am doing:

              @In
              private EntityManager em;
              .
              .
              .
              fullTextEntityManager = Search.createFullTextEntityManager(em);
              .
              .
              .
              fullTextQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, Widget.class);
              


              And here is the persistence.xml:

              <properties>
               <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9Dialect"/>
               <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/>
               <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WeblogicTransactionManagerLookup"/>
               <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
               <property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider"/>
               <property name="hibernate.search.default.indexBase" value="C:/persistence/search/indexes"/>
               <property name="hibernate.search.analyzer" value="org.apache.lucene.analysis.standard.StandardAnalyzer"/>
              </properties>
              


              Let me know what else you need.

              Thanks.

              • 4. Re: Seam with Hibernate Search
                pmuir

                I'm no expert, but the examples do this:

                @In
                private FullTextEntityManager entityManager;
                
                ...
                
                entityManager.createFullTextQuery(...);


                • 5. Re: Seam with Hibernate Search

                  True enough. When combined with Seam, HS allows you to inject the FullTextEntityManager directly.

                  However, what I am doing is still correct--at least theoretically. It is basically what is found in the DVDStore example but with one catch. In that case, the JPA EntityManager is injected by Seam, but the EM is really the superinterface abstraction of an FTEM. So the FTEM is obtained by simply downcasting the EM.

                  In my case, the call to Search.createFullTextEntityManager(em) does the same thing. If the em parameter is actually an FTEM instance, then the downcast is returned. If it isn't, some other magic happens to turn the EM into an FTEM. If you are really bored, check out Emmanuel's code yourself.

                  Yet having said all this, if I can't actually figure out what's going on, I might just have the FTEM injected and see what happens.

                  Thanks.

                  • 6. Re: Seam with Hibernate Search

                    I forgot to mention also that if you look at the top of the stack trace, all the fun starts with the class org.hibernate.search.jpa.impl.FullTextEntityManagerImpl. If that is the class of object that is supposed to be injected with

                    @In
                    private FullTextEntityManager entityManager
                    


                    then it would seem that I obtained the FullTextEntityManager. I suppose the issue is if in fact I got the right FullTextEntityManager implementation by doing it the current way. Or if "my" way somehow contradicts the expectation of Gavin's code in FullTextHibernateSessionProxy.

                    Thanks.


                    • 7. Re: Seam with Hibernate Search

                      Incidentally, it looks also like the instance of FullTextHibernateSessionProxy is what is returned from the call to em.getDelegate() when Hibernate Search is enabled. Is this so? I see nothing in the documentation about this class, so what purpose does it serve?

                      Thanks.

                      • 8. Re: Seam with Hibernate Search
                        pmuir

                        I've asked Emmanuel to take a look at this thread as this is really his baby.

                        • 9. Re: Seam with Hibernate Search

                          I appreciate that. I only asked here since Gavin wrote that class, and it is outside Hibernate Search proper.

                          Thanks.

                          • 10. Re: Seam with Hibernate Search
                            epbernard

                            Gavin wrote the class but I had a glass of wine next to him when he did it, so that qualifies me as author as well :)

                            Let's move back this thread to the Hibernate Forum (the one you started already). Long story short, your analysis is correct except that Search.createFTEM will not return just the downcasted version since the proxy is not a FTEMImpl. There is clearly a bug becauser the proxy does not implement EventSource but I would like to understand why it works in DVDStore before fixing that.
                            Anyway let's move that discussion here: http://forum.hibernate.org/viewtopic.php?t=982853

                            • 11. Re: Seam with Hibernate Search

                              OK, I will pack my things up and head back over there.

                              Thanks.