Hibernate - 无法执行JDBC批量更新

时间:2014-09-08 05:38:37

标签: android hibernate openmobster

任何人都可以建议我在hibernate中导致此错误的原因。我正在使用OpenMobster云服务器(MBaaS工具)在Android中进行数据同步。

2014-09-08 10:43:15,763 WARN  [org.hibernate.util.JDBCExceptionReporter] (Thread-14) SQL  Error: 0, SQLState: null
2014-09-08 10:43:15,763 ERROR [org.hibernate.util.JDBCExceptionReporter] (Thread-14)  failed batch
2014-09-08 10:43:15,764 ERROR [org.hibernate.event.def.AbstractFlushingEventListener]  (Thread-14) Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
 at  org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java :126)
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
   at   org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEven tListener.java:321)
   at  org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListe ner.java:64)
   at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:996)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1141)
   at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
   at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:835)
   at  org.openmobster.core.synchronizer.server.engine.ServerSyncEngineImpl.getChangeLogEntry(Serve rSyncEngineImpl.java:576)
   at  org.openmobster.core.synchronizer.server.engine.ServerSyncEngineImpl.addChangeLogEntries(Ser verSyncEngineImpl.java:548)
   at  org.openmobster.core.synchronizer.event.SyncChannelEventListener.updateChangeLog(SyncChannel EventListener.java:126)
   at   org.openmobster.core.synchronizer.event.SyncChannelEventListener.channelUpdated(SyncChannelE ventListener.java:95)
   at  org.openmobster.core.services.CometService.broadcastChannelEvent(CometService.java:106)
   at  org.openmobster.core.services.MobileObjectMonitor.messageIncoming(MobileObjectMonitor.java:205)
   at  org.openmobster.core.common.bus.BusConsumer.sendBusListenerEvent(BusConsumer.java:184)
   at org.openmobster.core.common.bus.BusConsumer.consume(BusConsumer.java:120)
   at org.openmobster.core.common.bus.BusConsumer.run(BusConsumer.java:77)
   at java.lang.Thread.run(Thread.java:724)
   Caused by: java.sql.BatchUpdateException: failed batch
   at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
   at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
   at  org.jboss.resource.adapter.jdbc.WrappedStatement.executeBatch(WrappedStatement.java:774)
  at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
  at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
  ... 18 more

1 个答案:

答案 0 :(得分:2)

这里的问题是" GenericJDBCException:无法执行JDBC批量更新" - 它没有告诉你为什么给定的陈述无法执行。

一种解决方案是使用BatchUpdateException.getNextException来获取批处理异常的原因。但是,可能会发生这只是返回null,例如因为jdbc驱动程序不支持它。 所以替代解决方案是当我们没有获得有关批量更新失败原因的任何信息时,我们必须找到一种方法来阻止hibernate进行批处理。例如,在像测试用例这样的隔离环境中运行时,这非常有用。

这可以通过在系统属性中添加以下内容来实现:

-Dhibernate.statement_cache.size=0 
-Dhibernate.jdbc.batch_size=0 
-Dhibernate.jdbc.use_scrollable_resultset=false
-Dhibernate.bytecode.use_reflection_optimizer=false
-Dhibernate.show_sql=true

实现这一目标的另一种方法是: 为了更改执行策略,hibernate提供了hibernate.jdbc.factory_class配置属性,该属性接受org.hibernate.jdbc.BatcherFactory的实现。 Hibernate已经提供了NonBatchingBatcherFactory,这是我们想要的。 适当的hibernate配置可能如下所示:

final Configuration config = new Configuration();
// ... more config here
config.setProperty( "hibernate.jdbc.factory_class", "org.hibernate.jdbc.NonBatchingBatcherFactory" );

上面生成BatchUpdateException的代码现在会导致可以轻松跟踪的实际异常。为测试运行更改一次batcher策略以查看单个sql异常是有帮助的。但是,当生产设置不同时,您不应该更改所有测试的策略或持续集成。

参考:

  1. http://www.eishay.com/2010/04/testing-with-hibernate.html

  2. http://inoio.de/blog/2012/11/16/how-to-get-rid-of-hibernate-genericjdbcexception/