如何解决添加JPA关联后出现的com.fasterxml.jackson.databind.ser错误
JPA实体关联引发Jackson Databind序列化错误
问题背景
配置JPA实体间的ManyToOne和OneToMany关联后,出现Jackson Databind序列化错误,怀疑是关联配置导致的问题。Product实体对应Northwind数据库的产品表,关联了Category和Supplier表。
错误信息
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.13.4.2.jar:2.13.4.2] at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.4.2.jar:2.13.4.2] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.4.2.jar:2.13.4.2] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.4.2.jar:2.13.4.2] at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.4.2.jar:2.13.4.2] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.4.2.jar:2.13.4.2] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
关联后的实体代码
Product实体
package com.JpaTraining.JpaTraining.entities.concretes; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import lombok.Data; @Entity @Data @Table(name = "products") public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "product_id") private int productId; @Column(name = "product_name") private String productName; @ManyToOne @JoinColumn(name = "supplier_id") private Supplier supplier; @ManyToOne @JoinColumn(name = "category_id") private Category category; @Column(name = "unit_price") private double unitPrice; @Column(name = "units_in_stock") private int unitsInStock; public Product() { } public Product(int productId, String productName, Supplier supplier, Category category, double unitPrice, int unitsInStock) { this.productId = productId; this.productName = productName; this.supplier = supplier; this.category = category; this.unitPrice = unitPrice; this.unitsInStock = unitsInStock; } }
Category实体
package com.JpaTraining.JpaTraining.entities.concretes; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import lombok.Data; @Entity @Data @Table(name = "categories") public class Category { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "category_id") private int categoryId; @Column(name = "category_name") private String categoryName; @OneToMany(mappedBy = "category") private List<Product> product; public Category() { } public Category(int categoryId, String categoryName, List<Product> product) { this.categoryId = categoryId; this.categoryName = categoryName; this.product = product; } }
Supplier实体
package com.JpaTraining.JpaTraining.entities.concretes; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import lombok.Data; @Entity @Data @Table(name = "suppliers") public class Supplier { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "supplier_id") private int supplierId; @Column(name = "company_name") private String supplierName; @OneToMany(mappedBy = "supplier") private List<Product> product; public Supplier() { } public Supplier(int supplierId, String supplierName, List<Product> product) { this.supplierId = supplierId; this.supplierName = supplierName; this.product = product; } }
数据库字符集配置



解决方案
这个错误的核心原因是实体间的双向关联导致Jackson序列化时出现循环引用:Product引用了Category/Supplier,而Category/Supplier又反过来引用了Product列表,序列化时会无限递归调用,最终抛出异常。
解决方法(按需选择):
- 添加@JsonIgnore注解:在双向关联的一方忽略序列化,比如在Category和Supplier的
product字段上添加:
@OneToMany(mappedBy = "category") @JsonIgnore private List<Product> product;
- 使用@JsonManagedReference和@JsonBackReference:区分双向关联的主动/被动方,避免循环:
- 在Product的
supplier和category字段上添加@JsonManagedReference - 在Category和Supplier的
product字段上添加@JsonBackReference
- 使用DTO传输数据:创建专门的DTO类,只包含需要返回的字段,序列化时转换为DTO而非直接序列化实体类,彻底隔离实体关联与前端数据结构。
另外,建议将实体类中List<Product>的变量名改为products(复数形式),符合编码规范,避免歧义。
内容的提问来源于stack exchange,提问作者Emre
相关产品推荐
相关产品推荐

