构建ResponseEntity应该放在Controller层面

自从从一个Service注入多个Repo变更至一个Service对应一个Repo后,Service之间会产生注入关系。此时如果再讲ResponseEntity构建放在Service层面,可能会导致Service层的方法输出类型混乱:ResponseEntity及其他类型混杂。
同时,如果使用ResponseEntity作为Serivce方法的返回值,在Serivce之间调用会存在不方便。
故我认为Service应该统一返回DTO或PO,剩下的事情交由Controller或者调用方Service/Compnent进行处理。

在枚举类中进行依赖注入比较困难

自从看了 答应我,别再if/else走天下了可以吗 后就对其中的枚举类解耦情有独钟,结果发现用在实际业务中是有所限制的。
固然上面文章中的枚举类的解耦方案代码高度聚合,可读性非常强,但是由于枚举类的特殊限制(静态构造器?没有去深究,迟点补课),Spring很难向其中注入属性。所以枚举解耦的方案适合在不需要依赖注入的时候进行解耦。
推荐是使用工厂模式或者其他方法进行解决。

git commit的良好习惯

最近不知道在哪个论坛上看到的一篇文章,是在讨论大家开发中常用的git命令,其中有一层在讨论说是不是大家平时在git commit 之前都会 git add -A。
有一名网友回复到会先进行git diff查看提交的内容,保证只提交一个逻辑
我觉得这是一个很好的习惯,并且以后打算遵循这个原则。

注意处理嵌套事务回滚

最近在做毕设的时候遇到了嵌套事务回滚异常的情况。
解释在这里:UnexpectedRollbackException解决方案
简单地说就是内层的方法也开启了事务管理,同时采用的默认事务传播方式(加入当前已存在的事务),内层抛出异常时由Spring的全局事务管理设置了事务回滚,并且将异常向上层传递。
关键在于,由于外层也没有try-catch语句捕获异常,继续将异常向上层传递,此时Spring的全局事务管理再次捕获到了这个异常并尝试再一次设置事务回滚,从而抛出异常。

    ...
        authDetailPO.setType(authType.toString());
        authDetailPO.setComment(createAuthDTO.getComment());
        authDetailPO.setStatus(AuthStatus.STATUS_NORMAL.toString());
        authDetailRepo.save(authDetailPO);

        // 此处调用会抛出异常
        long defaultValueId = authValueService.createValues(authDetailPO.getId(), createAuthDTO.getValues(), authType);
        authDetailPO.setDefaultValueId(defaultValueId);
        authDetailRepo.save(authDetailPO);
    ...

我个人认为比较好的解决方法是在外层写一个try-catch语句,不要将内层的异常直接抛出去,在catch中设置回滚后再抛,即可消除这个问题。

    ...
        authDetailPO.setType(authType.toString());
        authDetailPO.setComment(createAuthDTO.getComment());
        authDetailPO.setStatus(AuthStatus.STATUS_NORMAL.toString());
        authDetailRepo.save(authDetailPO);

        long defaultValueId;
        try {
            defaultValueId = authValueService.createValues(authDetailPO.getId(), createAuthDTO.getValues(), authType);
        } catch (Exception e) {
            // 手动设置回滚事务,报错消除
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw e;
        }
        authDetailPO.setDefaultValueId(defaultValueId);
        authDetailRepo.save(authDetailPO);
    ...