Java – HibernateException: the proxy handle is no longer valid after the database violation error
I have a loop to hold several objects Invoke the service method in the loop and catch the exception. The service saves the method annotation @ transactional, and internally executes the hibernate saveOrUpdate call
In the loop, after I catch the exception of Oracle constraint violation:
I record the problem and try to save another object The next exception I get is:
Sometimes it happens only once after each ora error, but sometimes it repeats more objects (iterations)
How do I handle this exception & how do I make saving possible?
I'm using spring 3.1 3 and Hibernate 4.1 seven
[Edit] some code examples:
@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 my cycle, I do:
//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
[Edit] stack trace:
PreparedStatementProxyHandler(AbstractProxyHandler).errorIfInvalid() line: 63 PreparedStatementProxyHandler(AbstractStatementProxyHandler).continueInvocation(Object,Method,Object[]) line: 100 PreparedStatementProxyHandler(AbstractProxyHandler).invoke(Object,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,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,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
[editor] the last thing I noticed is that it will not happen on MS SQL server, but only on Oracle
Solution
I have different suggestions for your problem
Recommendation 1: you mistakenly reuse the same session in all transactions
To check this, place a breakpoint in saverecord and check whether the reference to sessionimpl is different in two consecutive calls
To be honest, it is unlikely that this is your problem, because your code runs with MS SQL server Therefore, the only chance that this proposal is correct is that the constraints in MS SQL server are different from those in Oracle In addition, I think hibernate will throw a more explicit exception in this case
Suggestion 2: you are experiencing a bug in Hibernate 4
There are some bug reports in Hibernate JIRA in this field Without your code, it's hard to tell your specific situation Your behavior is most likely associated with one of these errors:
https://hibernate.onjira.com/browse/HHH-7688 (this is very close to yours, but there are others)
Are there any solutions to this bug?
Suggestions I have hardly tried:
Hibernate jdbc. batch_ Size is set to a value higher than 1 This solution, suggested here by Michael wyraz, seems to be effective
Don't use reflection: I'm not sure it will be useful, but transactions are handled by AOP proxy, and using reflection may lead to bypassing some transaction manager code (it shouldn't, but it's a checking assumption)
Change connection release mode: all these errors (in sleep JIRA) are more or less related to jdbcconnection management, so changing connection release mode may help you identify problems at some time (I'm not saying that changing it is a solution. If you really encounter a bug in Hibernate: your best choice may be to wait / contribute to the repair)
Downgrade to sleep 3 10: Again, I won't say it's a solution, but it may indicate that you really encountered a bug in Hibernate 4
Upgrade to hibernate 4.2: as suggested by other answers, the latest change in Hibernate basic code: simply upgrading hibernate may solve the problem