J'ai une question. J'utilise le printemps + hibernate et je ne peux pas gérer des exceptions dans des méthodes marquées comme
de
Les classes DAO sont marquées avec @RePository.
Voici Snipper de mon ancien code.
en service: strong>
P> 2013-10-21 14:51:17 ERROR BookingController:89 - Unhandled exception
org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into booking (ticket_id, user_id, booking_id) values (?, ?, ?)]; constraint ["CONSTRAINT_INDEX_2 ON PUBLIC.BOOKING(TICKET_ID) VALUES ( /* key:1 */ 2, 1, 1)"; SQL statement:
insert into booking (ticket_id, user_id, booking_id) values (?, ?, ?) [23505-173]]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:643)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
at cdp.tarasenko.springmvc.task3.service.TicketsService$$EnhancerByCGLIB$$fabdc899.bookTickets(<generated>)
at cdp.tarasenko.springmvc.task3.controller.BookingController.bookTickets(BookingController.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:594)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:486)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:413)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111)
at org.eclipse.jetty.server.Server.handle(Server.java:351)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:900)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:954)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:857)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:609)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:45)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534)
at java.lang.Thread.run(Thread.java:662)
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.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
... 51 more
Caused by: org.h2.jdbc.JdbcBatchUpdateException: ÐаÑÑÑение ÑникалÑного индекÑа или пеÑвиÑного клÑÑа: "CONSTRAINT_INDEX_2 ON PUBLIC.BOOKING(TICKET_ID) VALUES ( /* key:1 */ 2, 1, 1)"
Unique index or primary key violation: "CONSTRAINT_INDEX_2 ON PUBLIC.BOOKING(TICKET_ID) VALUES ( /* key:1 */ 2, 1, 1)"; SQL statement:
insert into booking (ticket_id, user_id, booking_id) values (?, ?, ?) [23505-173]
at org.h2.jdbc.JdbcPreparedStatement.executeBatch(JdbcPreparedStatement.java:1167)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 59 more
3 Réponses :
Jetez un coup d'œil à hibernate flushmode p>
défaut Vous pouvez modifier le mode de rinçage HibernateTeTemplate sur flushmode.always, inefficace et non recommandé (mais fonctionnera comme vous vous attendez maintenant), ou appelez Session.flush () à certains points. P>
voir hiberanaetemplate code>
flushmode code> est
flusmode.auto code>, la synchronisation de la session se produira sur commit ou avant que des requêtes pour empêcher l'état avancé. p>
hiberanatetemplate.setflushMode () code> et
session.flush () code> p> p>
Vous n'obtenez pas les exceptions de DB comme des violations de contraintes avant d'avoir commis la TX et TX s'engage dans le gestionnaire de transactions. La meilleure solution serait la manipulation des exceptions de Gestionnaire TX à l'aide d'un aspect code> de l'après-variateur (AOP). Vous pouvez également appeler vos méthodes @TransActional code> à l'intérieur d'une autre méthode non transactionnelle dans votre service et de saisir les exceptions. Personnellement, je n'aime pas le plus tard, car vous devrez créer une méthode d'emballage pour tous vos services. P>
J'ai pensé à une deuxième approche, mais je n'aime pas aussi. Je vais essayer une approche d'AOP. Merci.
Les exceptions de responsable de l'entité attrapant pourraient être un peu difficiles. Je l'ai fait avant, mais ne vous souvenez pas comment pour le moment.;) Faites-moi savoir si vous avez des problèmes, je peux le trouver pour vous.
L'affranchissement de l'AOP n'est pas appelé à l'exception du TXMGR. Mon contrôleur est également annoté par "@scope (proxymode = scopedproxymode.target_class)" que je devais insérer pour que l'annotation transactionnelle ait un effet. J'ai également essayé avec l'annotation de la commande (la plus haute et la plus basse), à la fois sur le contrôleur et / ou sur ma classe AOP. J'ai trouvé aucun moyen de forcer le Spring AOP pour attraper également des exceptions à partir de la gestion de la TRX.
ou vous pouvez appeler votre code transactionnel en mode transaction explicite.
E.g. p>
Veuillez poster la trace de la pile de l'exception qui est lancée.
Est-ce vraiment important? Le point principal est que je ne peux pas gérer des exceptions que j'ai besoin. Mais j'ai mis à jour mon message avec l'exemple d'exception lorsque l'application essaie d'insérer une valeur qui enfreint une colonne unique.
Essayez d'ajouter un
enfin code> sur le
try-attraper code> dans la méthode de service. Ce qui se produit?
@Sotirios Delimanolis, je vais essayer. Mais ce comportement a l'air assez étrange que pour moi.
@Sotirios Delimanolis code dans le bloc final exécute. Cependant, code dans le bloc de capture - non. On dirait que Hibernate Transaction Manager jette une exception seulement après (à) les méthodes de transaction (et la transaction en cours). Avez-vous des idées comment le faire lancer une exception à l'intérieur de la méthode?
La seule chose à laquelle je puisse penser, c'est que des trucs sont en train de faire paresseusement. Que l'appel à
bookingDao.bookticket code> ne lance pas une exception code> code>. L'exception
code> est lancée dans le
transactionmanager code>, qui se produit dans le proxy qui enveloppe votre classe
@service code>. Si tel est vrai, c'est un design vraiment médiocre de leur part imo.
J'ai eu le même type de problème, j'ai retourné-le aux transactions manuelles, à la session.getTransaction () type de choses à l'intérieur du DAO