I have loop to save couple of objects. In loop a call service method and catch exceptions. Service save method is annotated @Transactional and inside does hibernate saveOrUpdate call.
Service is provided by getBean method of ApplicationContext object. I call it only once before loop.
In the loop, after i catch exception of oracle constraint violation :
org.hibernate.exception.constraintviolationexception: ora-00001: unique constraint (ccb.sys_c0017085) violated
I log problem and try to save another object. Next exception i get is:
org.hibernate.HibernateException: proxy handle is no longer valid
Sometimes it occurs only one time after each ora error but sometimes it repeats for more objects (iterations).
How to handle this exception & how to make save operation possible?
I’m using
Spring 3.1.3 and Hibernate 4.1.7.
[edit]
Some code sample:
@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]
last thing i noticed is that it does not occur on MS SQL Server, only on Oracle
I have different suggestions regarding your issue.
Suggestion 1 : you are wrongly reusing the same session in all transactions.
To check this : put a breakpoint in
saveRecordand check that the reference to theSessionImplis different in 2 successive calls.Honestly, there are few chances this is your problem because your code is running with MS SQL Server. So the only chance for this suggestion to be correct is that the constraints in MS SQL Server are not the same as the constraints in Oracle. Additionally, I think hibernate will throw a more explicit exception in this case.
Suggestion 2 : you are hitting a bug in hibernate 4
There are a few bug reports in hibernate JIRA in this area. (without your code, it’s difficult to say what’s your exact situation). There are good chance the behavior you have is linked to one of those bugs:
https://hibernate.onjira.com/browse/HHH-7688 (this one is very close to yours, but there some others)
Is there some workarounds to this bug ?
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 it will help, but transaction is handled by aop-proxy, and using reflection may cause to bypass some of the transaction manager code (it shouldn’t, but it’s an hypothesis to check).
Change the connection release mode : all those bugs (in hibernate JIRA) are more or less related to JdbcConnection management, so changing the connection release mode may at somepoint help you to identify the issue. (I don’t say that changing it is the solution, if you are really hitting a bug in hibernate: your best choice is probably to wait/contribute for the fix)
Downgrading to hibernate 3.X : Once again I don’t say it’s a solution, but it may indicate that you are really facing a bug in hibernate 4.
Upgrading to hibernate 4.2+ : As suggested in other answer and regarding recent changes in hibernate base code: simply upgrading hibernate may solve the problem.