Announcement Announcement Module
Collapse
No announcement yet.
Can't manage to catch a Spring exception!? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can't manage to catch a Spring exception!?

    Spring : 1.0.2 - Hibernate : 2.1 - Oracle : 8.1.7

    Full stack trace of exception that occurs:

    Code:
    org.springframework.dao.DataIntegrityViolationException: (HibernateTemplate): data integrity violated by SQL 'null'; nested exception is java.sql.BatchUpdateException: ORA-02292: integrity constraint (VENTES_TRAD.FK_INFO_VEN_CONCERNE_ARTICLE) violated - child record found 
    
    org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.translate(SQLStateSQLExceptionTranslator.java:82) 
    org.springframework.orm.hibernate.HibernateTransactionManager.convertJdbcAccessException(HibernateTransactionManager.java:516) 
    org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:394) 
    org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:314) 
    org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:126) 
    com.match.ventestrad.service.PeriodeService.deletePeriode(PeriodeService.java:133) 
    com.match.ventestrad.web.actions.GererPeriodesAction.perform(GererPeriodesAction.java:66) 
    org.apache.struts.action.ActionServlet.processActionPerform(ActionServlet.java:1787) 
    org.apache.struts.action.ActionServlet.process(ActionServlet.java:1586) 
    org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:492) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:743) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
    MAPPING Of objects :

    Code:
    <class name="Periode" table="periode"> 
       <id name="id" column="id_periode" type="integer" unsaved-value="null"> 
          <generator class="sequence"> 
             <param name="sequence">seq_periode</param> 
          </generator> 
       </id> 
       <property name="libelle" column="lc_libelle" type="string" /> 
       <property name="dateDebut" column="da_date_debut" type="date" /> 
       <property name="dateFin" column="da_date_fin" type="date" /> 
       <property name="visibleMags" column="fl_visible_mag" type="boolean" /> 
       <bag name="articles" table="article" lazy="true" inverse="true" cascade="all-delete-orphan" order-by="co_sous_secteur, co_code"> 
          <key column="id_periode" /> 
          <one-to-many class="Article" /> 
       </bag> 
    </class> 
    
    <class name="Article" table="article"> 
       <id name="id" column="id_article" type="integer" unsaved-value="null"> 
          <generator class="sequence"> 
             <param name="sequence">seq_article</param> 
          </generator> 
       </id> 
       <property name="code" column="co_code" type="string" /> 
       <property name="libelle" column="ll_libelle" type="string" /> 
       <many-to-one name="periode" column="id_periode" class="Periode" cascade="none" outer-join="true" /> 
    </class>
    My problem : i'm trying to delete an object 'Periode' which contains a list of objects 'Article' with this code :

    Code:
    public class PeriodeService &#123;
      &#91;...&#93;
      public Map savePeriodes&#40;final Map periodes&#41; throws ServiceException &#123;
        TransactionTemplate template = new TransactionTemplate&#40;ptm&#41;;
        return &#40;Map&#41; template.execute&#40;new TransactionCallback&#40;&#41; &#123;
          public Object doInTransaction&#40;TransactionStatus status&#41; &#123;
            try &#123;
              Iterator itPeriodes = periodes.keySet&#40;&#41;.iterator&#40;&#41;;
              while &#40;itPeriodes.hasNext&#40;&#41;&#41; &#123;
                periodeDAO.saveOrUpdate&#40;periodes.get&#40;itPeriodes.next&#40;&#41;&#41;&#41;;
              &#125;
              return periodes;
            &#125;
            catch &#40;DataAccessException e&#41; &#123;
              throw new ServiceException&#40;"LA SAUVEGARDE A ECHOUE", e&#41;;
            &#125;
          &#125;
        &#125;&#41;;
      &#125;
    &#125;
    
    public class PeriodeDAOImpl implements PeriodeDAO &#123;
      &#91;...&#93;
      public void delete&#40;final Object obj&#41; throws DataAccessException &#123; 
        hibernateTemplate.execute&#40;new HibernateCallback&#40;&#41; &#123; 
          public Object doInHibernate&#40;Session session&#41; throws HibernateException &#123; 
            session.delete&#40;obj&#41;; 
            return null; 
          &#125; 
        &#125;&#41;; 
      &#125; 
    &#125;
    and i got an exception because of an integrity violation due to database constraints on 'Article' (that's normal : other objects depends on 'Article' records but are not deleted before...).

    But what is not normal is that i can't manage to catch the exception so as to write a 'decent' message instead of having an horrible stacktrace on my html page...

    Anyone has an idea why the Exception is not caught?

    (DataIntegrityViolationException is a subclass od DataAccessException so I thought it would be caught...)

    Thx in advance

  • #2
    it's about when the flush is happening

    The changes made in your savePeriodes() method get flushed to the database only before the transaction completes. The calls to the hibernate session get transalated into actual calls to the database only when the transaction is about to end. If you want to explicitelly flush your changes and catch the exception as you want in your code, you need to add a hibernateSession.flush() in your PeriodeDAOImpl code. The simpler way is to let it bubble up in the web layer and put there (in the controller) the appropriate exception handling.

    regards, Croco.

    Comment


    • #3
      That's It!

      Thanks a lot Croco, it works fine now!!

      Comment


      • #4
        I think I saw this topic posted on the Hibernate forums also...it would be good to post the solution and explanation there, too, as they concern Hibernate users.

        Comment


        • #5
          Done!

          Thanks for advice Rod.

          Comment


          • #6
            Originally posted by croco View Post
            The changes made in your savePeriodes() method get flushed to the database only before the transaction completes. The calls to the hibernate session get transalated into actual calls to the database only when the transaction is about to end. If you want to explicitelly flush your changes and catch the exception as you want in your code, you need to add a hibernateSession.flush() in your PeriodeDAOImpl code. The simpler way is to let it bubble up in the web layer and put there (in the controller) the appropriate exception handling.

            regards, Croco.
            Can this be possibly done in iBATIS? I am using SqlMapClientDaoSupport and purposely updated a property that has a foreign key constraint (on update restrict, on delete restrict) to another table. I am just using the getSqlMapClientTemplate().update(<String>,<Object> ) method and I was returned a stacktrace for an error. I expected to have an error but I also expected Spring to be able to handle the error.

            Comment


            • #7
              What do you mean you want Spring to handle the error, presumably it rolled back the transaction for you.
              Last edited by karldmoore; Aug 29th, 2007, 10:05 AM.

              Comment


              • #8
                I expected that Spring would output (through the logs) some information that the update will not push through because of a constraint instead of a stacktrace printout like this:

                Code:
                2007-07-13 10:08:26,984 main
                 [INFO ] org.springframework.jdbc.support.SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2, Derby, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
                2007-07-13 10:08:26,984 main
                 [DEBUG] org.springframework.jdbc.support.SQLErrorCodesFactory - Looking up default SQLErrorCodes for DataSource [org.apache.commons.dbcp.BasicDataSource@14eaec9]
                2007-07-13 10:08:27,000 main
                 [DEBUG] org.springfr
                Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:   
                --- The error occurred in ibatis/loan.xml.  
                --- The error occurred while applying a parameter map.  
                --- Check the updateLoan-InlineParameterMap.  
                --- Check the statement (update failed).  
                --- Cause: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`pay/pay_loan`, CONSTRAINT `FK_pay_loan_freq` FOREIGN KEY (`frequency`) REFERENCES `pay_frequency` (`code`))
                	at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeUpdate(GeneralStatement.java:91)
                	at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.update(SqlMapExecutorDelegate.java:505)
                	at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.update(SqlMapSessionImpl.java:90)
                	at org.springframework.orm.ibatis.SqlMapClientTemplate$10.doInSqlMapClient(SqlMapClientTemplate.java:383)
                	at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:193)
                	at org.springframework.orm.ibatis.SqlMapClientTemplate.update(SqlMapClientTemplate.java:381)
                	at pay.dao.ibatis.SqlMapClientLoanDao.updateLoan(SqlMapClientLoanDao.java:55)
                	at pay.dao.ibatis.test.TestIbatisLoan.run(TestIbatisLoan.java:75)
                	at pay.dao.ibatis.test.TestIbatisLoan.main(TestIbatisLoan.java:139)
                Caused by: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`pay/pay_loan`, CONSTRAINT `FK_pay_loan_freq` FOREIGN KEY (`frequency`) REFERENCES `pay_frequency` (`code`))
                	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931)
                	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2870)
                	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
                	at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1169)
                	at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:693)
                	at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:794)
                	at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:169)
                	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                	at java.lang.reflect.Method.invoke(Unknown Source)
                	at com.ibatis.common.jdbc.logging.PreparedStatementLogProxy.invoke(PreparedStatementLogProxy.java:62)
                	at $Proxy3.execute(Unknown Source)
                	at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeUpdate(SqlExecutor.java:81)
                	at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteUpdate(GeneralStatement.java:200)
                	at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeUpdate(GeneralStatement.java:78)
                	... 8 more
                amework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
                2007-07-13 10:08:27,015 main
                 [DEBUG] org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
                2007-07-13 10:08:27,015 main
                 [DEBUG] org.springframework.jdbc.support.SQLErrorCodesFactory - Database product name cached for DataSource [org.apache.commons.dbcp.BasicDataSource@14eaec9]: name is 'MySQL'
                2007-07-13 10:08:27,015 main
                 [DEBUG] org.springframework.jdbc.support.SQLErrorCodesFactory - SQL error codes for 'MySQL' found
                2007-07-13 10:08:27,015 main
                 [DEBUG] org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - Unable to translate SQLException with Error code '1452', will now try the fallback translator
                2007-07-13 10:08:27,015 main
                 [DEBUG] org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource

                Comment


                • #9
                  Is it possible to see the code and configuation you are using, I'm not sure I understand the problem.
                  Last edited by karldmoore; Aug 29th, 2007, 10:05 AM.

                  Comment

                  Working...
                  X