Results 1 to 9 of 9

Thread: Can't manage to catch a Spring exception!?

  1. #1
    Join Date
    Dec 2004
    Posts
    10

    Default 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. #2
    Join Date
    Dec 2004
    Location
    Bucuresti, Romania
    Posts
    72

    Default 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.

  3. #3
    Join Date
    Dec 2004
    Posts
    10

    Default That's It!

    Thanks a lot Croco, it works fine now!!

  4. #4
    Join Date
    Aug 2004
    Location
    San Mateo, CA
    Posts
    1,265

    Default

    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.
    Rod Johnson - GM, SpringSource Division, VMware
    http://www.springsource.com
    Spring From the Source

  5. #5
    Join Date
    Dec 2004
    Posts
    10

    Default

    Done!

    Thanks for advice Rod.

  6. #6

    Default

    Quote 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.

  7. #7
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    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 at 10:05 AM.
    Barracuda Networks SSL VPN Lead Developer
    http://pramatr.wordpress.com
    http://twitter.com/karldmoore
    http://www.linkedin.com/in/karldmoore
    Any postings are my own opinion, and should not be attributed to my employer or clients.

  8. #8

    Default

    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

  9. #9
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    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 at 10:05 AM.
    Barracuda Networks SSL VPN Lead Developer
    http://pramatr.wordpress.com
    http://twitter.com/karldmoore
    http://www.linkedin.com/in/karldmoore
    Any postings are my own opinion, and should not be attributed to my employer or clients.

Similar Threads

  1. Context initialization failed
    By kanonmicke in forum Container
    Replies: 7
    Last Post: Sep 29th, 2005, 12:35 AM
  2. Replies: 1
    Last Post: May 22nd, 2005, 10:00 PM
  3. Replies: 14
    Last Post: Feb 21st, 2005, 05:41 PM
  4. Replies: 2
    Last Post: Jan 21st, 2005, 04:17 AM
  5. Replies: 3
    Last Post: Nov 8th, 2004, 07:30 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •