Binding Hibernate Session to New Thread

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Binding Hibernate Session to New Thread

jonsinfinity
I have an asynchronous controller action that calls a number of services that manipulate a handful of domain classes. In order to free up the user I am running this code in a separate thread since it can take some time to process. The issue is that the Hibernate Session is not bound to the new thread and I cannot save changes to the domain objects in the thread.

def asyncAction = {

    Thread.start {
               
        Service calls here ...
                       
    }
}

Here is the exception message that I get:
Exception in thread "Thread-43" org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

For dirty little fixes I've tried passing in the session factory to the services and creating a new hibernate session and a few similar things. But they were a no go.

Does anyone have any idea how to bind the current session to a new thread? Or any other ideas on how to get arround this?

Thanks in advance,
Jon



Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

Jason Davis
pretty much all over google:
http://grails.org/doc/latest/ref/Domain%20Classes/withTransaction.html

might checkout quartz fwiw

On Tue, Jan 17, 2012 at 8:59 AM, jonsinfinity <[hidden email]> wrote:

> I have an asynchronous controller action that calls a number of services that
> manipulate a handful of domain classes. In order to free up the user I am
> running this code in a separate thread since it can take some time to
> process. The issue is that the Hibernate Session is not bound to the new
> thread and I cannot save changes to the domain objects in the thread.
>
> def asyncAction = {
>
>    Thread.start {
>
>        Service calls here ...
>
>    }
> }
>
> Here is the exception message that I get:
> Exception in thread "Thread-43" org.hibernate.HibernateException: No
> Hibernate Session bound to thread, and configuration does not allow creation
> of non-transactional one here
>
> For dirty little fixes I've tried passing in the session factory to the
> services and creating a new hibernate session and a few similar things. But
> they were a no go.
>
> Does anyone have any idea how to bind the current session to a new thread?
> Or any other ideas on how to get arround this?
>
> Thanks in advance,
> Jon
>
>
>
>
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Binding-Hibernate-Session-to-New-Thread-tp4303722p4303722.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

Jonathan Rosenberg
In reply to this post by jonsinfinity
You should be able to get a hold of the SessionFactory & just create a
new session to use.  You mwon;t have any of the GORM magic methods
available, however.

I've done things like this before:

def sessionFactory

...

def session = sessionFactory.openSession();

... use session ...

What went wrong when you tried this?  Mayube you have to get a hold of
the sessionFactory wihtout the benefit of DI?

--
Jonathan Rosenberg
Founder & Executive Director
Tabby's Place, a Cat Sanctuary
http://www.tabbysplace.org/


On Tue, Jan 17, 2012 at 10:59 AM, jonsinfinity <[hidden email]> wrote:

> I have an asynchronous controller action that calls a number of services that
> manipulate a handful of domain classes. In order to free up the user I am
> running this code in a separate thread since it can take some time to
> process. The issue is that the Hibernate Session is not bound to the new
> thread and I cannot save changes to the domain objects in the thread.
>
> def asyncAction = {
>
>    Thread.start {
>
>        Service calls here ...
>
>    }
> }
>
> Here is the exception message that I get:
> Exception in thread "Thread-43" org.hibernate.HibernateException: No
> Hibernate Session bound to thread, and configuration does not allow creation
> of non-transactional one here
>
> For dirty little fixes I've tried passing in the session factory to the
> services and creating a new hibernate session and a few similar things. But
> they were a no go.
>
> Does anyone have any idea how to bind the current session to a new thread?
> Or any other ideas on how to get arround this?
>
> Thanks in advance,
> Jon
>
>
>
>
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Binding-Hibernate-Session-to-New-Thread-tp4303722p4303722.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

basejump (Josh)
In reply to this post by jonsinfinity
use the executor plugin. its was created for your use case.
Even if you do not use the plugin, your should avoid trying to manage your own threads.
Since java 1.5 the executorservice framework was added to do it in a correct and standard way. there are links to more info on the executor github page

On Jan 17, 2012, at 9:59 AM, jonsinfinity wrote:

I have an asynchronous controller action that calls a number of services that
manipulate a handful of domain classes. In order to free up the user I am
running this code in a separate thread since it can take some time to
process. The issue is that the Hibernate Session is not bound to the new
thread and I cannot save changes to the domain objects in the thread.

def asyncAction = {

   Thread.start {

Service calls here ...

   }
}

Here is the exception message that I get:
Exception in thread "Thread-43" org.hibernate.HibernateException: No
Hibernate Session bound to thread, and configuration does not allow creation
of non-transactional one here

For dirty little fixes I've tried passing in the session factory to the
services and creating a new hibernate session and a few similar things. But
they were a no go.

Does anyone have any idea how to bind the current session to a new thread?
Or any other ideas on how to get arround this?

Thanks in advance,
Jon





--
View this message in context: http://grails.1312388.n4.nabble.com/Binding-Hibernate-Session-to-New-Thread-tp4303722p4303722.html
Sent from the Grails - user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

pledbrook
> use the executor plugin. its was created for your use case.
> http://grails.org/plugin/executor
> Even if you do not use the plugin, your should avoid trying to manage your
> own threads.
> Since java 1.5 the executorservice framework was added to do it in a correct
> and standard way. there are links to more info on the executor github page

More importantly, the plugin ensures that the session is correctly
managed for the threads that it starts, so GORM works correctly. And
that means GORM/MongoDB etc, not just GORM/Hibernate.

Peter

--
Peter Ledbrook
Grails Advocate
SpringSource - A Division of VMware

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

jonsinfinity
Thanks for the quick replies : )

I've tried both the plugin and the .withTransaction suggestions both on their own and in conjunction. Either way i now get the following exception:

util.JDBCExceptionReporter failed batch
events.PatchedDefaultFlushEventListener Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update

How do I make sure that the session is synchronized?

Thanks again,
Jon
Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

basejump (Josh)
Please post an example of what you are doing with the executor plugin to get that exception?

On Jan 17, 2012, at 12:31 PM, jonsinfinity wrote:

> Thanks for the quick replies : )
>
> I've tried both the plugin and the .withTransaction suggestions both on
> their own and in conjunction. Either way i now get the following exception:
>
> util.JDBCExceptionReporter failed batch
> events.PatchedDefaultFlushEventListener Could not synchronize database state
> with session
> org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch
> update
>
> How do I make sure that the session is synchronized?
>
> Thanks again,
> Jon
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Binding-Hibernate-Session-to-New-Thread-tp4303722p4304256.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

jonsinfinity
This is in the controller

executorService.execute {
               
        ResultSet rs = productInterface.getResultSetForSQLString(tableName, sqlString)
                       
        String filePath = CSVConverterService.convertResultSetToCSV(rs, tableName)
                       
        MessagingService messagingService = new MessagingService()
                       
        messagingService.sendDownloadReadyMessage(user, filePath)
                       
}

This is in the messaging service

Message message = new Message(from:User.findByUserId(userId), subject:subject, messageBody:messageBody,
                        isRead:false, sentDate:Calendar.getInstance().getTime()).save()
                       
       
        User.withTransaction { status -> //This is where it's craping out
        User user2 = User.findByUserId(user.userId)
                       
        user2.messages.add(message)
                       
        user2.save() // have also tried merge()
}

Sorry if there is a code tag - couldn't find one.
Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

basejump (Josh)
your code is a bit strange to me as what you are calling a Service does not look like a grails service at all.
if you setup MessagingService as a standard transactional grails service then it should flush for you at the end of your sendDownloadMessage
we try to wrap our logic in a service or other method so we can test it.
you have a runAsync method available in the controller
so it would look like
runAsync{
        someService.sendDownloadMessage() //<-do all your logic in here
}

otherwise, you can try user2.save(flush:true) to clear up that error

for code formatting I paste my snippet into a blank editor(textmate for me) get it formatted and then paste back into the list email with a fixed font type of (monaco)

On Jan 17, 2012, at 1:24 PM, jonsinfinity wrote:

> This is in the controller
>
> executorService.execute {
>
> ResultSet rs = productInterface.getResultSetForSQLString(tableName,
> sqlString)
>
> String filePath = CSVConverterService.convertResultSetToCSV(rs, tableName)
>
> MessagingService messagingService = new MessagingService()
>
> messagingService.sendDownloadReadyMessage(user, filePath)
>
> }
>
> This is in the messaging service
>
> Message message = new Message(from:User.findByUserId(userId),
> subject:subject, messageBody:messageBody,
> isRead:false, sentDate:Calendar.getInstance().getTime()).save()
>
>
> User.withTransaction { status -> //This is where it's craping out
> User user2 = User.findByUserId(user.userId)
>
> user2.messages.add(message)
>
> user2.save() // have also tried merge()
> }
>
> Sorry if there is a code tag - couldn't find one.
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Binding-Hibernate-Session-to-New-Thread-tp4303722p4304454.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

jonsinfinity
Here is the revised MessagingService:

class MessagingService {
       
    def executorService
    static transactional = true

    void sendDownloadReadyMessage(String userId, String downloadPath) {
               
        executorService.execute {
               
            String subject = 'New Download Ready'
                       
            String messageBody = """The download that you have requested is ready!
                                                                        You can download your file here"""
            Message message = new Message(from:User.findByUserId("myId"), subject:subject, messageBody:messageBody,
                                isRead:false, sentDate:Calendar.getInstance().getTime()).save()
                               
            User.findByUserId(userId).messages.add(message)
                               
        }
    }
}

and here is the new call from the controller using di

messagingService.sendDownloadReadyMessage(user.userId, filePath)

Still get the same message

util.JDBCExceptionReporter failed batch
events.PatchedDefaultFlushEventListener Could not synchronize database state with session
Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

basejump (Josh)
is runAsync not working for you?
try
runAysync{
  messagingService.sendDownloadReadyMessage(user.userId, filePath)
}

and remove the executorService from your service

Without seeing the stacktrace I can't tell where its going wrong.
can you create a small sample app the reproduces the issue? if so then fire it my way and I will take a look

couple of notes.
google your error, there are a couple of things you can try (read,refresh, etc..)
but you have 2 findByUserIds that exists that are the same object. on in your Message constructor and the same thing  right below that. Why not use the same instance
Where are you saving?


On Jan 17, 2012, at 4:09 PM, jonsinfinity wrote:

> Here is the revised MessagingService:
>
> class MessagingService {
>
>    def executorService
>    static transactional = true
>
>    void sendDownloadReadyMessage(String userId, String downloadPath) {
>
> executorService.execute {
>
>    String subject = 'New Download Ready'
>
>    String messageBody = """The download that you have requested is ready!
> You can download your file here"""
>    Message message = new Message(from:User.findByUserId("myId"),
> subject:subject, messageBody:messageBody,
> isRead:false, sentDate:Calendar.getInstance().getTime()).save()
>
>    User.findByUserId(userId).messages.add(message)
>
> }
>    }
> }
>
> and here is the new call from the controller using di
>
> messagingService.sendDownloadReadyMessage(user.userId, filePath)
>
> Still get the same message
>
> util.JDBCExceptionReporter failed batch
> events.PatchedDefaultFlushEventListener Could not synchronize database state
> with session
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Binding-Hibernate-Session-to-New-Thread-tp4303722p4304919.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

jonsinfinity
I did try the runAsync. got the following:

groovy.lang.MissingMethodException: No signature of method: com.project.DBExplorerController.runAysync() is applicable for argument types: (com.project.DBExplorerController$_closure35_closure82) values: [com.project.DBExplorerController$_closure35_closure82@1e179ab]
Possible solutions: runAsync(java.lang.Runnable)
        at com.project.DBExplorerController.invokeMethod(DBExplorerController.groovy)
        at com.project.DBExplorerController$_closure35.doCall(DBExplorerController.groovy:1088)
        at com.project.DBExplorerController$_closure35.doCall(DBExplorerController.groovy)
        at java.lang.Thread.run(Thread.java:662)

here is what the code in the controller method with the runAsync looks like:

       /**
         * Export current tab SQL results to CSV file for download
         */
        def exportResultsToCSVAsync = {
               
                other code...
                runAysync {
                        messagingService.sendDownloadReadyMessage(user.userId, filePath)
                }
        }

Just an FYI I am running Grails 1.3.7 at the moment. I couldn't find any documentation on runAsync in the Grails User Guide or my Grails in action book. When I Google it, it always shows up in references to the executor plugin. Is it part of the plugin or part of grails?

Also in the MessagingService the User in the constructor in a different user from a different Id (right now it's just a hard coded string). the next User is from the userId argument being passed into the method.

I did try to call the refresh() on the User object but that didn't help either. Here is the original stack trace when running the executorService.execute {}

events.PatchedDefaultFlushEventListener Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
        at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:170)
        at org.codehaus.groovy.grails.orm.hibernate.events.PatchedDefaultFlushEventListener.performExecutions(PatchedDefaultFlushEventListener.java:46)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
        at org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptor.flush(HibernatePersistenceContextInterceptor.java:85)
        at org.codehaus.groovy.grails.support.PersistenceContextInterceptor$flush.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
        at grails.plugin.executor.PersistenceContextWrapper.wrap(PersistenceContextWrapper.groovy:37)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:266)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:51)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
        at grails.plugin.executor.PersistenceContextRunnableWrapper.run(PersistenceContextRunnableWrapper.groovy:34)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
Caused by: java.sql.BatchUpdateException: failed batch
        at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
        at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
        at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
        ... 24 moreException in thread "pool-1-thread-1" org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
        at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:170)
        at org.codehaus.groovy.grails.orm.hibernate.events.PatchedDefaultFlushEventListener.performExecutions(PatchedDefaultFlushEventListener.java:46)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
        at org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptor.flush(HibernatePersistenceContextInterceptor.java:85)
        at org.codehaus.groovy.grails.support.PersistenceContextInterceptor$flush.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
        at grails.plugin.executor.PersistenceContextWrapper.wrap(PersistenceContextWrapper.groovy:37)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:266)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:51)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
        at grails.plugin.executor.PersistenceContextRunnableWrapper.run(PersistenceContextRunnableWrapper.groovy:34)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
Caused by: java.sql.BatchUpdateException: failed batch
        at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
        at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
        at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
        at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
        ... 24 more
Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

John Moore
On 19/01/12 16:13, jonsinfinity wrote:
> I did try the runAsync. got the following:
>
> groovy.lang.MissingMethodException: No signature of method:
> com.project.DBExplorerController.runAysync() is applicable for argument

You've got

runAysync

Should be

runAsync




---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

basejump (Josh)
In reply to this post by jonsinfinity
runAsync is added by the executor plugin
Your best bet it to create a dirt simple sample application to see what and where things are going haywire.
If you can reproduce the issue in a simple app and send it , I can make sure the executor plugin is not messed up.

On Jan 19, 2012, at 10:13 AM, jonsinfinity wrote:

> I did try the runAsync. got the following:
>
> groovy.lang.MissingMethodException: No signature of method:
> com.project.DBExplorerController.runAysync() is applicable for argument
> types: (com.project.DBExplorerController$_closure35_closure82) values:
> [com.project.DBExplorerController$_closure35_closure82@1e179ab]
> Possible solutions: runAsync(java.lang.Runnable)
> at
> com.project.DBExplorerController.invokeMethod(DBExplorerController.groovy)
> at
> com.project.DBExplorerController$_closure35.doCall(DBExplorerController.groovy:1088)
> at
> com.project.DBExplorerController$_closure35.doCall(DBExplorerController.groovy)
> at java.lang.Thread.run(Thread.java:662)
>
> here is what the code in the controller method with the runAsync looks like:
>
>       /**
> * Export current tab SQL results to CSV file for download
> */
> def exportResultsToCSVAsync = {
>
> other code...
> runAysync {
> messagingService.sendDownloadReadyMessage(user.userId, filePath)
> }
> }
>
> Just an FYI I am running Grails 1.3.7 at the moment. I couldn't find any
> documentation on runAsync in the Grails User Guide or my Grails in action
> book. When I Google it, it always shows up in references to the executor
> plugin. Is it part of the plugin or part of grails?
>
> Also in the MessagingService the User in the constructor in a different user
> from a different Id (right now it's just a hard coded string). the next User
> is from the userId argument being passed into the method.
>
> I did try to call the refresh() on the User object but that didn't help
> either. Here is the original stack trace when running the
> executorService.execute {}
>
> events.PatchedDefaultFlushEventListener Could not synchronize database state
> with session
> org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch
> update
> at
> org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
> at
> org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
> at
> org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
> at
> org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
> at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
> at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:170)
> at
> org.codehaus.groovy.grails.orm.hibernate.events.PatchedDefaultFlushEventListener.performExecutions(PatchedDefaultFlushEventListener.java:46)
> at
> org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
> at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
> at
> org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptor.flush(HibernatePersistenceContextInterceptor.java:85)
> at
> org.codehaus.groovy.grails.support.PersistenceContextInterceptor$flush.call(Unknown
> Source)
> at
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
> at
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
> at
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
> at
> grails.plugin.executor.PersistenceContextWrapper.wrap(PersistenceContextWrapper.groovy:37)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:266)
> at
> org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:51)
> at
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
> at
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
> at
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
> at
> grails.plugin.executor.PersistenceContextRunnableWrapper.run(PersistenceContextRunnableWrapper.groovy:34)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> at java.lang.Thread.run(Thread.java:662)
> Caused by: java.sql.BatchUpdateException: failed batch
> at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
> at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
> at
> org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
> at
> org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
> at
> org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
> ... 24 moreException in thread "pool-1-thread-1"
> org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch
> update
> at
> org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
> at
> org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
> at
> org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
> at
> org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
> at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
> at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:170)
> at
> org.codehaus.groovy.grails.orm.hibernate.events.PatchedDefaultFlushEventListener.performExecutions(PatchedDefaultFlushEventListener.java:46)
> at
> org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
> at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
> at
> org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptor.flush(HibernatePersistenceContextInterceptor.java:85)
> at
> org.codehaus.groovy.grails.support.PersistenceContextInterceptor$flush.call(Unknown
> Source)
> at
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
> at
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
> at
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
> at
> grails.plugin.executor.PersistenceContextWrapper.wrap(PersistenceContextWrapper.groovy:37)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at
> org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:266)
> at
> org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:51)
> at
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
> at
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
> at
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
> at
> grails.plugin.executor.PersistenceContextRunnableWrapper.run(PersistenceContextRunnableWrapper.groovy:34)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> at java.lang.Thread.run(Thread.java:662)
> Caused by: java.sql.BatchUpdateException: failed batch
> at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
> at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
> at
> org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
> at
> org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
> at
> org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
> at
> org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
> ... 24 more
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Binding-Hibernate-Session-to-New-Thread-tp4303722p4310481.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

netwiser
It could be a typo in your code:

It should be runAsync  but you are writing it as  runAysync

> From: [hidden email]

> Date: Thu, 19 Jan 2012 10:56:10 -0600
> To: [hidden email]
> Subject: Re: [grails-user] Re: Binding Hibernate Session to New Thread
>
> runAsync is added by the executor plugin
> Your best bet it to create a dirt simple sample application to see what and where things are going haywire.
> If you can reproduce the issue in a simple app and send it , I can make sure the executor plugin is not messed up.
>
> On Jan 19, 2012, at 10:13 AM, jonsinfinity wrote:
>
> > I did try the runAsync. got the following:
> >
> > groovy.lang.MissingMethodException: No signature of method:
> > com.project.DBExplorerController.runAysync() is applicable for argument
> > types: (com.project.DBExplorerController$_closure35_closure82) values:
> > [com.project.DBExplorerController$_closure35_closure82@1e179ab]
> > Possible solutions: runAsync(java.lang.Runnable)
> > at
> > com.project.DBExplorerController.invokeMethod(DBExplorerController.groovy)
> > at
> > com.project.DBExplorerController$_closure35.doCall(DBExplorerController.groovy:1088)
> > at
> > com.project.DBExplorerController$_closure35.doCall(DBExplorerController.groovy)
> > at java.lang.Thread.run(Thread.java:662)
> >
> > here is what the code in the controller method with the runAsync looks like:
> >
> > /**
> > * Export current tab SQL results to CSV file for download
> > */
> > def exportResultsToCSVAsync = {
> >
> > other code...
> > runAysync {
> > messagingService.sendDownloadReadyMessage(user.userId, filePath)
> > }
> > }
> >
> > Just an FYI I am running Grails 1.3.7 at the moment. I couldn't find any
> > documentation on runAsync in the Grails User Guide or my Grails in action
> > book. When I Google it, it always shows up in references to the executor
> > plugin. Is it part of the plugin or part of grails?
> >
> > Also in the MessagingService the User in the constructor in a different user
> > from a different Id (right now it's just a hard coded string). the next User
> > is from the userId argument being passed into the method.
> >
> > I did try to call the refresh() on the User object but that didn't help
> > either. Here is the original stack trace when running the
> > executorService.execute {}
> >
> > events.PatchedDefaultFlushEventListener Could not synchronize database state
> > with session
> > org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch
> > update
> > at
> > org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
> > at
> > org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
> > at
> > org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
> > at
> > org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
> > at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
> > at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:170)
> > at
> > org.codehaus.groovy.grails.orm.hibernate.events.PatchedDefaultFlushEventListener.performExecutions(PatchedDefaultFlushEventListener.java:46)
> > at
> > org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
> > at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
> > at
> > org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptor.flush(HibernatePersistenceContextInterceptor.java:85)
> > at
> > org.codehaus.groovy.grails.support.PersistenceContextInterceptor$flush.call(Unknown
> > Source)
> > at
> > org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
> > at
> > org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
> > at
> > org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
> > at
> > grails.plugin.executor.PersistenceContextWrapper.wrap(PersistenceContextWrapper.groovy:37)
> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > at
> > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> > at
> > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> > at java.lang.reflect.Method.invoke(Method.java:597)
> > at
> > org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:266)
> > at
> > org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:51)
> > at
> > org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
> > at
> > org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
> > at
> > org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
> > at
> > grails.plugin.executor.PersistenceContextRunnableWrapper.run(PersistenceContextRunnableWrapper.groovy:34)
> > at
> > java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> > at
> > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> > at java.lang.Thread.run(Thread.java:662)
> > Caused by: java.sql.BatchUpdateException: failed batch
> > at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
> > at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
> > at
> > org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
> > at
> > org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
> > at
> > org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
> > ... 24 moreException in thread "pool-1-thread-1"
> > org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch
> > update
> > at
> > org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
> > at
> > org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
> > at
> > org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
> > at
> > org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
> > at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
> > at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:170)
> > at
> > org.codehaus.groovy.grails.orm.hibernate.events.PatchedDefaultFlushEventListener.performExecutions(PatchedDefaultFlushEventListener.java:46)
> > at
> > org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
> > at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
> > at
> > org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptor.flush(HibernatePersistenceContextInterceptor.java:85)
> > at
> > org.codehaus.groovy.grails.support.PersistenceContextInterceptor$flush.call(Unknown
> > Source)
> > at
> > org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
> > at
> > org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
> > at
> > org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
> > at
> > grails.plugin.executor.PersistenceContextWrapper.wrap(PersistenceContextWrapper.groovy:37)
> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > at
> > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> > at
> > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> > at java.lang.reflect.Method.invoke(Method.java:597)
> > at
> > org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:266)
> > at
> > org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:51)
> > at
> > org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
> > at
> > org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
> > at
> > org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
> > at
> > grails.plugin.executor.PersistenceContextRunnableWrapper.run(PersistenceContextRunnableWrapper.groovy:34)
> > at
> > java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> > at
> > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> > at java.lang.Thread.run(Thread.java:662)
> > Caused by: java.sql.BatchUpdateException: failed batch
> > at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
> > at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
> > at
> > org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
> > at
> > org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
> > at
> > org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
> > at
> > org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
> > ... 24 more
> >
> > --
> > View this message in context: http://grails.1312388.n4.nabble.com/Binding-Hibernate-Session-to-New-Thread-tp4303722p4310481.html
> > Sent from the Grails - user mailing list archive at Nabble.com.
> >
> > ---------------------------------------------------------------------
> > To unsubscribe from this list, please visit:
> >
> > http://xircles.codehaus.org/manage_email
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

jonsinfinity
Yeah I caught that after I posted. Thanks though. That was causing the MissingMethodException. Back to the original error now.

I did figure out that runAsync is from the executor plugin. The error is happening in this code:

    PersistenceContextInterceptor persistenceInterceptor

    protected wrap(Closure wrapped) {
        persistenceInterceptor.init()
        try {
            wrapped()
        } finally {
            persistenceInterceptor.flush()  **** This is where the exception is thrown
            persistenceInterceptor.destroy()
        }
    }

I also moved all of the logic from the service into the controller wrapped in the runAsync{}... same results.
Reply | Threaded
Open this post in threaded view
|

Re: Binding Hibernate Session to New Thread

jonsinfinity
I figured it out. It was an issue with the Message domain objects mapping. The runAsync{} was masking the true exception. Thanks everyone for the help at least I have a good understanding of how the executor plugin works now.