Grails не очищает сеанс после возникновения сообщения об ошибке

Я вижу, что это сообщение об ошибке уже несколько раз публиковалось в контексте гибернации.

Я получаю эту ошибку при использовании службы Grails и класса домена, любая помощь будет очень признательна

Класс домена

class Coupon {
    Date dateCreated
    Date lastUpdated
    String code
    String email
    String address
    String state
    String city
    String zip
    def couponCodeGeneratorService

    def beforeValidate() {
        println code+"---------8-"
        code = couponCodeGeneratorService.generate()
        println code+"----------"
    }
    static constraints = {
        email blank:false,email:true
        address blank:false
        state blank:false
        city blank:false
        zip blank:false
    }
}

Услуга

class CouponCodeGeneratorService {
    Random randomGenerator = new Random()
    def serviceMethod() {

    }
    def generate(){
        def group1 =  randomGenerator.nextInt(9999)+"";
        def group2 =  randomGenerator.nextInt(9999)+"";
        def group3 =  randomGenerator.nextInt(9999)+"";
        def group4 =  randomGenerator.nextInt(9999)+"";
        return group1.padLeft(4,"0") +group2.padLeft(4,"0")+group3.padLeft(4,"0")+group4.padLeft(4,"0")
    }
}

Ошибка, которую я получаю,

---------8-
4844634041715590----------
4844634041715590---------8-
| Error 2012-09-10 11:32:54,938 [http-bio-8080-exec-7] ERROR hibernate.AssertionFailure  - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
Message: null id in com.easytha.Coupon entry (don't flush the Session after an exception occurs)
   Line | Method
->>  19 | beforeValidate     in com.easytha.Coupon
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    46 | onApplicationEvent in org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
|    24 | save . . . . . . . in com.easytha.CouponController
|   186 | doFilter           in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|    63 | doFilter . . . . . in grails.plugin.cache.web.filter.AbstractFilter
|   886 | runTask            in java.util.concurrent.ThreadPoolExecutor$Worker
|   908 | run . . . . . . .  in     ''
^   662 | run                in java.lang.Thread
| Error 2012-09-10 11:32:54,944 [http-bio-8080-exec-7] ERROR errors.GrailsExceptionResolver  - AssertionFailure occurred when processing request: [POST] /EasyTha/coupon/save - parameters:
zip: asdf
address: asd
email: [email protected]
state: asd
code: 
create: Create
city: asdf
null id in com.easytha.Coupon entry (don't flush the Session after an exception occurs). Stacktrace follows:
Message: null id in com.easytha.Coupon entry (don't flush the Session after an exception occurs)
   Line | Method
->>  19 | beforeValidate     in com.easytha.Coupon
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    46 | onApplicationEvent in org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
|    24 | save . . . . . . . in com.easytha.CouponController
|   186 | doFilter           in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|    63 | doFilter . . . . . in grails.plugin.cache.web.filter.AbstractFilter
|   886 | runTask            in java.util.concurrent.ThreadPoolExecutor$Worker
|   908 | run . . . . . . .  in     ''
^   662 | run                in java.lang.Thread

Я не очень хорошо знаком с Hibernate, также это правильный способ создать код купона, который выглядит как номер кредитной карты?


person Sap    schedule 09.09.2012    source источник
comment
Похоже, это может быть ошибка проверки или служба выдает исключение, но код, который вызывает save в домене, все еще пытается вызвать save(), можете ли вы попробовать проверить это?   -  person Steve    schedule 10.09.2012
comment
@steve Контроллер имеет только аннотацию «scaffold = true». Я добавил try catch в сервисный метод, и теперь исключение выглядит немного по-другому. Теперь консоль выводит отладочные сообщения до и после вызова метода службы. См. обновленное исключение   -  person Sap    schedule 10.09.2012
comment
Итак, это говорит о том, что «код» пуст, и этого не должно быть, поэтому его проверка не проходит, и я думаю, что именно поэтому вы видите ошибку, можете ли вы вернуться и просто жестко закодировать значение для «кода» в beforeValidate()... извините, если я ввожу в заблуждение, это немного догадка на данный момент   -  person Steve    schedule 10.09.2012
comment
@ Стив, нет ... та же ошибка, даже если я отправлю значение кода ... и в любом случае проверка не должна происходить до того, как будет вызвано правильное значение beforevalidate? и после его вызова строка кода имеет значение!   -  person Sap    schedule 10.09.2012
comment
Я не уверен, что вызов транзакционного метода службы изнутри beforeValidate является хорошей идеей, я не удивлюсь, если логика транзакции вставит дополнительный сброс или вызовет дополнительную проверку в неподходящий момент. Попробуйте добавить static transactional = false к CouponCodeGeneratorService.   -  person Ian Roberts    schedule 10.09.2012
comment
@IanRoberts Большое спасибо Ян, это сработало!! Можете ли вы преобразовать свой комментарий в ответ! Благодарность   -  person Sap    schedule 10.09.2012


Ответы (1)


Я подозреваю, что проблема может заключаться в том, что CouponCodeGeneratorService является транзакционным. Поэтому, когда вы вызываете метод службы из своего beforeValidate, вы открываете и закрываете транзакцию (даже если вы не касаетесь базы данных внутри метода), что, среди прочего, вызовет еще один сброс сеанса.

Попробуйте сделать сервис нетранзакционным:

static transactional = false
person Ian Roberts    schedule 10.09.2012
comment
Хороший. В любом случае, я даже не вижу смысла иметь этот метод внутри службы? может быть чище в статическом классе Util или Mixin? - person Steve; 11.09.2012