当前位置: 首页 > 面试题库 >

HibernateException:数据库违规错误后,代理句柄不再有效

马侯林
2023-03-14
问题内容

我有循环来保存几个对象。循环调用服务方法并捕获异常。服务保存方法带有@Transactional注释,并且在内部进行hibernatesaveOrUpdate调用。服务由ApplicationContext对象的getBean方法提供。我在循环之前只调用一次。

在循环中,在我捕获到oracle约束违反异常之后:

org.hibernate.exception.constraintviolationexception:ORA-00001:违反了唯一约束(ccb.sys_c0017085)

我记录问题并尝试保存另一个对象。我得到的下一个例外是:

org.hibernate.HibernateException:代理句柄不再有效

有时,它仅在每个ora错误之后发生一次,但有时会针对更多对象(迭代)重复。

如何处理此异常以及如何使保存操作成为可能?

我正在使用Spring 3.1.3和Hibernate 4.1.7。

[编辑]一些代码示例:

@Service
public class ServiceForRecord {
    @Transactional
public Record saveRecord(Record record, String user) {
      Record obj = record;
      // some validation & seting internal values
      getHibernateTemplate().saveOrUpdate(obj)
      return obj;
    }
...

在我的循环中,我这样做:

//in params:
serviceClass = ServiceForRecord.class;
entityClass = Record.class;
saveMethod = "saveRecord";
//loop prepare
service = getApplicationContext().getBean(serviceClass);
serviceSave = serviceClass.getMethod("saveRecord", Record.class, String.class);
while (condition) {
entity =  BeanUtils.instantiate(entityClass);
//setup entity
serviceSave.invoke(service, entity, "testUser");
//catch error
} //end while

[编辑]堆栈跟踪:

PreparedStatementProxyHandler(AbstractProxyHandler).errorIfInvalid() line: 63   
PreparedStatementProxyHandler(AbstractStatementProxyHandler).continueInvocation(Object, Method, Object[]) line: 100 
PreparedStatementProxyHandler(AbstractProxyHandler).invoke(Object, Method, Object[]) line: 81   
$Proxy100.clearBatch() line: not available  
NonBatchingBatch(AbstractBatchImpl).releaseStatements() line: 163   
NonBatchingBatch(AbstractBatchImpl).execute() line: 152 
JdbcCoordinatorImpl.getBatch(BatchKey) line: 151    
SingleTableEntityPersister(AbstractEntityPersister).insert(Serializable, Object[], boolean[], int, String, Object, SessionImplementor) line: 2940   
SingleTableEntityPersister(AbstractEntityPersister).insert(Serializable, Object[], Object, SessionImplementor) line: 3403   
EntityInsertAction.execute() line: 88   
ActionQueue.execute(Executable) line: 362   
ActionQueue.executeActions(List) line: 354  
ActionQueue.executeActions() line: 275  
DefaultFlushEventListener(AbstractFlushingEventListener).performExecutions(EventSource) line: 326   
DefaultFlushEventListener.onFlush(FlushEvent) line: 52  
SessionImpl.flush() line: 1210  
SessionImpl.managedFlush() line: 399    
JdbcTransaction.beforeTransactionCommit() line: 101 
JdbcTransaction(AbstractTransactionImpl).commit() line: 175 
HibernateTransactionManager.doCommit(DefaultTransactionStatus) line: 480    
HibernateTransactionManager(AbstractPlatformTransactionManager).processCommit(DefaultTransactionStatus) line: 754   
HibernateTransactionManager(AbstractPlatformTransactionManager).commit(TransactionStatus) line: 723 
TransactionInterceptor(TransactionAspectSupport).commitTransactionAfterReturning(TransactionAspectSupport$TransactionInfo) line: 392    
TransactionInterceptor.invoke(MethodInvocation) line: 120   
ReflectiveMethodInvocation.proceed() line: 172  
AfterReturningAdviceInterceptor.invoke(MethodInvocation) line: 50   
ReflectiveMethodInvocation.proceed() line: 172  
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 202   
$Proxy71.save(Account, String) line: not available  
GeneratedMethodAccessor115.invoke(Object, Object[]) line: not available 
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available   
Method.invoke(Object, Object...) line: not available    
ImportServiceProvider.save(Object, String) line: 380

我注意到的最后一件事是它不会在MS SQL Server上发生,仅在Oracle上会发生


问题答案:

关于您的问题,我有不同的建议。

建议1 :您在所有交易中都错误地重用了同一会话。

要检查此问题,请执行以下操作:放入一个断点,saveRecord并检查SessionImpl2个连续调用中对的引用是否不同。

老实说,这是您的问题的几率很小,因为您的代码正在与MS SQL Server一起运行。因此,此建议正确的唯一机会是MS SQL
Server中的约束与Oracle中的约束不同。另外,我认为在这种情况下,hibernate将抛出更明确的异常。

建议2 :您在hibernate4中遇到错误

hibernateJIRA中有一些有关此区域的错误报告。(没有您的代码,很难说出您的确切情况)。您的行为很有可能与这些错误之一相关:

https://hibernate.onjira.com/browse/HHH-7688(这个位置与您的位置非常接近,但还有其他位置)

这个错误有一些解决方法吗?

我有一些建议可以尝试:

将hibernate.jdbc.batch_size设置为大于1的值 。此解决方法由Michale Wyraz
建议在此处使用,并且似乎有效。

不要使用反射 :不确定它是否会帮助,但是事务是由aop-
proxy处理的,并且使用反射可能会导致绕过某些事务管理器代码(不应该这样做,但这是要检查的假设)。

更改连接释放模式 :所有这些bug(在hibernateJIRA中) 或多或少都
与JdbcConnection管理有关,因此更改连接释放模式可能会在某个时候帮助您识别问题。(如果您确实遇到了hibernate中的错误,那么我并不是说更改它是解决方案:您最好的选择可能是等待/提供此修复程序

降级到hibernate3.X :我再也不说这是一种解决方案,但是它可能表明您确实面临着hibernate4中的错误。

升级到hibernate 4.2+ :如其他答案中所建议的,并且有关hibernate基本代码的 最新
更改:只需升级hibernate即可解决问题。



 类似资料:
  • react_devtools_backend。js:2273不变违规:缩小反应错误#152;参观http://reactjs.org/docs/error-decoder.html?invariant=152 当我在本地运行项目时不会出现此问题,但在AWS服务器上部署代码后,可以在控制台中看到此问题。 请帮助,还有一件事如何在本地调试此问题?

  • 问题内容: 使用PDO更新数据库时出现错误。我是PDO的新手,所以问题可能很小,我只是不明白。 关于错误的有趣的是,该命令可以正常运行,并且数据库确实得到了更新。 但是它仍然向我返回错误。 码: 错误: 错误更新内容:SQLSTATE [HY000]:一般错误 我真的不知道问题可能在哪里,因为它非常怪诞,而且我无法找到遇到相同问题的任何人。 问题答案: 您不使用fetchAll(),如 与更新或插

  • 我有一个API运行在AWS Lambda和AWS Gateway使用Up。我的API在启动时创建一个数据库连接,因此Lambda在第一次触发该函数时会这样做。我的API是用node写的,使用Express和pg-promise来连接和查询数据库。 问题是Lambda在它认为合适的情况下创建函数的新实例,有时看起来好像一次有多个实例。 由于我的 Lambda 函数占用了太多数据库句柄,我的数据库连接

  • 你可以创建任何MATLAB函数的句柄,然后用这些句柄作为函数链接的途径。函数句柄主要用来传递自变量列表给其他函数,用句柄执行函数或求值。 在MATLAB中,通过在函数名前加上符号@构造函数句柄。下面例子为SIN函数创建一个函数句柄,然后赋值给变量fhandle: fhandle = @sin; 用MATLAB的fevel函数对函数句柄求值。下面的plot_fhandle函数接收一个函数句柄和数据

  • 问题内容: 我写了一个简单的程序。只是CTabItem固有的CTabFolder和WelcomTab。我想通过呈现我的html的浏览器填充我的WelcomeTab。在WelcomeTab的init()方法上,我创建了一个浏览器,但是当程序要构造它时,出现此错误 … 另外,我在基于Arch-Linux的KDE上使用Eclipse 3.7,因为我在各处搜索到此错误时都发现线程受限,所以这是一个简单的程

  • 我正在使用改装连接到REST服务器,我需要处理成功响应和错误响应。我基于此示例构建我的客户机。 例如,在get token方法上,服务器成功响应具有以下结构: 故障响应是: 我的问题是,应用程序将错误响应视为成功。我的代码是: -rest api方法接口: -模型登录响应: -模型错误响应: -Rest回调: -客户端类别: 错误在哪里?