@Transactional对于默认(package-private)级别的方法,会导致注入为null

2023-12-14 09:33:39

最近项目从springboot1.x升级到2.3.x时,发现调用方法时注入的dao类为空。经过长时间排查发现是@Transactional引起。以前一直的思路是只要@Transactional注释的方法为public就可以正常注入,但发现如果是同包下package-private级别的方法调用,也会导致注入为空。

下面代码是UserService中调用了menuService.listMenus()方法

UserService

public List<ProductDto> genProductDtoList(String roleTypeCode) {
        List<ProductEntity> productList = productService.listAllProducts();
        
        List<MenuDto> menuDtoList = menuService.listMenus(productCodeList, roleTypeCode);
       // 非关键代码省略....
     return ...
}

MenuService:

 List<MenuDto> listMenus(List<String> productCodeList, String roleTypeCode) {
        List<MenuEntity> leafMenus = menuDao.listMenus(productCodeList, roleTypeCode);
        if (leafMenus.isEmpty()) {
            return Lists.newArrayList();
        }
        Set<String> parentMenuCodes = leafMenus.stream().map(MenuEntity::getParentCode).collect(Collectors.toSet());
        List<MenuEntity> parentMenu = menuDao.listMenus(parentMenuCodes);
        List<MenuEntity> menus = Collections.concat(leafMenus, parentMenu);
        return menus.stream().map(MenuDto::new).collect(Collectors.toList());
    }

@Transactional(rollbackFor = Exception.class)
public void saveRelationsOfMenuAndRoleType(String typeCode, List<String> menuCodes) {
        menuDao.deleteRelationsByRoleType(typeCode);

        List<MenuEntity> menus = menuDao.listLeafMenus(menuCodes);
        if (menus.isEmpty() && !Objects.equals(typeCode,VISITOR)) {
            LOGGER.info("至少选择一个菜单!参数:{}", menuCodes);
            throw new DataException("至少选择一个菜单!");
        }
        // 省略代码 --------
    }

在MenuService中有其他的方法使用了@Transactional进行事务管理,会导致listMenus中的menuDao注入为null.原因就是listMenus方法未定义访问权限,默认是package-private。当把该方法改成public时,则能正常注入:

public List<MenuDto> listMenus(List<String> productCodeList, String roleTypeCode) {
        List<MenuEntity> leafMenus = menuDao.listMenus(productCodeList, roleTypeCode);
        if (leafMenus.isEmpty()) {
            return Lists.newArrayList();
        }
        Set<String> parentMenuCodes = leafMenus.stream().map(MenuEntity::getParentCode).collect(Collectors.toSet());
        List<MenuEntity> parentMenu = menuDao.listMenus(parentMenuCodes);
        List<MenuEntity> menus = Collections.concat(leafMenus, parentMenu);
        return menus.stream().map(MenuDto::new).collect(Collectors.toList());
    }

具体的源码后续分析,先用该方法解决业务报错问题处理。

文章来源:https://blog.csdn.net/u010786902/article/details/134907600
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。