mstein / elasticsearch-grails-plugin

ElasticSearch grails plugin
Based on Graeme Rocher initial stub. Note that it is still in early stage.
Other
62 stars 164 forks source link

Problem in Hibernate sessions management #15

Closed germander closed 12 years ago

germander commented 12 years ago

Hi, and thank you for this useful plugin.

I think there is a serious bug related with the use of Hibernate sessions in the plugin.

First, this is how you can reproduce the bug: in a newly created, vanilla project, install elasticsearch plugin (tested with last release 0.17.8.1 as well as 0.18.7.1-SNAPSHOT). Create a simple domain class Book with a single property name (String), and mark it as searchable = true. Create a BookController with scaffolding activated. When the application is running, create a Book book0 and then edit it several times changing its name: book1, book2... book10. Then, if you reload its page several times, without further editing, most times the name displayed is book10 as expected, but some times you'll randomly get 'older' versions book5, book8, book2... If you remove the searchable = true statement or uninstall the plugin, the problem disappears.

After having performed some debugging, I found that, with the plugin installed, the Hibernate session bound to controller actions sometimes is pre-populated with the 'older versions' of the book instace. Even if the first thing that I do in an action is displaying the current session (log.debug sessionFactory.currentSession), sometimes it contains already the stale object. Hibernate sessions are being reused from a request to a different one, instead of having an empty, newly created session in each action, which is the case when the plugin is not installed.

The problem only happens after modifying an instance (e.g, in update scaffolded actions); if I restart the application and reload the show page several times, only the real, in-DB value is displayed, and the Hibernate sessions are never reused. After the first modification, I start having reused Hibernate sessions with old values. I tried setting the disableAutoIndex parameter to true, but the problem is still there.

I looked a bit at the plugin's code and I think the problem resides in the way AuditEventListener manages responds to hibernate events with threads. Maybe an explicit call to session.close() or session.flush() is needed, but I'm not sure. Please tell me if you need any further details.

germander commented 12 years ago

Also, it seems that the reused sessions often have their flushMode property set to MANUAL

mstein commented 12 years ago

I'll take a look when I can, are you using Grails 2.x or still using 1.3.x ? There are a few issue with Grails 2 right now, so we may have to refactor a few things. Anyways, thanks for the report.

germander commented 12 years ago

Hi, and thank you for looking into this. I am using Grails 2.0.1, and the bug was also present in Grails 2.0.0.

germander commented 12 years ago

Hi again,

Any updates in this issue? Thanks!

bhopek commented 12 years ago

Hi,

I'm using grails 2.0.4 and have the same problem. Did you get to something that can resolve this?

germander commented 12 years ago

Hi again,

Any updates in this issue? Thanks!

ph4t commented 11 years ago

Although the issue is closed, we still sometimes see the behavior described by germander... It less frequent but it still happens... I double checked that our version of plugins contains all changes from pull request #44 Does anyone else still experience this issue?

vsaar commented 11 years ago

I also still have this issue regularly. I sometimes have the impression that it occurs when domain entities are manipulated concurrently, but since I can't reproduce it reliably, I don't know for sure. Any plans to look into this again? Would be much appreciated.

ttyusupov commented 11 years ago

We also met this issue in our project and found following cause - http://jira.grails.org/browse/GRAILS-10024

vsaar commented 11 years ago

@ttyusupov Thanks a lot for digging into this and reporting the bug! The issue definitely blocks any production use of the plugin, which is a real pity. Do you know of any way to work around this in the plugin itself?

ttyusupov commented 11 years ago

@vsaar , yes there is a workaround to remember HibernatePersistenceInterceptor.participate flag before calling HibernatePersistenceInterceptor.init and restore it after HibernatePersistenceInterceptor.destroy. This is a private field, so you will need to use java reflection API to do that.

mstein commented 11 years ago

Hi, first of all, thanks for digging in this issue @ttyusupov ! (I know, I'm quite late). The grails issue seems to have been fixed in the latest Grails 2.2.2 release. That being said, do you think you could submit a pull request with a workaround for grails 2.2.1 & anterior if you already have that?

ttyusupov commented 11 years ago

Hi @mstein,

Sorry for late response. I have checked the code - we updated ThreadWithSession and IndexRequestQueue. Our fork is based on 0.19.4 and since that version IndexRequestQueue was updated, so I can't just fork off latest version of plugin and cherrypick workaround - it requires merge, resolve conflicts and retest.