Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails 2.4 + Hibernate 4 + Searchable plugin = ClassNotFoundException: org.hibernate.impl.SessionFactoryImpl

Recently I was integrating a simple Grails application with the Searchable plugin. What I've found was that Searchable plugin does not work with Hibernate 4 library.

Here you can find a sample application that contains only clean Grails 2.4 app with only Searchable plugin added - https://github.com/wololock/grails-searchable-example

When I run this app with:

runtime ":hibernate4:4.3.5.5"

dependency, it wont start and throws an exception:

ClassNotFoundException: org.hibernate.impl.SessionFactoryImpl

What I have found already is that in the Hibernate4 SessionFactoryImpl was moved to the org.hibernate.internal package and it seems like Compass looks for this class in the old location:

2014-10-11 19:41:58,142 [localhost-startStop-1] ERROR context.GrailsContextLoaderListener  - Error initializing the application: org/hibernate/impl/SessionFactoryImpl
Message: org/hibernate/impl/SessionFactoryImpl
Line | Method
->>   95 | injectLifecycle in org.compass.gps.device.hibernate.lifecycle.DefaultHibernateEntityLifecycleInjector

Switching back to the:

runtime ":hibernate:3.6.10.17"

and changing

cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'

in the DataSource.groovy resolves the problem.

My question is: is there any workaround to use Searchable plugin with Hibernate 4 or we have to wait or fix the issue in Compass/Searchable source code? How did you deal with that problem in your Grails application? I will be grateful for your tips.

like image 434
Szymon Stepniak Avatar asked Oct 11 '14 18:10

Szymon Stepniak


2 Answers

There were several package and class name changes between Hiberate 3.x and 4.x, so code that works with Hibernate 3.x won't work with 4.x except in rare cases. Beyond the name changes, there were big internal changes in how things work, so code that compiles won't necessarily run. App option #1 is to downgrade to Hibernate 3.x. The config settings for that are included and commented out (BuildConfig.groovy, DataSource.groovy), so this a very quick option. Obviously not an option if you depend on a feature added in 4.x, and this just delays the real problem until you have to upgrade Hibernate.

All plugins using Hibernate 3 need to be updated to support Hibernate 4, either as a replacement, or ideally supporting both using some cross-compile tricks or another 3rd party library. One plugin option that assumes users will eventually upgrade from 3.x is to create a 3.x branch and start a new major revision of the plugin (in the master branch) for Hibernate 4 and make the changes to get it working in 4.x. Use the 3.x branch to support security updates and very minor issues, but don't add new features. A lot of plugin authors will probably go this route.

In some cases yet another option makes the most sense - don't do anything. This applies to Searchable. Searchable uses http://www.compass-project.org/ which is effectively dead - its last release was 4 years ago. Shay Banon is now the CTO of http://www.elasticsearch.org/ I believe Shay stopped working on Compass and started Elasticsearch because it's impractical to scale Compass beyond a single server. It's possible to store the Lucene index in a database, but while that does give you a centralized single writer and one or more (with db clustering or similar) centralized reader(s), an optimized search server with custom protocols, etc. makes way more sense.

There's also Solr the consensus seems to be that Elasticsearch is preferred. The Solr Grails plugin hasn't been updated in 3 years, and the Elasticsearch plugin was getting moldy too, but recently Noam Tenne took over as the plugin lead and has done a lot of great work and he's done several releases in the last few months. Note that the old elasticsearch and elasticsearch-gorm plugins were merged and updated to create the new elasticsearch plugin.

Yet another option is to use Hibernate's own product, Hibernate Search. There's a plugin for that but it hasn't been updated since 2012. Selfishly this is my personal preference for you - choose this option, take over the plugin (assuming affirmative reply or no response from the original authors) and update it to be compatible with the latest Hibernate 4.x plugin. That would give us a good alternative to Elasticsearch.

Barring that, I think Elasticsearch is your best option.

like image 133
Burt Beckwith Avatar answered Oct 03 '22 17:10

Burt Beckwith


Burt gave very good description. Thanks for this.

I just want to add short hint. At this time Searchable plugin doesn't work with Hibernate 4.X.X. Try to downgrade your hibernate in the project to 3.X.X (hibernate:3.6.10.18)

So you will need: in DataSource.groovy

add/uncomment the following:

cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'

and delete/comment:

cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory'

in BuildConfig.groovy:

change Hibernate dependency to ":hibernate:3.6.10.18"

It works on my machine with such changes.

Hope it will help to somebody.

(I've found the answer here http://tiku.io/questions/4052527/does-the-searchable-plugin-work-with-grails-2-0-0-i-argue-no

like image 45
Sergei Dubinin Avatar answered Oct 03 '22 16:10

Sergei Dubinin