-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Calling entityManager in catch DataIntegrityViol block
PostPosted: Thu Jun 26, 2008 10:07 am 
Newbie

Joined: Fri Sep 21, 2007 11:55 am
Posts: 4
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: hibernate 3.2.4.sp1, annotations 3.3.0.ga, entitymanager 3.3.1.ga

Full stack trace of any exception that occurs:

Name and version of the database you are using: Oracle 10


Hello,

I would like to handle unique constraints error in a try/catch block.
For this I need to call the entityManager in my catch block.
Is it allowed or is it forbidden ? (I've read some issues [1] about em inconsistent state, but it was never clear enough for me I suppose...).

With following code :
Code:
try {
    getEntityManager().persist(aEntity);
    getEntityManager().flush();
    return aEntity;
} catch (DataIntegrityViolationException err) {

      //just need to determine if it's a business exception (user entered illegal value)   
    String lRequest = "SELECT count(*) FROM Client c WHERE c.personne.matricule=:matricule ";
    Query lQuery = getEntityManager().createQuery(lRequest);
    lQuery.setParameter("matricule", aMatricule);
      //the following line always rethrows the exception
    Long lCount = (Long) lQuery.getSingleResult();
      if (lCount == 0) {
         throw new MatriculeExistantException(err);
      } else {
         throw err;
      }
}

Whenever the lQuery.getSingleResult() is called in my catch block, Hibernate generates once more the same DataIntegrityViolationException [2].


Any inputs appreciated thanks !

[1]
From EJB 3 Persistence specification
Quote:
In 3.3.2 Transaction rollback : 'Transaction rollback typically causes the persistence context to be in an inconsistent state at the point of rollback.
An in chapter 3.7 : 'All instances of PersistenceException (except NoResultException and NonUniqueResultException) will cause the current transaction to be marked for rollback).


Also, from Java persistence with hibernate chapter 10 Transactions and concurrency page 441 :
Quote:
All exceptions thrown by Hibernate are fatal. This means you have to rollback the database transaction and close the current session.
You aren't allowed to continue working with a session that threw an exception.


[2] Stack trace :
Code:
org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
   at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:624)
   at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:95)
   at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:335)
   at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:62)
   at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:212)
   at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:146)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy41.findIdForMatricule(Unknown Source)
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
   at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:92)
   at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
   at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:222)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2224)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2660)
   at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:41)
   at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:969)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1114)
   at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
   at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:66)
   ... 35 more
Caused by: java.sql.BatchUpdateException: ORA-00001: violation de contrainte unique (EDUOA.SPHXPERSONNE1)

   at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
   at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10720)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
   ... 59 more


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 26, 2008 7:01 pm 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
Hi,
you really should use rollback as first instruction in the catchblock;
after that make sure you get a new EntityManager with a new Session before using DB again.

_________________
Sanne
http://in.relation.to/


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 01, 2008 4:26 am 
Newbie

Joined: Fri Sep 21, 2007 11:55 am
Posts: 4
Thank you very much for your answer !

From what you say :
Quote:
Is it allowed or is it forbidden ? :

-> It is forbidden (em would be in inconsistent state)

I'll change my application code in order to prevalidate my constraints BEFORE calling persist.
This will be more simple than rolling back the em, closing it and creating a new one in the catch block.

Whenever I'll have an error generated by em.persist/merge methods, I'll assume it to be a fatal exception and bring the main error page to the user (instead for instance of presenting the input page).

So, my code is now sthing like :

Code:
public void mainMethod (Client aEntity) throws MatriculeExistantException {
  // prevalidation
  checkMatriculeExistant (aEntity.getMatricule());

  //data is OK, I'll call persist
  getEntityManager().persist(aEntity);
  getEntityManager().flush();
}

private void checkMatriculeExistant (String aMatricule) throws MatriculeExistantException{
  String lRequest = "SELECT count(*) FROM Client c WHERE c.personne.matricule=:matricule ";
  Query lQuery = getEntityManager().createQuery(lRequest);
  lQuery.setParameter("matricule", aMatricule);
  //the following line always rethrows the exception
  Long lCount = (Long) lQuery.getSingleResult();
  if (lCount == 0) {
     throw new MatriculeExistantException(err);
  }
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.