HibernateException: Proxy handler no longer takes effect after database violation error
I have a loop to save multiple objects. In the loop, call and exception call method catch. The service save method is annotated with @Transactional and hibernate saveOrUpdate is called internally. The service is provided by the getBean method of the ApplicationContext object. I only call this once before the loop.
In the loop after I catch the oracle constraint violation exception:
org.hibernate.exception.constraintviolationexception: ora-00001: unique constraint (ccb.sys_c0017085) violated
I am logging a problem and am trying to save another object. The following exception I am getting:
org.hibernate.HibernateException: Proxy handle is no longer valid
Sometimes this only happens once after each ora error, but sometimes it repeats for more objects (iterations).
How do I deal with this exception and how do I make the save operation possible?
I am using Spring 3.1.3 and Hibernate 4.1.7.
[edit] Code example:
@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;
}
...
and in my loop 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, 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
[edit] the last thing I noticed is that this doesn't happen on MS SQL Server, only on Oracle
source to share
I have different suggestions regarding your problem.
Suggestion 1 : You are using the same session incorrectly across all transactions.
To test this: put a breakpoint at saveRecord
and check that the reference to SessionImpl
differs in two successive calls.
To be honest, you have little chance that this is your problem because your code is running on MS SQL Server. So the only chance for this proposal to be true is that the limits in MS SQL Server are not the same as those in Oracle. Also, I think hibernate will throw a more explicit exception in this case.
Suggestion 2 : you run into error in sleep mode 4
There are several bug reports in JIRA hibernation in this area. (without your code, it's hard to tell which situation exactly). Chances are good that your behavior is related to one of these errors:
https://hibernate.onjira.com/browse/HHH-7688 (this one is very close to yours, but there are others)
Are there any workarounds for this error?
I have few suggestions to try:
set hibernate.jdbc.batch_size to something above 1 . This workaround was suggested here by Michale Wyraz and seems to work.
Don't use reflection : Not sure if this helps, but the transaction is handled by aop-proxy, and using reflection might bypass some of the transaction manager code (it shouldn't, but that's a hypothesis to test).
Change connection release mode : All of these errors (in JIRA hibernation) are more or less related to JdbcConnection management, so changing the connection release mode may help you identify the problem at some point. (I am not saying this change is a solution if you actually run into an error while sleeping: your best bet is probably to wait / contribute to the fix)
Hibernation 3.X : Again I am not saying this solution, but it may indicate that you are indeed encountering an error in hibernation 4.
Upgrading to hibernate 4.2+ : as suggested in another answer and regarding recent changes to the underlying hibernate code: just upgrading hibernate might fix the issue.
source to share
I lost hours with a similar issue trying to close the session and unfortunately none of the ben75 suggestions worked. This was my environment:
- error message:
org.hibernate.HibernateException: proxy handle is no longer valid ...
- hibernate version 4.1.7
- application server: IBM WebSphere 7
so it was only in case anyone else encounters this error that the solution that worked for me was upgrade to Hibernate 4.2. Required banks:
- ANTLR-2.7.7.jar
- dom4j-1.6.1.jar
- hibernation-wikimedia Commons annotation-4.0.1.Final.jar
- hibernate-core-4.2.0.Final.jar
- hibernate jpa-2.0-api-1.0.1.Final.jar-
- Javassist-3.15.0-GA.jar
- JBoss Logging 3.1.0.GA.jar
- Jboss-transaction api_1.1_spec-1.0.0.Final.jar
NTN.
source to share
Hibernate 4.1.3 does not close batch statements if they throw an exception (in org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch ()). You catch an exception, rollback the current transaction, start a new one, and hope everything will be perfect. But if you run your own update script (for example), after running, you finally need to close the instructions. And here it is, an unclosed (now disabled due to rollback) operator throws this exception and your new transaction goes wrong. Fortunately, before the new exception, the instructions are flushed, so only the first update is wrong ... I created a handler method that I call on every rollback (in this case, it is called after the first exception).and after rolling back and starting, I create a dummy (and quick) update (update [tablename] set [column] = [column] where 1 = 2) and execute it. This throws the error above, I catch it, rollback the transaction again and create a new one, so I exit the method with a good hibernate session and a live transaction. This is an ugly workaround, but now I can't update the hibernate version ...
source to share