Spring boot SpringBoot正在抛出一个JpaSystemException而不是ClientException

Spring boot SpringBoot正在抛出一个JpaSystemException而不是ClientException,spring-boot,exception,spring-data-jpa,Spring Boot,Exception,Spring Data Jpa,当方法handleException()抛出ClientException时,为什么SpringBoot抛出JpaSystemException而不是ClientException @RestController @RequestMapping(path = "/api/clients") public class ClientController { private Logger logger = LoggerFactory.getLogger(getClass()); @

当方法
handleException()
抛出
ClientException
时,为什么SpringBoot抛出
JpaSystemException
而不是
ClientException

@RestController
@RequestMapping(path = "/api/clients")
public class ClientController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private MessageByLocaleService messageByLocaleService;

    @Autowired
    private PersonService personService;

    @PostMapping(path = "/saveperson", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Void> savePerson(@RequestBody @Valid Person person) throws Exception {
        try {
            this.personService.save(person);
        }catch(ClientException ce){
            logger.info(ce.getMessage());
        }catch(JpaSystemException jse){
            logger.info(jse.getMessage());  // <<<<< is catching this exception instead ClientException
        }catch (Exception e){
            logger.info(e.getMessage());
        }
        return new ResponseEntity<Void>(HttpStatus.CREATED);
    }
}

@Service
@Transactional
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonRepository personRepository;

    @Autowired
    private MessageByLocaleService messageByLocaleService;

    @Override
    public Person save(Person client) throws ClientException {
        try {
            return this.personRepository.save(client); //trying to save the client throw a MySQLIntegrityConstraintViolationException: Duplicate entry..
        } catch (DataIntegrityViolationException dive) {
            Throwable th = dive.getCause();
            if (th != null && th instanceof ConstraintViolationException) {

                ConstraintViolationException violationException = (ConstraintViolationException) th;
                violationException.printStackTrace();

                handleException(dive, violationException); 

            }
        }
        return null;
    }

    private void handleException(DataIntegrityViolationException dive, ConstraintViolationException violationException) throws ClientException {
        try {
            String ukName = violationException.getConstraintName();
            String ukMessage = messageByLocaleService.getMessage(ukName);

            if (ukMessage != null) {
                ClientException ce = new ClientException(dive.getMostSpecificCause().getMessage(), ukMessage);
                throw ce; 
            }

        } catch (NoSuchMessageException ex) {
            throw new ClientException(violationException.getCause().getMessage(), "UnknownError : " + violationException.getCause().getMessage());
        }
    }   
}
@RestController
@请求映射(path=“/api/clients”)
公共类客户端控制器{
私有记录器Logger=LoggerFactory.getLogger(getClass());
@自动连线
私有消息ByLocaleService消息ByLocaleService;
@自动连线
私人私人服务;
@PostMapping(path=“/saveperson”,consumes=MediaType.APPLICATION\u JSON\u VALUE,products=MediaType.APPLICATION\u JSON\u VALUE)
public ResponseEntity savePerson(@RequestBody@Valid Person)引发异常{
试一试{
这个。personService。save(个人);
}捕获(客户例外ce){
logger.info(ce.getMessage());
}捕获(JpaSystemException jse){

logger.info(jse.getMessage());//
handleException()
仅为
DataIntegrityViolationException
-
JpaSystemException
调用,我想我不明白
接收DataIntegrityViolationException和ConstraintViolationException作为参数。您看到我给出的链接了吗?捕获特定异常时,您只能处理该异常及其子异常(它扩展了该异常).
JpaSystemException
不是
DataIntegrityViolationException
的子项,您正在
捕获它。@vasan当然这是我的困难,但我仍然无法理解其观点。我只是将服务更改为
@Transactional(rollboor=Exception.class)
现在可以正确地捕捉到客户异常。这有意义吗?