Hibernate Persist for large field values给出了ConstraintViolationException

时间:2013-07-29 06:26:40

标签: spring oracle hibernate

我遇到了一个问题,即持有一个Entity(YieldCurveArchive)的记录,其字段(reason)的长度相当于2048个字符。以下是方案及其结果:

  • 使用较小的原因字段上传新实体:正常工作。
  • 使用原因字段上传实体 更改为更大(2048个字符)的数据集:工作正常。再次如此 以上。这是对现有记录的更新。
  • 上传新实体 更大(2048个字符)的原因字段:失败。

我也尝试使用entityManager.flush()刷新hibernate查询缓冲区,但上面的测试结果不会改变。

我怀疑在实际执行最终插入数据库之前,Hibernate执行的缓冲可能存在问题:

  • 选择要与之比较的数据库中的可用记录 现有数据集。
  • 插入被触发但仅保留在缓冲区中 hibernate触发批量更新。
  • 另一个选择被解雇了 不同的客户。看到另一个选择后,hibernate决定 将插入内容激活到数据库中然后失败。

来自失败日志的跟踪摘录:

2013-07-02 12:46:00,792  WARN [pool-1-thread-4]: org.hibernate.util.JDBCExceptionReporter - SQL Error: 1400, SQLState: 23000
2013-07-02 12:46:00,792 ERROR [pool-1-thread-4]: org.hibernate.util.JDBCExceptionReporter - ORA-01400: cannot insert NULL into ("CORE_TOTEM"."YC_MONTHLY_ARCHIVE"."PKEY")

2013-07-02 12:46:00,792  WARN [pool-1-thread-4]: org.hibernate.util.JDBCExceptionReporter - SQL Error: 1400, SQLState: 23000
2013-07-02 12:46:00,792 ERROR [pool-1-thread-4]: org.hibernate.util.JDBCExceptionReporter - ORA-01400: cannot insert NULL into ("CORE_TOTEM"."YC_MONTHLY_ARCHIVE"."PKEY")

2013-07-02 12:46:00,985 ERROR [pool-1-thread-4]: org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
                        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
                        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:167)
                        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
                        at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.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.ejb.QueryImpl.getResultList(QueryImpl.java:65)
                        at markit.totem.dao.DaoHelper.list(DaoHelper.java:19)
                        at com.markit.totem.rates.yieldcurve.dao.YieldCurveArchiveDao.getArchivesMonthly(YieldCurveArchiveDao.java:172)
                        at com.markit.totem.rates.yieldcurve.dao.YieldCurveArchiveDao$$FastClassByCGLIB$$55ef1569.invoke(<generated>)
                        at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
                        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:628)
                        at com.markit.totem.rates.yieldcurve.dao.YieldCurveMonthlyArchiveDao$$EnhancerByCGLIB$$6aa04fe7.getArchivesMonthly(<generated>)
                        at com.markit.totem.rates.yieldcurve.results.upload.monthly.YieldCurveMonthlyArchivePersister.getExisting(YieldCurveMonthlyArchivePersister.java:38)
                        at com.markit.totem.rates.yieldcurve.results.upload.YieldCurveArchivePersister.persist(YieldCurveArchivePersister.java:68)
                        at com.markit.totem.rates.yieldcurve.results.upload.YieldCurveArchivePersister$$FastClassByCGLIB$$ac0db3fb.invoke(<generated>)
                        at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
                        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:628)
                        at com.markit.totem.rates.yieldcurve.results.upload.monthly.YieldCurveMonthlyArchivePersister$$EnhancerByCGLIB$$4b00cfa0.persist(<generated>)
                        at com.markit.totem.rates.yieldcurve.results.upload.YieldCurveResultsUploader.upload(YieldCurveResultsUploader.java:158)
                        at com.markit.totem.rates.yieldcurve.results.upload.YieldCurveResultsUploadTask.run(YieldCurveResultsUploadTask.java:53)
                        at com.markit.totem.workflow.WorkflowExecutor.executeWorkflowTask(WorkflowExecutor.java:258)
                        at com.markit.totem.workflow.WorkflowExecutor.executeSubWorkflow(WorkflowExecutor.java:227)
                        at com.markit.totem.workflow.WorkflowExecutor.access$000(WorkflowExecutor.java:17)
                        at com.markit.totem.workflow.WorkflowExecutor$1.run(WorkflowExecutor.java:72)
                        at markit.totem.dao.Transactionator.execute(Transactionator.java:19)
                        at markit.totem.dao.Transactionator$$FastClassByCGLIB$$c9204755.invoke(<generated>)
                        at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
                        at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
                        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
                        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
                        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
                        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
                        at markit.totem.dao.Transactionator$$EnhancerByCGLIB$$4eec78e2.execute(<generated>)
                        at com.markit.totem.workflow.WorkflowExecutor.execute(WorkflowExecutor.java:83)
                        at com.markit.totem.workflow.WorkflowExecutor.execute(WorkflowExecutor.java:213)
                        at com.markit.totem.workflow.WorkflowManager$OldWorkflow.execute(WorkflowManager.java:218)
                        at com.markit.totem.workflow.WorkflowManager$1.run(WorkflowManager.java:119)
                        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                        at java.lang.Thread.run(Thread.java:662)
Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("CORE_TOTEM"."YC_MONTHLY_ARCHIVE"."PKEY")

                        at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:367)
                        at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:9055)
                        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
                        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
                        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)

我最初的想法是,由于数据库中的编码差异和Hibernate的默认编码,它失败了。

与底层数据库一样,Oracle和NLS_CHARACTERSET定义为:

NLS_CHARACTERSET    AL32UTF8

因此它存储1个字符作为4个字节,任何特殊字符作为6个字节存储。我插入Oracle的失败是1001但是直到我插入1000个字符。但是,如果我使用更多字符进行更新而不是这种情况,这会使其更加混乱。

任何指针都会有很大帮助吗?

0 个答案:

没有答案