不写JSON:无限递归(StackOverflowError);嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException: 无限递归
not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion
我正在开发 Spring Boot + Data Jpa + Postgres + Swaggerfox
示例。在这个例子中,我遇到了以下错误。
错误:
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@4b0cc859<rs=HikariProxyResultSet@1568394184 wrapping org.postgresql.jdbc.PgResultSet@439cca7d>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@2b3b519c<rs=HikariProxyResultSet@1558688075 wrapping org.postgresql.jdbc.PgResultSet@749887a>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@2a2ad6ca<rs=HikariProxyResultSet@1350054348 wrapping org.postgresql.jdbc.PgResultSet@fc02ed0>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@7e063905<rs=HikariProxyResultSet@324722253 wrapping org.postgresql.jdbc.PgResultSet@35c774e7>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@49a76813<rs=HikariProxyResultSet@1730994902 wrapping org.postgresql.jdbc.PgResultSet@479f6959>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@89ebebe<rs=HikariProxyResultSet@2103425508 wrapping org.postgresql.jdbc.PgResultSet@6f08306>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@74e5843b<rs=HikariProxyResultSet@1775874661 wrapping org.postgresql.jdbc.PgResultSet@488cfe5f>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@359ac2be<rs=HikariProxyResultSet@60954866 wrapping org.postgresql.jdbc.PgResultSet@37708fb8>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@6fec0131<rs=HikariProxyResultSet@2098642686 wrapping org.postgresql.jdbc.PgResultSet@403d6495>
BaseEntity.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
@CreatedDate
@Column(name = "createdDate", nullable = false, updatable = false)
private Instant createdDate;
@LastModifiedDate
@Column(name = "lastUpdateDate", nullable = false)
private Instant lastUpdateDate;
@Column(name = "createUser", nullable = false, length = 50)
private String createUser;
@Column(name = "lastUpdateUser", length = 50)
private String lastUpdateUser;
}
Category.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "category")
public class Category extends BaseEntity implements java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "CATEGORY_ID", unique = true, nullable = false)
private Integer categoryId;
@Column(name = "NAME", nullable = false, length = 10)
private String name;
@Column(name = "[DESC]", nullable = false)
private String desc;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "categories")
private Set<Stock> stocks = new HashSet<>(0);
@Builder(builderMethodName = "cBuilder")
public Category(Integer categoryId, String name, String desc, Set<Stock> stocks,
Instant createdDate,Instant lastUpdateDate, String createUser, String lastUpdateUser) {
super(createdDate, lastUpdateDate, createUser, lastUpdateUser);
this.categoryId = categoryId;
this.name = name;
this.desc = desc;
this.stocks = stocks;
}
}
Stock.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "stock", uniqueConstraints = { @UniqueConstraint(columnNames = "STOCK_NAME"),
@UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock extends BaseEntity implements java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "STOCK_ID", unique = true, nullable = false)
private Integer stockId;
@Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
private String stockCode;
@Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
private String stockName;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "stock_category", catalog = "mkyongdb", joinColumns = {
@JoinColumn(name = "STOCK_ID", nullable = false, updatable = false) }, inverseJoinColumns = {
@JoinColumn(name = "CATEGORY_ID", nullable = false, updatable = false) })
private Set<Category> categories = new HashSet<>(0);
@Builder(builderMethodName = "sBuilder")
public Stock(Integer stockId, String stockCode, String stockName, Set<Category> categories, Instant createdDate,
Instant lastUpdateDate, String createUser, String lastUpdateUser) {
super(createdDate, lastUpdateDate, createUser, lastUpdateUser);
this.stockId = stockId;
this.stockCode = stockCode;
this.stockName = stockName;
this.categories = categories;
}
}
启动时:http://localhost:8080/swagger-ui.html#/Category_Management 出现上述错误:
主应用程序
@SpringBootApplication
@EnableJpaAuditing
public class MyExampleApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(MyExampleApplication.class, args);
}
@Autowired
private StockRepository stockRepository;
@Autowired
private CategoryRepository categoryRepository;
@Override
public void run(String... args) throws Exception {
Stock stock = Stock.sBuilder().stockCode("7052").stockName("PADINI").createUser("John Doe")
.lastUpdateUser("John Doe").build();
Category category1 = Category.cBuilder().name("CONSUMER").desc("CONSUMER COMPANY").createUser("John Doe")
.lastUpdateUser("John Doe").build();
Category category2 = Category.cBuilder().name("INVESTMENT").desc("INVESTMENT COMPANY").createUser("Neha Parate")
.lastUpdateUser("Neha Parate").build();
Set<Category> categories = new HashSet<>();
categories.add(category1);
categories.add(category2);
stock.setCategories(categories);
stockRepository.save(stock);
}
}
注意:如果我使用许多块建议的 @JsonIgnore
,那么我也会丢失对象关联的实体数据,但我也希望显示所有数据 + 关联的实体数据。
您遇到的问题是循环引用。
@JsonManagedReference
和@JsonBackReference
用于处理循环引用。
@JsonManagedReference
用于目标 POJO 的子引用。
@JsonBackReference
用于对应的子class。它被放置在反向引用 属性 上。
我正在开发 Spring Boot + Data Jpa + Postgres + Swaggerfox
示例。在这个例子中,我遇到了以下错误。
错误:
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@4b0cc859<rs=HikariProxyResultSet@1568394184 wrapping org.postgresql.jdbc.PgResultSet@439cca7d>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@2b3b519c<rs=HikariProxyResultSet@1558688075 wrapping org.postgresql.jdbc.PgResultSet@749887a>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@2a2ad6ca<rs=HikariProxyResultSet@1350054348 wrapping org.postgresql.jdbc.PgResultSet@fc02ed0>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@7e063905<rs=HikariProxyResultSet@324722253 wrapping org.postgresql.jdbc.PgResultSet@35c774e7>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@49a76813<rs=HikariProxyResultSet@1730994902 wrapping org.postgresql.jdbc.PgResultSet@479f6959>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@89ebebe<rs=HikariProxyResultSet@2103425508 wrapping org.postgresql.jdbc.PgResultSet@6f08306>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@74e5843b<rs=HikariProxyResultSet@1775874661 wrapping org.postgresql.jdbc.PgResultSet@488cfe5f>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@359ac2be<rs=HikariProxyResultSet@60954866 wrapping org.postgresql.jdbc.PgResultSet@37708fb8>
2019-08-06 20:29:02.449 WARN 24884 --- [nio-8080-exec-1] o.h.e.loading.internal.LoadContexts : HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@6fec0131<rs=HikariProxyResultSet@2098642686 wrapping org.postgresql.jdbc.PgResultSet@403d6495>
BaseEntity.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
@CreatedDate
@Column(name = "createdDate", nullable = false, updatable = false)
private Instant createdDate;
@LastModifiedDate
@Column(name = "lastUpdateDate", nullable = false)
private Instant lastUpdateDate;
@Column(name = "createUser", nullable = false, length = 50)
private String createUser;
@Column(name = "lastUpdateUser", length = 50)
private String lastUpdateUser;
}
Category.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "category")
public class Category extends BaseEntity implements java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "CATEGORY_ID", unique = true, nullable = false)
private Integer categoryId;
@Column(name = "NAME", nullable = false, length = 10)
private String name;
@Column(name = "[DESC]", nullable = false)
private String desc;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "categories")
private Set<Stock> stocks = new HashSet<>(0);
@Builder(builderMethodName = "cBuilder")
public Category(Integer categoryId, String name, String desc, Set<Stock> stocks,
Instant createdDate,Instant lastUpdateDate, String createUser, String lastUpdateUser) {
super(createdDate, lastUpdateDate, createUser, lastUpdateUser);
this.categoryId = categoryId;
this.name = name;
this.desc = desc;
this.stocks = stocks;
}
}
Stock.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "stock", uniqueConstraints = { @UniqueConstraint(columnNames = "STOCK_NAME"),
@UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock extends BaseEntity implements java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "STOCK_ID", unique = true, nullable = false)
private Integer stockId;
@Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
private String stockCode;
@Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
private String stockName;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "stock_category", catalog = "mkyongdb", joinColumns = {
@JoinColumn(name = "STOCK_ID", nullable = false, updatable = false) }, inverseJoinColumns = {
@JoinColumn(name = "CATEGORY_ID", nullable = false, updatable = false) })
private Set<Category> categories = new HashSet<>(0);
@Builder(builderMethodName = "sBuilder")
public Stock(Integer stockId, String stockCode, String stockName, Set<Category> categories, Instant createdDate,
Instant lastUpdateDate, String createUser, String lastUpdateUser) {
super(createdDate, lastUpdateDate, createUser, lastUpdateUser);
this.stockId = stockId;
this.stockCode = stockCode;
this.stockName = stockName;
this.categories = categories;
}
}
启动时:http://localhost:8080/swagger-ui.html#/Category_Management 出现上述错误:
主应用程序
@SpringBootApplication
@EnableJpaAuditing
public class MyExampleApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(MyExampleApplication.class, args);
}
@Autowired
private StockRepository stockRepository;
@Autowired
private CategoryRepository categoryRepository;
@Override
public void run(String... args) throws Exception {
Stock stock = Stock.sBuilder().stockCode("7052").stockName("PADINI").createUser("John Doe")
.lastUpdateUser("John Doe").build();
Category category1 = Category.cBuilder().name("CONSUMER").desc("CONSUMER COMPANY").createUser("John Doe")
.lastUpdateUser("John Doe").build();
Category category2 = Category.cBuilder().name("INVESTMENT").desc("INVESTMENT COMPANY").createUser("Neha Parate")
.lastUpdateUser("Neha Parate").build();
Set<Category> categories = new HashSet<>();
categories.add(category1);
categories.add(category2);
stock.setCategories(categories);
stockRepository.save(stock);
}
}
注意:如果我使用许多块建议的 @JsonIgnore
,那么我也会丢失对象关联的实体数据,但我也希望显示所有数据 + 关联的实体数据。
您遇到的问题是循环引用。
@JsonManagedReference
和@JsonBackReference
用于处理循环引用。
@JsonManagedReference
用于目标 POJO 的子引用。
@JsonBackReference
用于对应的子class。它被放置在反向引用 属性 上。