为了账号安全,请及时绑定邮箱和手机立即绑定

Jackson/Hibernate,meta get 方法和序列化

Jackson/Hibernate,meta get 方法和序列化

哆啦的时光机 2022-09-07 21:16:28
我们有很多具有嵌套关系的休眠实体类。我试图找到将给定实体转换为等效json格式的最佳方法。我知道JsonIgnore,Jackson mixins和JsonFilters,并且一直在尝试这些。我们面临的挑战如下使用 OneToMany/JoinColumn 或类似注释相互关联的对象 - 创建无限递归。实用工具或元方法。杰克逊似乎在通过获取方法而不是通过字段。某些方法是不与任何列关联的“meta”方法。示例 getTotal 方法可以对几个实际字段的值求和,而没有实际的总计字段。其他情况类似,例如getIncomeAccounts,它根据某些标准过滤帐户。我写的 Jackson Filter 有点帮助 - 它根据 Jackson 属性名称检查类字段是否存在。它还会检查是否存在诸如 JoinColumn 批注之类的批注,以避免在字段存在时递归。有没有办法从休眠中获取元数据并在我的过滤器中使用它?基本上,对于给定的实体对象,我有兴趣知道Jackson想要序列化的属性是否会映射到列,并且只有在存在与其关联的列值时才进行序列化。Hibernate 当然知道属性和列映射。Mixins和jsonignore选项是可行的,但是我们依赖于个人开发人员记住将注释放在适当的位置。通常,当我们真的想要获取导出的数据来分析一些问题并在本地创建测试用例时,忘记的注释被发现得太晚了。
查看完整描述

2 回答

?
红颜莎娜

TA贡献1842条经验 获得超13个赞

我通常做的是手动将实体映射到DTO,或者在MapStruct等工具的帮助下。
不幸的是,这将为您提供最大的灵活性,在开始时会有一些开销。
然而,随着时间的推移,你会发现这是值得的。

Jackson、GSON 和其他序列化工具在开箱即用的功能方面显然受到限制,而且这种自定义需要太多的工作,恕我直言,同时也难以理解和维护。

保持简单。


查看完整回答
反对 回复 2022-09-07
?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

如果不想创建新模型以在级别上进行表示,则需要在传递到层之前准备模型。POJOJSONREST APIORMJackson

启用休眠X模块

您应该从启用最适合您的版本的Hibernate模块开始。它解决了许多内部数据类型问题。Hibernatelazy-loadings

双向关系

阅读有关在序列化过程中解决周期问题的选项。主要注释包括:Jackson

定义适当的可见性

您可以在 上定义全局可见性,如何指定 jackson 以仅使用字段 - 最好是全局的,如果需要使用 JsonAutoDetect 注释为给定类自定义它。ObjectMapper

查看模型POJO

可能在大多数情况下,您将能够重用为 创建的模型。如果使用注释自定义输出非常困难,您可以随时在额外的映射/业务层中手动创建自定义类并将模型映射到此类和模型。POJOORMJSONORM

自定义序列化器

如果您需要以一般方式处理某些自定义注释或某些字段,则可以使用BeanSerializerModifierBeanPropertyWriter。它不容易实现,但它非常强大。请参阅此处的示例用法:Jackson 自定义序列化和反序列化

如何为双向关系和可见性配置完成的简单示例:

import com.fasterxml.jackson.annotation.JsonAutoDetect;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;

import com.fasterxml.jackson.annotation.ObjectIdGenerators;

import com.fasterxml.jackson.databind.ObjectMapper;


import java.io.File;

import java.util.Arrays;

import java.util.List;


public class JsonApp {


    public static void main(String[] args) throws Exception {

        File jsonFile = new File("./resource/test.json").getAbsoluteFile();


        Item item0 = new Item();

        item0.setId(1);

        item0.setItemName("Item 0");


        Item item1 = new Item();

        item1.setId(2);

        item1.setItemName("Item 1");


        List<Item> items = Arrays.asList(item0, item1);

        User user = new User();

        user.setId(123);

        user.setName("Rick");

        user.setUserItems(items);

        items.forEach(item -> item.setOwner(user));


        ObjectMapper mapper = new ObjectMapper();

        mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()

                .withFieldVisibility(JsonAutoDetect.Visibility.ANY)

                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)

                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)

                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));


        System.out.println(mapper.writeValueAsString(user));

    }

}


@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")

class User {


    private int id;

    private String name;

    private List<Item> userItems;


    // getters, setters

}


@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")

class Item {


    private int id;

    private String itemName;

    private User owner;


    // getters, setters

}

以上代码打印:


{"id":123,"name":"Rick","userItems":[{"id":1,"itemName":"Item 0","owner":123},{"id":2,"itemName":"Item 1","owner":123}]}


查看完整回答
反对 回复 2022-09-07
  • 2 回答
  • 0 关注
  • 160 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号