当前位置: 代码网 > it编程>编程语言>Javascript > Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

2025年03月19日 Javascript 我要评论
使用 jackson 库进行 json 序列化时遇到了 ‌无限递归(infinite recursion)‌ 问题,这是因为两个实体类 compointquotaentity 和

使用 jackson 库进行 json 序列化时遇到了 ‌无限递归(infinite recursion)‌ 问题,这是因为两个实体类 compointquotaentity 和 compointentity 之间存在双向关联(point 和 pointquota 相互引用),导致序列化时陷入死循环。以下是解决方案:

解决方案‌

1. 使用 @jsonignore 忽略一个方向的引用

在其中一个实体类的关联字段上添加 @jsonignore 注解,直接阻止某一方的序列化:

// compointquotaentity.java
public class compointquotaentity {
    @manytoone
    @joincolumn(name = "point_id")
    private compointentity point;  // 保留此字段的序列化
    // 其他字段...
}
// compointentity.java
public class compointentity {
    @onetomany(mappedby = "point")
    @jsonignore  // 忽略此字段的序列化
    private list<compointquotaentity> pointquota;
    // 其他字段...
}

2. 使用 @jsonmanagedreference 和 @jsonbackreference

通过注解明确父子关系,jackson 会序列化父级(@jsonmanagedreference),但忽略子级(@jsonbackreference):

// compointquotaentity.java
public class compointquotaentity {
    @manytoone
    @joincolumn(name = "point_id")
    @jsonmanagedreference  // 标记为父级(序列化)
    private compointentity point;
    // 其他字段...
}
// compointentity.java
public class compointentity {
    @onetomany(mappedby = "point")
    @jsonbackreference  // 标记为子级(不序列化)
    private list<compointquotaentity> pointquota;
    // 其他字段...
}

3. 使用 dto 替代直接序列化实体

创建 data transfer object (dto),只暴露需要的字段,避免直接序列化 jpa 实体:

// compointquotaentity.java
public class compointquotaentity {
    @manytoone
    @joincolumn(name = "point_id")
    @jsonmanagedreference  // 标记为父级(序列化)
    private compointentity point;
    // 其他字段...
}
// compointentity.java
public class compointentity {
    @onetomany(mappedby = "point")
    @jsonbackreference  // 标记为子级(不序列化)
    private list<compointquotaentity> pointquota;
    // 其他字段...
}

4. 配置 jackson 忽略循环引用

在 application.properties 或 application.yml 中配置 jackson:

# application.properties
spring.jackson.serialization.fail-on-empty-beans=false
spring.jackson.serialization.fail-on-self-references=false

或在代码中配置 objectmapper:

@configuration
public class jacksonconfig {
    @bean
    public objectmapper objectmapper() {
        return new objectmapper()
            .configure(serializationfeature.fail_on_empty_beans, false)
            .configure(serializationfeature.fail_on_self_references, false);
    }
}

5. 自定义序列化器(高级)

为关联字段自定义序列化逻辑,跳过循环引用:

public class compointquotaentity {
    @manytoone
    @joincolumn(name = "point_id")
    @jsonserialize(using = compointentityserializer.class)
    private compointentity point;
    // 其他字段...
}
public class compointentityserializer extends jsonserializer<compointentity> {
    @override
    public void serialize(compointentity value, jsongenerator gen, serializerprovider provider) throws ioexception {
        if (value != null) {
            gen.writestartobject();
            gen.writenumberfield("id", value.getid());
            // 仅序列化需要的字段,跳过 pointquota
            gen.writeendobject();
        }
    }
}

‌ 总结‌

  • 推荐方案 2(@jsonmanagedreference 和 @jsonbackreference)‌:简单且能保持双向关联。
    ‌>- 推荐方案 3(dto)‌:彻底解耦序列化逻辑与数据库实体,适合复杂场景。
  • 避免直接序列化 jpa 实体,尤其是涉及双向关联时。

到此这篇关于jackson库进行json 序列化时遇到了 ‌无限递归(infinite recursion)的问题及解决方案的文章就介绍到这了,更多相关jackson json 序列化无限递归内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com