2014-09-14 3 views
0

Пользователь заполняет форму, где он задает параметры для формирования отчета. Он отправляет форму, сервер проверяет параметры, возвращает сообщение, что все в порядке для пользователя и генерирует отчет. По завершении создания отчета пользователь получает электронную почту со ссылкой для отчета.Граали и фоновые задачи

Каков правильный способ достижения этого в граале? На данный момент у меня есть служба, которая генерирует отчет, это выглядит следующим образом:

@Transactional 
class AnalyticsService { 

    ExecutorService executor = Executors.newSingleThreadExecutor() 

    def buildExportAndSendMail() { 
     executor.execute { 
      //GENERATE REPORT AND SEND MAIL. USES GORM. 
     } 
    } 

    @PreDestroy 
    void shutdown() { 
     executor.shutdownNow() 
    } 
} 

Мои действия контроллер выглядит следующим образом:

def generateReport(ReportParams command) { 
    if(!command.hasErrors()) { 
     analyticsService.buildExportAndSendMail() 
     render([success:true, html:"Your report is being generated."] as JSON) 
    } else { 
     ... 
    } 
} 

Однако служба бросает ошибку при попытке доступа доменные объекты:

Exception in thread "pool-8-thread-1" 
Error | 
org.hibernate.LazyInitializationException: could not initialize proxy - no Session 

Что было бы правильным способом сделать это в граале?

ответ

1

Проблема в том, что вы создаете новый поток и не привязаны к сеансу Hibernate. Создание одного достаточно просто. Неважно, какой класс домена вы используете. Например:

def buildExportAndSendMail() { 
    executor.execute { 
    SomeDomainClass.withNewSession { session -> 
     //GENERATE REPORT AND SEND MAIL. USES GORM. 
    } 
    } 
} 

Вы можете прочитать больше о withNewSession в documentation.

+1

Вы правы, это работает. Мне также пришлось повторно присоединить некоторые объекты с obj.attach() (они были приобретены в предыдущем сеансе). Благодарю. –

+0

Добро пожаловать. Рад помочь. –

+2

Даже если вы выбрали это как решение, вам действительно нужно прочитать раздел 10 Руководства - Асинхронное программирование. Хотя вы успешно создали новый сеанс спящего режима, вы, вероятно, должны использовать поддержку асинхронного выполнения Grails, поскольку вы бесплатно получаете всю поддержку сеанса artefact и hibernate. Если вы хотите сделать что-то запланированное, то плагин Quartz (как предлагается в другом ответе) - это правильный путь. –

1

я бы, вероятно, добавить работу с Граалей quartz plugin:

class ReportJob { 
    def execute() { 
     // create report 
     // mail report 
    } 
} 

, а затем запускают работу с

ReportJob.triggerNow (Map params) 

преимущество заключается в том, что вам не нужно явно обрабатывать многопоточность или сессию вещи.

+0

Да, это тоже может работать. Другой вариант: http://gpc.github.io/grails-jms/docs/manual/index.html –

Смежные вопросы