jackson双向关系(一对多)不起作用

slwdgvem  于 2021-06-26  发布在  Java
关注(0)|答案(3)|浏览(405)

我在这个web服务项目中使用spring(xml+annotations)、hibernate(annotations)。数据库关系图、模型、预期和实际输出如下:,
数据库表关系
客户.java

@Entity
@Table(name="customer")
public class Customer implements Serializable{
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="customer_id", unique=true, nullable =false)
    long customerId;
    @Column(name="name")
    String name;
    @Column(name="secondary_name")
    String secondaryName;
    @Column(name="date")
    Date date;
    @Column(name="address")
    String address;
    @Column(name="post")
    String post;
    @Column(name="pin")
    String pin;
    @Column(name="phone")
    String phone;
    @OneToMany(fetch=FetchType.LAZY, mappedBy="customer", cascade=CascadeType.ALL)
    @JsonManagedReference
    Set<Loan> loans = new HashSet<Loan>();
    //constructors, getters and setters
}

贷款.java

public class Loan implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="loan_id", nullable=false, unique=true)
    long loanId;
    @ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinColumn(name="customer_id", nullable = false)
    @JsonBackReference
    Customer customer;
    @Column(name="date", nullable=false)
    Date date;
    @Column(name="amount", nullable=false)
    double amount;
    @OneToMany(fetch=FetchType.LAZY, mappedBy="loan", cascade=CascadeType.ALL)
    @JsonManagedReference
    List<Item> items = new ArrayList<Item>();
    //constructors, getters, setters
}

项目.java

public class Item implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="item_id", nullable=false, unique=true)
    long itemId;
    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinColumn(name="loan_id", nullable = false)
    @JsonBackReference
    Loan loan;
    @Column(name="name", nullable=false)
    String name;
    @Column(name="weight", nullable=false)
    double weight;
    //constructors, setters, getters
}

实际output:here,不显示客户详细信息

{  
   "loanId":4,
   "date":1484937000000,
   "amount":10000.0,
   "items":[  
      {  
         "itemId":3,
         "name":"Item1",
         "weight":10.0
      },
      {  
         "itemId":4,
         "name":"Item2",
         "weight":20.0
      }
   ]
}

预期输出:在寻找贷款时也需要显示客户详细信息

{  
   "loanId":4,
   "customer":{  
      "customerId":2,
      "name":"Prem",
      "address":"Street,State"
   },
   "date":1484937000000,
   "amount":10000.0,
   "items":[  
      {  
         "itemId":3,
         "name":"Item1",
         "weight":10.0
      },
      {  
         "itemId":4,
         "name":"Item2",
         "weight":20.0
      }
   ]
}

我可以从数据库中获取客户的详细信息,但无法使用jacksonjson加载。如果我删除@jsonmanagedreference,我将以循环结束。如果我删除@jsonbackreference,则输出中没有任何效果。完成代码:https://github.com/liwevire/tm_service 提前谢谢。

lsmepo6l

lsmepo6l1#

这看起来很古老,但让我把我的硬币也放在这里;我会把实体和模型分开。手段;

> Client <-> Application : Models
> 
> Application <-> Database : Entities

您的服务层或处理数据的任何层都应该在实体和模型之间进行转换。
您可以通过按自己的意愿返回数据来摆脱递归。
您将定义分为两个不同的通信通道。这样你就可以决定向你的客户展示什么以及如何展示你的客户。这将保存直接公开的db模式。
您可以根据自己的意愿扩展模型,而无需接触数据库后端。

ni65a41a

ni65a41a2#

因为你用的是 @JsonBackReferenceCustomer 中的属性 Loan 实体 Customer 对象将不包括在序列化中。使用 @JsonManagedReference 对于 CustomerLoan 对象和用途 @JsonBackReferenceLoan 中的属性 Customer 实体。
这将序列化 Customer 你的财产 Loan 实体。但是 Customer 对象序列化将不包含 Loan 财产。您需要选择要序列化的关系的一侧。
若要允许两侧,请使用 @JsonIdentityInfo 并删除 @JsonBackReference 以及 @JsonManagedReference . 你会是这样的:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "customerId")
public class Customer implements Serializable {
    ...
}

这个 property@JsonIdentityInfo 有关详细信息,请参阅实体id属性 Customer 这将是 customerId . 做这个是为了 Loan 以及 Item 也。

de90aj5v

de90aj5v3#

这是一个有点冗长的方法。但你的应用程序需要一些设计修改。我有一个类似的问题,我为每个实体类创建了单独的pojo。
在服务层中,我使用这些pojo而不是实体对象作为参数,并使用适当的getter/setter来设置/获取实体类的属性。通过这种方式,您可以获得/设置想要的属性,并避免不需要的属性。然而,我在dao层实现了额外的方法来获取相关的实体。这是一个很长的方法,但解决了我的问题。

相关问题