由于GUID重复,无法与会话org.hibernate.exception.ConstraintViolationException同步数据库状态

Vij*_*har 7 java sql sql-server hibernate

我使用休眠模式使用自动生成的GUID将数据插入到表中,但是有时会由于GUID重复而导致插入失败。

例如:

在Logs中,通过打印重复的GUID'0500edac-0074-4324-3436-31444231342d',在前两次尝试中插入失败。花费的时间如下

     1st attempt :08-27-2018 04:27:00.012,

     2nd attempt :08-27-2018 04:27:01.024,

     3rd attempt was not logged ,as it was successful
Run Code Online (Sandbox Code Playgroud)

但是在数据库中,我看到在'08 -27-2018 04:27:01.054'创建的GUID为'0500edac-0074-4324-3436-31444231342d'的行

所以我不确定为什么我会在前两次尝试中获得异常,然后成功地将其插入到第3次。

SQL表属性:我有一个名为“ DataHistory”的SQL Server表,其中的列名为

"DataHistoryGuid" with the following properties uniqueidentifier,ROWGUIDCOL,Primary Key column,newsequentialid .
Run Code Online (Sandbox Code Playgroud)

Hibernate属性:我正在使用hibernate将数据存储在该表中,对于GUID列,我正在使用

<id name="dataHistoryGuid" type="java.util.UUID" >
        <column name="DataHistoryGuid"/>
        <generator class="guid"/>
    </id>
Run Code Online (Sandbox Code Playgroud)

以下是异常跟踪:

[event.def.AbstractFlushingEventListener:performExecutions:324]
Could not synchronize database state with session 
org.hibernate.exception.ConstraintViolationException: could not 
 insert: [com.testProj.dataprocessor.model.sql.SqlDataHistory] 
  at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94) 
  at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
  at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2295) 
  at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688) 
  at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79) 
  at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279) 
  at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263) 
  at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167) 
  at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
  at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) 
  at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027) 
  at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390) 
  at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:420) 
  at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) 
  at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:748) 
  at com.testProj.dataprocessor.common.sql.hibernate.HibernateSession.upsertDataHistory(HibernateSession.java:505) 
  at com.testProj.dataprocessor.common.sql.SqlStore.upsertDataHistory(SqlStore.java:92) 
  at com.testProj.dataprocessor.common.sql.SqlStore$$FastClassByCGLIB$$18d897d8.invoke(<generated>) 
  at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) 
  at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700) 
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149) 
  at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:77) 
  at com.testProj.dataprocessor.model.performance.Profiler.profile(Profiler.java:15) 
  at sun.reflect.GeneratedMethodAccessor160.invoke(Unknown Source) 
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
  at java.lang.reflect.Method.invoke(Method.java:498) 
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627) 
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616) 
  at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:64) 
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) 
  at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:77) 
  at com.testProj.dataprocessor.common.sql.SqlRetryPolicy.retry(SqlRetryPolicy.java:20) 
  at sun.reflect.GeneratedMethodAccessor161.invoke(Unknown Source) 
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
  at java.lang.reflect.Method.invoke(Method.java:498) 
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627) 
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616) 
  at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:64) 
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) 
  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) 
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) 
  at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635) 
  at com.testProj.dataprocessor.common.sql.SqlStore$$EnhancerByCGLIB$$f3a323cc.upsertDataHistory(<generated>) 
  at com.testProj.dataprocessor.dao.DataDAO.updateDataHistory(DataDAO.java:88) 
  at com.testProj.dataprocessor.eventhandler.DataHistoryEventHandler.doWork(DataHistoryEventHandler.java:34) 
  at com.testProj.dataprocessor.eventhandler.DataHistoryEventHandler.updateDiagnosticsHistory(DataHistoryEventHandler.java:28) 
  at com.testProj.dataprocessor.DataProcessorService.doWork(DataProcessorService.java:37) 
  at com.testProj.dataprocessor.DataProcessorService.process(DataProcessorService.java:24) 
  at com.testProj.dataprocessor.DataProcessorService.process(DataProcessorService.java:80) 
  at com.testProj.dataprocessor.DataProcessorService.postDataEventSync(DefaultDataProcessorService.java:41) 
  at com.testProj.dataprocessor.DataProcessorService.postDataEvent(DefaultDataProcessorService.java:36) at sun.reflect.GeneratedMethodAccessor272.invoke(Unknown Source) 
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
  at java.lang.reflect.Method.invoke(Method.java:498) 
  at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:173) 
  at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:89) 
  at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:60) 
  at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:75) 
  at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58) 
  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
  at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
  at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37) 
  at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106) 
  at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236) 
  at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:109) 
  at Caused by: java.sql.SQLException: Violation of PRIMARY KEY constraint 'PK_DataHistory_on_DataHistoryGuid'. Cannot insert duplicate key in object 'dbo.DataHistory'. The duplicate key value is (0500edac-0074-4324-3436-31444231342d). 
  at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:372) 
  at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2988) 
  at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2421) 
  at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:671) 
  at net.sourceforge.jtds.jdbc.JtdsStatement.processResults(JtdsStatement.java:613) 
  at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:572) 
  at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeUpdate(JtdsPreparedStatement.java:727) 
  at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) 
  at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) 
  at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46) 
  at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2275) ... 68 more
Run Code Online (Sandbox Code Playgroud)

假设:

1.正如Sql Server网站提到的那样,十亿Guid创建的数据库中有1是重复的,因此我不希望表中存在重复的数据。

bru*_*aus 0

尽管问题集中在 Hibernate 上,但跟踪中的以下行表明数据库拒绝插入。

引起原因:java.sql.SQLException:违反主键约束“PK_DataHistory_on_DataHistoryGuid”。无法在对象“dbo.DataHistory”中插入重复的键。重复的键值为 (0500edac-0074-4324-3436-31444231342d)。

这更多的是一个设计问题,而不是 SQL Server 或 Hibernate 的问题。如果自动生成的 UUID 作为表PRIMARY KEY中的aDataHistory是您的目标,那么您最好使用数据库来实现此目的,而不是使用 Hibernate(或更糟糕的是,滚动您自己的解决方案)。UNIQUE INDEX这是因为如果指定了or ,数据库的设计目的是避免值冲突PRIMARY KEY

请参见SQL UNIQUE 约束

您可以使用创建自动生成的 UUID 的任务PRIMARY KEY DEFAULT (NEWID())。如果稍后需要使用 UUID,请在创建后使用非主键值来选择该值。

示例表:

CREATE TABLE dbo.DataHistory
(
    DatahistoryGuid uniqueidentifier PRIMARY KEY DEFAULT (NEWID()),
    history_row integer NOT NULL,
    data_stuff  nvarchar(4000) NOT NULL,
    created_date datetime2 DEFAULT (GETDATE())
);
Run Code Online (Sandbox Code Playgroud)

尝试将该insertable属性设置为falseHibernate。对数据库默认的所有列执行此操作。例如:

@Column(name = "DatahistoryGuid", insertable=false)
@Column(name = "created_date", insertable=false)
Run Code Online (Sandbox Code Playgroud)

这会产生类似于以下内容的 SQL:

INSERT INTO dbo.DataHistory (history_row, data_stuff)
VALUES (1234, 'Joe Bloggs');
Run Code Online (Sandbox Code Playgroud)

查看相关问题

要获取该DatahistoryGuid值,请使用以下SELECT语句:

SELECT DatahistoryGuid from dbo.DataHistory where history_row = 1234;
Run Code Online (Sandbox Code Playgroud)

SQL 小提琴示例