如何从事务性Spring服务中抛出自定义异常? [英] How to throw custom exception from transactional Spring service?

查看:122
本文介绍了如何从事务性Spring服务中抛出自定义异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个春季服务:

@Service
@Transactional
public class ConsorcioServiceImpl implements ConsorcioService {

    ...

    @Autowired
    private ConsorcioRepository consorcioRepository;

    @Override
    public void saveBank(Consorcio consorcio) throws BusinessException {

        try {
            consorcioRepository.save(consorcio);
        }
        catch(DataIntegrityViolationException divex) {
            if(divex.getMessage().contains("uq_codigo")) {
                throw new DuplicatedCodeException(divex);
            }
            else {
                throw new BusinessException(dives); 
            }
        }
        catch (Exception e) {
            throw new BusinessException(e);
        }
    }


}

该服务使用此Spring数据存储库:

That service uses this Spring Data repository:

@Repository
public interface ConsorcioRepository extendsCrudRepository<Consorcio, Integer> {


}

我正在从Spring控制器调用服务:

I'm calling the service from a spring controller:

@Controller
@RequestMapping(value = "/bank")
public class BancaController {

    @Autowired
    private ConsorcioService consorcioService;

    @RequestMapping(value="create", method=RequestMethod.POST)
    public ModelAndView crearBanca(@Valid BancaViewModel bancaViewModel, BindingResult bindingResult,
                                   RedirectAttributes redirectAttributes) {
        ModelAndView modelAndView;

        MessageViewModel result;
        try {

            consorcioService.saveBank(bancaViewModel.buildBanca());
            result = new MessageViewModel(MessageType.SUCESS);
            redirectAttributes.addFlashAttribute("messageViewModel", result);
            modelAndView = new ModelAndView("redirect:/banca/crear");
            return modelAndView;
        } catch (Exception e) {
            result = new MessageViewModel(MessageType.ERROR);
            modelAndView = new ModelAndView("crear-bancas");
            modelAndView.addObject("messageViewModel", result);
            return modelAndView;
        }
}

但是我在控制器中遇到的异常是:org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly 而不是DuplicatedCodeException我投入了服务.我需要确定异常的类型,以便提供自定义友好的用户消息.

But the exception I get in the controller is: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly instead of the DuplicatedCodeException I throw in the service. I need to identify the type of exception so I can give a custom friendly user message.

推荐答案

您的DuplicatedCodeException,BusinessException应该是运行时异常,或为方法saveBank添加:

also your DuplicatedCodeException , BusinessException should be runtime exception , or add for method saveBank :

@Transactinal(rolbackFor = {BusinessException.class,DuplicatedCodeException.,class})

@Transactinal(rolbackFor={BusinessException.class,DuplicatedCodeException.,class })

在其他情况下,spring不会回滚事务.

in other case spring will not rollback transaction.

Spring文档中的

from Spring documentation:

虽然EJB的默认行为是让EJB容器执行以下操作: 自动在系统异常时回滚事务(通常 运行时异常),EJB CMT不会回滚事务 自动针对应用程序异常(即,已检查 java.rmi.RemoteException以外的其他异常).春天的时候 声明式事务管理的默认行为遵循EJB 约定(仅在未检查的异常时自动回滚),它 自定义它通常很有用.

While the EJB default behavior is for the EJB container to automatically roll back the transaction on a system exception (usually a runtime exception), EJB CMT does not roll back the transaction automatically on an application exception (that is, a checked exception other than java.rmi.RemoteException). While the Spring default behavior for declarative transaction management follows EJB convention (roll back is automatic only on unchecked exceptions), it is often useful to customize this.

这篇关于如何从事务性Spring服务中抛出自定义异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆