2014-11-03 47 views
0

我正在使用插件平臺核心和事件總線模塊。我需要添加一些域assync,但我強制同步測試,在我的數據庫中,但每次我嘗試save()時都會拋出異常DataIntegrityViolation。這是域結構:平臺核心事件總線拋出DataIntegrationException

class Alocacao { 
    static belongsTo = [tipoUnidade: TipoUnidade] 
    //Anothers attrs and constraints 
} 

class TipoUnidade { 

    static belongsTo = [ estabelecimento : Estabelecimento];  

    static hasMany = [alocacoes: Alocacao]; 

    List<Alocacao> alocacoes 

    //Constraints and fields... 

} 

在我的控制,我有這樣的代碼:

tipoUnidadeService.save(tipoUnidadeInstance) 
event('criarAlocacaoQuartoEvent', tipoUnidadeInstance, [fork: false]) 

而在我的事件監聽器這樣的:

class AlocacaoService { 

@Listener(topic="criarAlocacaoQuartoEvent", namespace="app") 
def defaultAlocacaoCreator(EventMessage<TipoUnidade> message) { 
    Canal canalSist = Canal.findByNomeIlike("%manual%") 
    TipoUnidade quarto = TipoUnidade.get(message.data.id) 
    def alocacaoSistema = new Alocacao(exclusivo: 0, nExclusivo: 0, data: tmp.toDate(), canal: canalSist, tipoUnidade: quarto).save(failOnError: true) //EXCEPTION!! 
} 
} 

我不知道什麼與發生該代碼。

這是整個例外:

util.JDBCExceptionReporter SQL Error: 1048, SQLState: 23000 
util.JDBCExceptionReporter Column 'tipo_unidade_id' cannot be null 
services.AlocacaoService could not insert: [br.com.qreserva.portal.domains.Alocacao]; SQL [insert into alocacao (version, canal_id, data, date_created, exclusivo, n_exclusivo, tipo_unidade_id, alocacoes_idx) values (?, ?, ?, ?, ?, ?, ?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [br.com.qreserva.portal.domains.Alocacao] 
org.springframework.dao.DataIntegrityViolationException: could not insert: [br.com.qreserva.portal.domains.Alocacao]; SQL [insert into alocacao (version, canal_id, data, date_created, exclusivo, n_exclusivo, tipo_unidade_id, alocacoes_idx) values (?, ?, ?, ?, ?, ?, ?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [br.com.qreserva.portal.domains.Alocacao] 
    at br.com.qreserva.portal.services.AlocacaoService.defaultAlocacaoCreator(AlocacaoService.groovy:178) 
    at org.grails.plugin.platform.events.registry.DefaultEventsRegistry$ListenerHandler.invoke(DefaultEventsRegistry.java:238) 
    at org.grails.plugin.platform.events.registry.DefaultEventsRegistry.invokeListeners(DefaultEventsRegistry.java:160) 
    at org.grails.plugin.platform.events.publisher.DefaultEventsPublisher.event(DefaultEventsPublisher.java:79) 
    at org.grails.plugin.platform.events.EventsImpl.event(EventsImpl.groovy:154) 
    at org.grails.plugin.platform.events.EventsImpl$_closure1_closure5_closure9.doCall(EventsImpl.groovy:83) 
    at br.com.qreserva.portal.controllers.TipoUnidadeController.salvar(TipoUnidadeController.groovy:126) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [br.com.qreserva.portal.domains.Alocacao] 
    ... 10 more 
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'tipo_unidade_id' cannot be null 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) 
    at com.mysql.jdbc.Util.getInstance(Util.java:381) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2542) 
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1734) 
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2019) 
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1937) 
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1922) 
    at com.jolbox.bonecp.PreparedStatementHandle.executeUpdate(PreparedStatementHandle.java:203) 
    ... 10 more 

[編輯]

我創建這個git project來說明我的問題,並會發生同樣的錯誤

[解決方法] 我使用belongsTo類中的addTo * attrs解決了這個問題。但爲什麼這個作品我不知道。

回答

1

的核心問題是

MySQLIntegrityConstraintViolationException: Column 'tipo_unidade_id' cannot be null 

這列是tipoUnidade變量外鍵(駱駝情況tipoUnidade成爲tipo_unidade作爲列名,並有_id後綴添加,因爲它是一個FK),所以這意味着該值爲null,這意味着TipoUnidade.get(message.data.id)返回null。如果message.data.id爲空(可能是因爲message.data不爲空,但尚未保存?),或者沒有該ID的記錄,則會發生這種情況。

由於您使用異步代碼,我的猜測是這是一個計時問題,並且message.data值尚未保存,但您嘗試基於插入的值加載一個值。

檢查值,並考慮打開SQL日誌記錄,以便您可以看到項目的插入和檢索順序。

+0

Thx to reply Burt。 TipoUnidade.get(message.data.id)返回一個值,並且sql日誌確認tipoUnidadeInstance在數據庫上被持久化。我不明白可以爲空的消息。 SQL日誌:Hibernate:插入到tipo_unidade(...)。我嘗試了withNewTransacion和whitSession,但我有同樣的結果。 – 2014-11-03 16:32:22

0

基於Burt的迴應,我做了一個解決方法,並由於某種原因使用addTo *解決了問題。

TipoUnidade quarto = TipoUnidade.get(message.data.id) 
quarto.addToAlocacoes(new Alocacao(exclusivo: 0, nExclusivo: 0, data: tmp.toDate(), canal: canalSist)) 
quarto.save(failOnError: true) 

Thx。

1

我有與EventBus相同的問題。問題是EventBus與線程一起工作。我想你也使用事務。這兩個對象是在兩個不同的線程中創建的,而hibernate不能保存其中的一個,因爲另一個不可用。