Hibernate call in background threads in grails

I am trying to create a specific type of background processing setup in a grails application.

  • A fixed thread pool size exists only during the job package
  • A single session is supported by each thread.
  • Each task is performed in a separate transaction.

I am trying to start the work as follows:

int poolSize = 10
ThreadFactory factory = new MyThreadFactory (Executors.defaultThreadFactory())
ExecutorService pool = Executors.newFixedThreadPool (poolSize, factory)

(1..100).each { i ->
  pool.submit {
    try {
      MyDomainClass.withTransaction {
        doSomeWork(i)
      }
    } catch (Exception e) {
      log.error "error in job ${i}", e
    }
  }
}

MyThreadFactory creates threads in which the hibernate session is connected for the duration of the thread.

class MyThreadFactory implements ThreadFactory {

  ThreadFactory delegate
  PersistenceContextInterceptor persistenceInterceptor

  MyThreadFactory (ThreadFactory delegate) {
    this.delegate = delegate
    ApplicationContext applicationContext = ApplicationHolder.getApplication().getMainContext()
    persistenceInterceptor = applicationContext.getBean("persistenceInterceptor");
  }

  Thread newThread (Runnable work) {
    return delegate.newThread {
      persistenceInterceptor.init()
      try {
        work.run()
      } finally {
        persistenceInterceptor.flush()
        persistenceInterceptor.destroy()
      }
    }
  }
}

Everything seems to work, however the first time I run the batch job, I get the following error. (Subsequent tasks run without incident)

groovy.lang.MissingMethodException: No signature of method: static MyDomainClass.save() is applicable for argument types: (java.util.LinkedHashMap) values: [[flush:false]]
Possible solutions: save(), save(java.util.Map), save(java.lang.Boolean), wait(), any(), wait(long)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at ...

persitanceInterceptor MyDomainClass.withNewSession {} .

, GORM .

- , , ?

@fixitagain :

 doSomeWork = { id ->
    MyDomainClass a = MyDomainClass.findById (id)
    a.value = lotsOfWork()
    a.save()
 }

, - , , "DomainClass.withTransaction(Closure)" .

, , , (-?).

+5
3

, , - Grails. , , .. , .

Grails , , .

+1

, , ?

0

, , .

edit: GORM , .

0

All Articles