Невозможно перехватить исключение в контроллере в весенних данных

#spring #spring-mvc #spring-data #spring-roo #spring-data-jpa

#весна #весна-mvc #весна-данные #spring-roo #весна-данные-jpa

Вопрос:

У меня есть приложение Spring MVC с компонентами @Controller, @Service и @Repository (все они сгенерированы из Spring Roo). Я пытаюсь поймать исключение ConstraintViolationException в контроллере, но у меня это не получается. Я пытаюсь обработать все исключения на уровне контроллера, но проблема в том, что когда я делаю вызов репозитория из своей службы, и если возникает исключение, я не получаю поток внутри моего блока catch в контроллере. Я не могу понять, почему это происходит. Настроено ли это Spring? Заранее благодарю.

Контроллер:

     @RequestMapping(method = RequestMethod.POST, headers = "Accept=application/json")
     public ResponseEntity<String> createFromJson(@RequestBody IndividualProviderDto individualProviderDto) {
            HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/json");

    HttpStatus httpStatus = null;

    try {
        individualProviderService.saveIndividualProvider(individualProviderDto);
        httpStatus = HttpStatus.CREATED;

    } catch (ConstraintViolationException e) {
        httpStatus = HttpStatus.CONFLICT;
    }

    return new ResponseEntity<String>(headers, httpStatus);
    }
 

Обслуживание:

  public void saveIndividualProvider(IndividualProviderDto individualProviderDto) {
    IndividualProvider individualProvider = individualProviderDtoToIndividualProviderMapper.map(individualProviderDto);
    individualProviderRepository.save(individualProvider);
}
 

Стек:

 2014-06-24 09:15:36,117 ["http-bio-9001"-exec-6] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Duplicate entry 'xxx@gmail.com' for key 'UK_thwi4ibpanesigdfbx3iqt0bg'
Servlet.service() for servlet [bham] in context with path [/cds] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception
.ConstraintViolationException: could not execute statement; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statemen
t] with root cause
         com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'xxx@gmail.com' for key 'UK_thwi4ibpanesigdfbx3iqt0bg'
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
        at com.mysql.jdbc.Util.getInstance(Util.java:386)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2825)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2156)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2441)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2366)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2350)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187)
        at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
        at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3032)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3558)
        at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:98)
        at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:490)
        at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:195)
        at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:179)
        at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:214)
        at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:324)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
        at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
        at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
        at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:342)
        at com.sun.proxy.$Proxy97.persist(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:262)
        at com.sun.proxy.$Proxy96.persist(Unknown Source)
        at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:369)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:358)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:343)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:105)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
        at com.sun.proxy.$Proxy98.save(Unknown Source)
        at com.mycompany.bham.service.provider.IndividualProviderServiceImpl.saveIndividualProvider(IndividualProviderServiceImpl.java:82)
        at com.mycompany.bham.web.IndividualProviderController.createFromJson(IndividualProviderController.java:88)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
 

Комментарии:

1. Можете ли вы опубликовать свой код? Как выглядит журнал при возникновении исключения?

2. Отредактировал мой вопрос, чтобы включить код и журнал.

3. Мне кажется, что генерируемое исключение — это a org.springframework.orm.jpa.JpaSystemException , я не прав? Вместо этого попробуйте перехватить это исключение.

4. Spring, вероятно, переносит ваше исключение

5. ‘sp00m’ является правильным. Мне пришлось перехватить JpaSystemException. Я смотрел на неправильное исключение — нужно быть более осторожным при просмотре стека. Спасибо вам всем! 🙂

Ответ №1:

Возможно, вы захотите использовать обработчик исключений Spring http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

Вот пример кода:

               @Controller
              public class ExceptionHandlingController {

                // @RequestHandler methods
                ...

                // Exception handling methods

                // Convert a predefined exception to an HTTP Status code
                @ResponseStatus(value=HttpStatus.CONFLICT, reason="Data integrity violation")  // 409
                @ExceptionHandler(DataIntegrityViolationException.class)
                public void conflict() {
                  // Nothing to do
                }

                // Specify the name of a specific view that will be used to display the                   error:
                @ExceptionHandler({SQLException.class,DataAccessException.class})
                public String databaseError() {
                  // Nothing to do.  Returns the logical view name of an error page, passed to
                  // the view-resolver(s) in usual way.
                  // Note that the exception is _not_ available to this view (it is not added to
                  // the model) but see "Extending ExceptionHandlerExceptionResolver" below.
                  return "databaseError";
                }

                // Total control - setup a model and return the view name yourself. Or consider
                // subclassing ExceptionHandlerExceptionResolver (see below).
                @ExceptionHandler(Exception.class)
                public ModelAndView handleError(HttpServletRequest req, Exception exception) {
                  logger.error("Request: "   req.getRequestURL()   " raised "   exception);

                  ModelAndView mav = new ModelAndView();
                  mav.addObject("exception", exception);
                  mav.addObject("url", req.getRequestURL());
                  mav.setViewName("error");
                  return mav;
                }
              }