我正在使用插件平台核心和事件总线模块。我需要添加一些域assync,但我强制同步测试,在我的数据库,但异常DataIntegrityViolation每次我试图save()时抛出。这就是域结构:
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解决了这个问题。但为什么这个工作我不知道。
答案 0 :(得分: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日志记录,以便查看项目的插入和检索顺序。
答案 1 :(得分:1)
我和EventBus有同样的问题。问题是EventBus适用于线程。我想你也使用了交易。这两个对象都是在两个不同的线程中创建的,休眠无法保存其中一个,因为另一个不可用。
答案 2 :(得分: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。