我有以下课程:
public interface GarageRepository extends PagingAndSortingRepository<Garage, Integer> {}
public class GarageBO {
private GarageRepository garageRepository;
public void updateGarage(Garage garage) {
try {
garageRepository.save(garage);
} catch (Exception e) {
throw BoozinaExceptions.getCodeException(garage, e);
}
}
}
public class GarageFacade implements GarageService {
private GarageBO garageBO;
@Transactional
public void updateGarage(Garage garage) {
garageBO.updateGarage(garage);
}
}
假设我正在尝试更新车库并且抛出了一个独特的违规行为
当我使用@Transactional
注释从GarageFacade调用updateGarage时,garageRepository不会抛出任何异常。
当我在没有@Transactional
注释的情况下调用相同的方法时,garageRepository抛出唯一的违例异常,现在我可以使用BoozinaExceptions.getCodeException(garage, e)
转换异常;
发生这种情况是因为当我有@Transactional
注释时,Spring jpa数据执行提交时将抛出异常。这是在GarageBO.updateGarage执行后发生的吗?
但我需要转换唯一的违规行为。我怎么能这样做? 提交后如何处理spring异常然后转换为我的异常?
答案 0 :(得分:4)
您描述的是预期的行为。在方法结束后提交事务,提交导致唯一约束违规。
将@Transactional
添加到服务方法会使事务在调用提交事务的服务方法之后结束。删除它会在调用存储库方法后进行事务提交。
另外,为什么你有BO一个Facade和一个存储库?!基本上BO和Facade是相同的恕我直言。
要解决您的问题,请GarageRepository
延长JpaRepository
而不是PagingAndSortingRepository
并调用saveAndFlush
方法而不是save
。这将执行sql(不提交事务)并触发约束违例异常。
另一种解决方案是在BO创建和Aspect中执行try / catch,而不是在转换中执行。每次需要时都可以节省编写try / catch的代码。