【问题标题】:How to handle @JsonManagedReference and @JsonBackReference for three connected tables如何处理三个连接表的@JsonManagedReference 和@JsonBackReference
【发布时间】:2021-12-20 14:51:39
【问题描述】:

我被困在给定的场景中:
共有三个实体
a) 账单(与供应商的多对一关系)[双向] b) 供应商(与供应商和供应商银行的一对多关系)
c) VendorBank(与供应商的多对一关系)[单向]

账单:显示有限的字段

@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@Table(name="bill_details") 
public class Bills {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="bill_id")
    private int bill_id;
    
    @Column(name="bill_no")
    private String billno;
    
    @ManyToOne(cascade = {CascadeType.MERGE})
    @JoinColumn(name="b_vendor_id")
    private Vendors vendors;
    
        /* Args contructor code here */
             
    @JsonManagedReference
     public Vendors getVendors() { return vendors; }

VendorBank:显示有限的字段

public class VendorBank {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="v_bank_id")
    private int vendorBankId;
    
    @Column(name="v_acc_no")
    private String accountNumber;
    
    @Column(name="v_vendor_id")
    private int vendor_id;
    
    /*Both constructor code here*/
    }

供应商类别:仅显示 imp 字段

/*Lombok code here*/    
     public class Vendors {
    
        @Id 
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="vendor_id")
        private int vendor_id;
        
        @Column(name="vendor_name")
        private String vendor_name;
    
        @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
        @JoinColumn(name="v_vendor_id")
        private List<VendorBank> vendorBank;
            
        @OneToMany(mappedBy = "vendors",cascade = {CascadeType.DETACH,CascadeType.MERGE,
                            CascadeType.PERSIST,CascadeType.REFRESH})
        private List<Bills> bills;
    
         @JsonBackReference 
        public List<Bills> getBills() {
            return bills;
        }
        //@JsonManagedReference()
        // @JsonIgnore
            public List<VendorBank> getVendorBank() {
                return vendorBank;
        }

输出:

{
            "bill_id": 102,
            "billno": "B-858",
            "vendors": {
                "vendor_id": 3,
                "vendor_name": "ABC Company",
                 "vendorBank": [
                    {
                        "vendorBankId": 14,
                        "accountNumber": "502998745002",
                        "vendor_id": 3
                    }
                ]
         }
        }

1.当我调用供应商端点时,我会根据需要从供应商 + 供应商银行获取数据。
2.但是当我调用 Bill 端点时,我会从 Bill + vendor + vendorbank 中获取数据,如上所述。 我不希望供应商银行来。[如果我在 vendorbank 上使用 JsonIgnore,那么我会得到正确的输出,但是上面的第 1 点出错了]

【问题讨论】:

    标签: java json spring-boot hibernate spring-mvc


    【解决方案1】:

    好的,所以你想要实现的是在一个上下文中包含来自实体的一些数据,而不是在另一个上下文中包含它。

    我不认为你可以通过在实体上使用纯粹的注释来做到这一点,因为它们没有调用上下文。

    那么,我们可以在这里做什么?

    我们可以使用Jackson Mixins。例如:

    class YourClass {
      public int ignoreThis() { return 0; }    
    }
    

    有了这个 Mixin

    abstract class MixIn {
      @JsonIgnore abstract int ignoreThis(); // we don't need it!  
    }
    

    有了这个:

    objectMapper.getSerializationConfig().addMixInAnnotations(YourClass.class, MixIn.class)
    

    然后您可以使用它在您的控制器中将对象序列化为json(您将其发送到服务),然后将其添加为响应正文并发送给用户。

    如果你能以某种方式配置ObjectMapper,那将是理想的,Spring 在后台使用它来执行此操作,但是,这是不可能的(至少很容易),因为你需要绑定这个 objectMapper仅适用于您的特定控制器,而不是所有控制器。

    【讨论】:

    • 感谢您的回复。由于我是开发新手,所以您的解决方案看起来很困难。但我会试一试,让你知道是否适合我。
    猜你喜欢
    • 1970-01-01
    • 2015-09-27
    • 2016-09-20
    • 2018-05-23
    • 2020-04-23
    • 2016-11-07
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多