最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JSON.toJSONString使用異常分析

 更新時間:2023年09月11日 15:36:29   作者:土豆肉絲蓋澆飯  
這篇文章主要為大家介紹了JSON.toJSONString使用異常分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

先說說坑

JSON.toString在序列化對象時,默認通過的是get*()方法來查找屬性,而不是具體某個屬性,同時回忽略transient注解的屬性。

測試案例如下

public class FastJsonTest {
    public static void main(String[] args) {
        Person person = new Person();
        person.setBirth(new Date());
        System.out.println(JSON.toJSONString(person));
    }
    public static class Person{
        private Integer age =123;
        private transient Date birth;
        public Date getBirth() {
            return birth;
        }
        public void setBirth(Date birth) {
            this.birth = birth;
        }
        public String getName(){
            return "scj";
        }
    }
}

輸出

{"name":"scj"}

問題發(fā)生

最近在迭代一個老項目,升級中間件框架版本(不升級不給打包部署)后,在項目啟動的時候居然拋出以下異常

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.masaike.yama.platform.domain.model.product.ProductServiceEntity.properties, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:582)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:201)
    at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:145)
    at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261)
    at com.masaike.yama.platform.infrastructure.converter.ProductServiceConverterImpl.productServicePropertyVOListToProductServicePropertyDTOList(ProductServiceConverterImpl.java:139)
    at com.masaike.yama.platform.infrastructure.converter.ProductServiceConverterImpl.map(ProductServiceConverterImpl.java:50)
    at com.masaike.yama.platform.infrastructure.converter.ProductServiceConverterImpl.entityListToDTOList(ProductServiceConverterImpl.java:32)
    at com.masaike.yama.platform.query.ProductServiceQueryServiceImpl.getAllProductService(ProductServiceQueryServiceImpl.java:43)
    at com.alibaba.fastjson.serializer.ASMSerializer_12_ProductServiceQueryServiceImpl.write(Unknown Source)
    at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:333)
    at com.alibaba.fastjson.serializer.ASMSerializer_1_InterfaceInfo.write(Unknown Source)
    at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:285)
    at com.alibaba.fastjson.JSON.toJSONString(JSON.java:745)
    at com.alibaba.fastjson.JSON.toJSONString(JSON.java:683)
    at com.alibaba.fastjson.JSON.toJSONString(JSON.java:648)
    at com.alibaba.dubbo.config.masaikehttp.ExportedInterfaceManager.addInterface(ExportedInterfaceManager.java:104)//關鍵點
    at com.alibaba.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:321)
    at com.alibaba.dubbo.config.ServiceConfig.export(ServiceConfig.java:218)
    at com.alibaba.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:123)
    at com.alibaba.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:49)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:400)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:354)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:886)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:161)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230)
    at com.masaike.yama.bootstrap.BootStrapApplication.main(BootStrapApplication.java:36)

這個一個使用JPA時常見問題:延遲加載的時候session不存在

關于延遲加載no-session問題,可以看如何解決JPA延遲加載no Session報錯

從日志定位到拋出異常的方法為

@Override
@Transactional(rollbackFor = Exception.class)
public List<XXDTO> getAllXX() {
    List<XXEntity> result = xXQueryRepository.findAll();
    //下面的converter會觸發(fā)延遲加載
    return XXConverter.INSTANCE.entityListToDTOList(result);
}

這邊存在兩個迷惑性行為

  • 啟動的時候怎么調(diào)用了getAllXX方法
  • getAllXX我加了@Transactional,理論上是有session的

問題排查

精簡上面的異常棧

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.masaike.yama.platform.domain.model.product.ProductServiceEntity.properties, could not initialize proxy - no Session
    at com.masaike.yama.platform.infrastructure.converter.ProductServiceConverterImpl.productServicePropertyVOListToProductServicePropertyDTOList(ProductServiceConverterImpl.java:139)
    at com.masaike.yama.platform.infrastructure.converter.ProductServiceConverterImpl.map(ProductServiceConverterImpl.java:50)
    at com.masaike.yama.platform.infrastructure.converter.ProductServiceConverterImpl.entityListToDTOList(ProductServiceConverterImpl.java:32)
    at com.masaike.yama.platform.query.ProductServiceQueryServiceImpl.getAllProductService(ProductServiceQueryServiceImpl.java:43)
    at com.alibaba.fastjson.JSON.toJSONString(JSON.java:648)
    at com.alibaba.dubbo.config.masaikehttp.ExportedInterfaceManager.addInterface(ExportedInterfaceManager.java:104)//關鍵點
    at com.alibaba.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:321)
    at com.alibaba.dubbo.config.ServiceConfig.export(ServiceConfig.java:218)

可以復盤出問題發(fā)生的現(xiàn)場

dubbo服務進行export的時候調(diào)用了ExportedInterfaceManager.addInterface方法,而在addInterface方法中調(diào)用的JSON.toJSONString方法觸發(fā)了ProductServiceQueryServiceImpl.getAllProductService方法

在看了ExportedInterfaceManager.addInterface源碼之后,問題的起因浮出水面

ExportedInterfaceManager這個類是用來針對接口暴露http服務時收集元數(shù)據(jù)使用

public synchronized void addInterface(Class<?> interfaceCls, Object obj) {
    //如果是代理類獲取代理類對象
    obj = getObjectTarget(obj);//獲取原始對象
    //...
    InterfaceInfo interfaceInfo = new InterfaceInfo();
    interfaceInfo.setInterfaceName(interfaceName);
    interfaceInfo.setRef(obj);//致命之處
    //...
    logger.info(String.format("start to addInterface into interfaceMap,interfaceName[%s],interfaceInfo[%s]",interfaceName, JSON.toJSONString(interfaceInfo)));//致命之處
    // add interface info to map
    interfaceMap.put(interfaceName, interfaceInfo);
}

對于第一個問題,InterfaceInfo的ref指向ProductServiceQueryServiceImpl,在打印日志的時候,JSON.toJSONString觸發(fā)了ProductServiceQueryServiceImpl中的get方法

而對于第二個問題,obj = getObjectTarget(obj);這段代碼會獲取代理的原始對象,導致事務失效。

問題危害

拋開獲取原始對象這個邏輯不說,這個bug的致命之處在于,他會調(diào)用所暴露dubbo接口中所有get*()格式的方法

問題解決

解決方式很簡單,有以下兩種

  • 不要序列化ref(加fastjson注解或字段加transient)
  • 去掉打印日志邏輯

在反饋這個問題后,中間件團隊的改動如下

以上就是JSON.toJSONString使用異常分析的詳細內(nèi)容,更多關于JSON.toJSONString異常的資料請關注腳本之家其它相關文章!

相關文章

  • Java中監(jiān)聽器Listener詳解

    Java中監(jiān)聽器Listener詳解

    Listener是由Java編寫的WEB組件,主要完成對內(nèi)置對象狀態(tài)的變化 (創(chuàng)建、銷毀)和屬性的變化進行監(jiān)聽,做進一步的處理,主要對session和application內(nèi)置對象監(jiān)聽,這篇文章主要介紹了Java中監(jiān)聽器Listener,需要的朋友可以參考下
    2023-08-08
  • java如何執(zhí)行l(wèi)inux/cmd命令

    java如何執(zhí)行l(wèi)inux/cmd命令

    本文詳細介紹了在Java中執(zhí)行命令行命令的兩種方法:Runtime.exec()和ProcessBuilder,包括它們的優(yōu)缺點、參數(shù)傳遞、流處理、多線程處理、超時控制、跨平臺兼容性和亂碼問題的解決方案
    2026-01-01
  • Java 四種基本加密算法分析

    Java 四種基本加密算法分析

    這篇文章主要介紹了Java 四種基本加密算法分析的相關資料,需要的朋友可以參考下
    2017-02-02
  • Java多線程教程之如何利用Future實現(xiàn)攜帶結果的任務

    Java多線程教程之如何利用Future實現(xiàn)攜帶結果的任務

    Callable與Future兩功能是Java?5版本中加入的,這篇文章主要給大家介紹了關于Java多線程教程之如何利用Future實現(xiàn)攜帶結果任務的相關資料,需要的朋友可以參考下
    2021-12-12
  • Java實現(xiàn)布隆過濾器的幾種方式總結

    Java實現(xiàn)布隆過濾器的幾種方式總結

    這篇文章給大家總結了幾種Java實現(xiàn)布隆過濾器的方式,手動硬編碼實現(xiàn),引入Guava實現(xiàn),引入hutool實現(xiàn),通過redis實現(xiàn)等幾種方式,文中有詳細的代碼和圖解,需要的朋友可以參考下
    2023-07-07
  • Java?基于Hutool實現(xiàn)DES加解密示例詳解

    Java?基于Hutool實現(xiàn)DES加解密示例詳解

    這篇文章主要介紹了Java基于Hutool實現(xiàn)DES加解密,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • mybatis之增刪改查

    mybatis之增刪改查

    本篇文章主要介紹了Mybatis實現(xiàn)數(shù)據(jù)的增刪改查實例(CRUD),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-07-07
  • java實現(xiàn)文件上傳的詳細步驟

    java實現(xiàn)文件上傳的詳細步驟

    文件上傳是用戶將本地文件通過Web頁面提交到服務器的過程,涉及客戶端、服務器端、上傳表單等組件,在SpringBoot中,通過MultipartFile接口處理上傳文件,并將其保存在服務器,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-10-10
  • elasticsearch 8.2.3 安裝及springboot簡單使用

    elasticsearch 8.2.3 安裝及springboot簡單使用

    這篇文章主要介紹了elasticsearch 8.2.3 安裝及springboot簡單使用,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • SpringBoot整合GRPC微服務遠程通信的實現(xiàn)示例

    SpringBoot整合GRPC微服務遠程通信的實現(xiàn)示例

    本文主要介紹了SpringBoot整合GRPC微服務遠程通信的實現(xiàn)示例,包含gRPC的工作原理,以及如何在Spring Boot應用中集成gRPC,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02

最新評論

于都县| 红桥区| 清远市| 遂川县| 青铜峡市| 双牌县| 连城县| 海口市| 浦县| 定安县| 南昌县| 辛集市| 冷水江市| 新乡县| 霍林郭勒市| 武强县| 桂平市| 建德市| 云南省| 建湖县| 邻水| 霞浦县| 布拖县| 林州市| 灵武市| 溆浦县| 津南区| 商河县| 尼玛县| 桃园县| 揭东县| 肃宁县| 宁波市| 广昌县| 临朐县| 阳新县| 株洲县| 双桥区| 曲靖市| 盐边县| 布拖县|