[Spring+Hibernate]SQLException vertaling

Pagina: 1
Acties:
  • 107 views sinds 30-01-2008
  • Reageer

  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 30-04 14:30
Ik heb volgende situatie:

ik wel een object verwijderen, maar dit kan niet door een referentiële beperking op databank nivo.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
[22/08/05 16:08:09:113 CEST] 39575699 SystemErr     R [C501BBJO][Appartementen] 22 aug 2005 16:08:09,097 ERROR JDBCExceptionReporter:72 - [SQL0532] Wissen verhinderd door referentiële beperking QSYS_SITEID_00004 in LIBTN01COB.
[22/08/05 16:08:09:129 CEST] 39575699 SystemErr     R [C501BBJO][Appartementen] 22 aug 2005 16:08:09,113 ERROR AbstractFlushingEventListener:277 - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not delete: [be.xx.apartment.vo.Site#18]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:63)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.persister.entity.BasicEntityPersister.delete(BasicEntityPersister.java:2076)
    at org.hibernate.persister.entity.BasicEntityPersister.delete
...(HibernateTemplate.java:313)
    at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:686)
    at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:682)
    at be.xx.apartment.dao.iSeries.SiteDAOImpl.deleteSite(SiteDAOImpl.java:43)
    at be.xx.apartment.bo.SiteBO.deleteSite(SiteBO.java:73)
...
Caused by: java.sql.SQLException: [SQL0532] Wissen verhinderd door referentiële beperking QSYS_SITEID_00004 in LIBTN01COB.
    at com.ibm.as400.access.JDError.throwSQLException(JDError.java:643)
    at com.ibm.as400.access.JDError.throwSQLException(JDError.java:614)
    at com.ibm.as400.access.AS400JDBCStatement.commonExecute(AS400JDBCStatement.java:862)
    at com.ibm.as400.access.AS400JDBCPreparedStatement.executeUpdate(AS400JDBCPreparedStatement.java:1135)
    at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.executeUpdate(WSJdbcPreparedStatement.java:471)
    at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
    at org.hibernate.persister.entity.BasicEntityPersister.delete(BasicEntityPersister.java:2059)
    ... 60 more
[22/08/05 16:08:09:129 CEST] 39575699 SystemErr     R cause == java.sql.SQLException: [SQL0532] Wissen verhinderd door referentiële beperking QSYS_SITEID_00004 in LIBTN01COB. code = -532
[22/08/05 16:08:20:254 CEST]  9a85699 WebGroup      I SRVE0180I: [<null>] [/appartementen] [Servlet.LOG]: /jsp/content/articleDefinition/search.jsp: init
[22/08/05 16:08:20:300 CEST]  9a85699 WebGroup      I SRVE0180I: [<null>] [/appartementen] [Servlet.LOG]: /jsp/content/articleDefinition/contentTop.jsp: init
[22/08/05 16:08:20:379 CEST]  9a85699 WebGroup      I SRVE0180I: [<null>] [/appartementen] [Servlet.LOG]: /jsp/content/articleDefinition/buttonsTop.jsp: init
[22/08/05 16:08:20:394 CEST]  9a85699 WebGroup      I SRVE0180I: [<null>] [/appartementen] [Servlet.LOG]: /jsp/content/articleDefinition/contentBottom.jsp: init
[22/08/05 16:08:20:425 CEST]  9a85699 WebGroup      I SRVE0180I: [<null>] [/appartementen] [Servlet.LOG]: /jsp/content/articleDefinition/buttonsBottom.jsp: init
[22/08/05 16:08:22:160 CEST]  9a85699 SystemErr     R [C501BBJO][Appartementen] 22 aug 2005 16:08:22,160 ERROR JDBCExceptionReporter:72 - [SQL0532] Wissen verhinderd door referentiële beperking QSYS_ARTIC00001_00001 in LIBTN01COB.
[22/08/05 16:08:22:175 CEST]  9a85699 SystemErr     R [C501BBJO][Appartementen] 22 aug 2005 16:08:22,160 ERROR AbstractFlushingEventListener:277 - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not delete: [be.xx.apartment.vo.ArticleDefinition#106]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:63)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.persister.entity.BasicEntityPersister.delete(BasicEntityPersister.java:2076)
        
... at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java(Compiled Code))
Caused by: java.sql.SQLException: [SQL0532] Wissen verhinderd door referentiële beperking QSYS_ARTIC00001_00001 in LIBTN01COB.
    at com.ibm.as400.access.JDError.throwSQLException(JDError.java:643)
    at com.ibm.as400.access.JDError.throwSQLException(JDError.java:614)
    at com.ibm.as400.access.AS400JDBCStatement.commonExecute(AS400JDBCStatement.java:862)
    at com.ibm.as400.access.AS400JDBCPreparedStatement.executeUpdate(AS400JDBCPreparedStatement.java:1135)
    at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.executeUpdate(WSJdbcPreparedStatement.java:471)
    at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
    at org.hibernate.persister.entity.BasicEntityPersister.delete(BasicEntityPersister.java:2059)
    ... 60 more
[22/08/05 16:08:22:175 CEST]  9a85699 SystemErr     R cause == java.sql.SQLException: [SQL0532] Wissen verhinderd door referentiële beperking QSYS_ARTIC00001_00001 in LIBTN01COB. code = -532


Ik krijg dus eerst een zinnige org.hibernate.exception.ConstraintViolationException (hier weet ik dat het om een constraint gaat) deze heeft als cause een SQLException -532.

Daarna zie ik dat Spring er een org.springframework.dao.DataIntegrityViolationException van maakt (afgeleid van de DataAccessException). Deze zegt al een stuk minder over de aard van fout. Ik zou dan verwachten dat DataIntegrityViolation als cause de zinnige org.hibernate.exception.ConstraintViolationException heeft, maar deze heeft enkel de SQLException met foutcode als cause exception.

Ik zou verwachten dat de cause van de Spring DataAccessException die hibernate exception is en de cause van deze hibernate exception dan de SQL exception. Blijkbaar is dit niet zo ?

Als ik nu wil weten welk fout juist optrad moet ik nu terug deze SQL exception gaan analyseren en adhv de foutcode de juist exception aanmaken...

nogal omslachtig en dubbel werk niet ? zeker omdat je weet dat de hibernate exception translator er wel weg mee kan

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 28-04 15:07
Wat moet je eigenlijk met die "correcte" exception dan? Je kan toch in het log zien wat er misgaat en dit oplossen?

Je verwacht deze exceptions toch niet in een productiesituatie?

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 01-05 20:17

Janoz

Moderator Devschuur®

!litemod

In principe is een DataIntegrityViolationException hetzelfde als een ConstraintViolationException. Beiden geven aan dat de operatie mislukt is vanwege een constraint. Er gaat dus geen informatie verloren. Daarnaast is het niet wenselijk dat je code afhankelijk is van de cause van de exception. Het hele idee van die spring excepties is juist dat je de verschillende lagen los koppelt. De cause uitlezen betekend dat je buisness laag afhankelijk wordt van jdbc/sqlexceptions of hibernate. Dat is niet alleen lastig bij het (redelijk onwaarschijnlijke) geval dat voor een andere O/R mapper gekozen wordt, maar vooral erg lastig bij het schrijven van testcode.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 30-04 14:30
matthijsln schreef op maandag 22 augustus 2005 @ 23:42:
Je verwacht deze exceptions toch niet in een productiesituatie?
Waarom zouden deze exceptions niet in productie mogen voorkopen? Het kan toch zijn dat een gebruiker een object wil wissen, maar dit niet kan doordat andere objecten er van afhankelijk zijn? Ik vind het net heel handig dat ik hier een exceptie krijg en zo aan de gebruiker kan vertrellen wat verkeerd ging bij het verwijderen
Janoz schreef op dinsdag 23 augustus 2005 @ 08:59:
In principe is een DataIntegrityViolationException hetzelfde als een ConstraintViolationException. Beiden geven aan dat de operatie mislukt is vanwege een constraint. Er gaat dus geen informatie verloren.
Ja hebt wel gelijk, maar er kan meestal meer informatie uitgehaald worden dan net een DataIntegriteitException alleen. Bv het verschil tussen een duplicate key en een referentie constraint.

Hier is het ook handig dat je naar de gebruiker kan melden dat er bv al een object met deze naam bestaat als er een duplicate key exception geworpen wordt.
Daarnaast is het niet wenselijk dat je code afhankelijk is van de cause van de exception.
Het hele idee van die spring excepties is juist dat je de verschillende lagen los koppelt. De cause uitlezen betekend dat je buisness laag afhankelijk wordt van jdbc/sqlexceptions of hibernate.
Ik heb hier als het ware een soort tussenlaag gemaakt. Alle DAO operaties geven een Spring DataAccessException terug. Deze vorm ik dan om naar eigen Businessexceptions. Dit is in feite niet meer dan een exceptie met een correct uitleg van wat fout is gegaan, en deze BusinessExceptions kunnen dan afgehandeld worden in de Controller laag.

een korte schets:

daoService.save(object) --> DataAccessException dae --> throw new BusinessException(dae) [ = deze zorgt dan dat de DataAccessException geinterpreteerd wordt en er juiste informatie naar de gebruiker kan gestuurd worden].

"Live as if you were to die tomorrow. Learn as if you were to live forever"