Spring Boot Jackson ResponseEntity 找不到类的序列化程序
Posted
技术标签:
【中文标题】Spring Boot Jackson ResponseEntity 找不到类的序列化程序【英文标题】:Spring Boot Jackson ResponseEntity No serializer found for class 【发布时间】:2020-07-26 02:32:36 【问题描述】:我在使用 Spring Boot 控制器时遇到了一个奇怪的错误,没有返回最近创建的对象。
我有一个控制器,有两种方法(见下文)。一个简单的检索类“OrderPay”的对象并将其作为响应实体的有效负载返回。这工作正常,因此对象没问题。
另一个创建并保存“OrderPay”的新实例,然后应该返回那个新创建的对象。新对象的创建及其持久性工作正常。但是,当我尝试退货时,我收到以下错误消息。
现在我会理解该错误消息,如果它始终如一地发生。但是,当使用第一个函数(“getPaymentByIdTest”)返回这个新创建的对象时,它会毫无问题地返回它,即使我以完全相同的方式从数据库中检索它并以相同的方式返回它,具有相同的返回类型方法。
现在我知道在 HTTP-GET 方法中执行代码不是最佳实践,但它更快更方便测试。
谁能看到我需要在哪里调整代码?
2020-04-13 21:37:57.507 错误 26796 --- [nio-8081-exec-2] oaccC[.[.[/].[dispatcherServlet]:Servlet.service() 用于 servlet [dispatcherServlet]在路径 [] 的上下文中抛出异常 [请求处理失败;嵌套异常是org.springframework.http.converter.HttpMessageConversionException:类型定义错误:[简单类型,类org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor];嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties found to create BeanSerializer(为避免异常,禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS)(通过参考链:com.brownbag_api.model.OrderPay["posSend"]->com.brownbag_api.model.Pos$HibernateProxy$7l7MDMEi["hibernateLazyInitializer"])] 根本原因
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor 也没有发现创建 BeanSerializer 的属性(为避免异常,禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS)(通过参考链:com.brownbag_api.model.OrderPay["posSend"]->com.brownbag_api.model.Pos$HibernateProxy$7l7MDMEi["hibernateLazyInitializer"])
-
控制器
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api/pay")
public class PaymentController
@Autowired
private OrderPayRepo orderPayRepo;
@Autowired
private OrderPaySvc orderPaySvc;
@GetMapping("/id")
public ResponseEntity<?> getPaymentByIdTest(@PathVariable Long id)
Optional<OrderPay> orderPay = orderPayRepo.findById(id);
return ResponseEntity.ok(orderPay);
@GetMapping("/exec/from/from/to/to/amount/amount")
public ResponseEntity<?> execPayment(@PathVariable Long from, @PathVariable Long to, @PathVariable double amount)
Pos posFrom = posRepo.getOne(from);
Pos posTo = posRepo.getOne(to);
OrderPay pay = orderPaySvc.createPay(amount, posFrom, posTo);
pay = orderPaySvc.execPay(pay);
if (pay == null)
return ResponseEntity.ok("Payment could not be executed. Please see log for more details!");
else
System.err.println("Payment executed: " + pay.getPosRcv().getParty().getName());
Long payId = pay.getId();
System.err.println("Payment executed: " + payId);
// payId returns the expected value here, the object is therefore saved in the database (verified).
Optional<OrderPay> orderPay = orderPayRepo.findById(payId);
return ResponseEntity.ok(pay);
-
Order.java
@Entity
@Table(name = "order_base")
@Inheritance(strategy = InheritanceType.JOINED)
public class Order implements Serializable
private static final long serialVersionUID = -3458221490393509305L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@NotNull
@Column(name = "QTY")
private double qty;
public Order()
public Order(@NotNull double qty)
super();
this.qty = qty;
-
订单支付
@Entity
@Table(name = "order_pay")
public class OrderPay extends Order implements Serializable
private static final long serialVersionUID = 4643589803146964779L;
@NotNull
@OneToOne(targetEntity = Pos.class)
@JoinColumn(name = "POS_SEND_ID")
private Pos posSend;
@NotNull
@OneToOne(targetEntity = Pos.class)
@JoinColumn(name = "POS_RCV_ID")
private Pos posRcv;
public OrderPay()
super();
public OrderPay(@NotNull double qty, @NotNull Pos posSend, @NotNull Pos posRcv)
super(qty);
this.posSend = posSend;
this.posRcv = posRcv;
-
Pos.java
@Entity
@Table(name = "POS")
public class Pos implements Serializable
private static final long serialVersionUID = 1530699992135610397L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@NotNull
@Column(name = "QTY")
private double qty;
@NotNull
@ManyToOne(targetEntity = Party.class)
@JoinColumn(name = "PARTY_ID")
@JsonBackReference
private Party party;
public Pos()
public Pos(@NotNull double qty, @NotNull Party owner)
super();
this.qty = qty;
this.party = owner;
-
JSON
"id":7,
"qty":33000.0,
"posSend":
"id":1,
"qty":-266010.0,
"hibernateLazyInitializer":
,
"posRcv":
"id":2,
"qty":66000.0,
"hibernateLazyInitializer":
【问题讨论】:
添加Pos
类也
【参考方案1】:
如果您使用的是 Spring Boot,您可以在 application.properties 文件中设置以下属性。根据您的堆栈跟踪,这应该可以解决问题(请参阅:“为避免异常,禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS”)
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
【讨论】:
这修复了错误,但在 JSON 文件中添加了一个新行。有没有没有这种副作用的替代品? 它为您添加了哪些额外的行?您能否将 JSON 添加到您的原始问题陈述中? 我添加了带有“hibernateLazyInitializer”附录的 JSON。它仅在初始创建时发生,并在使用第一个控制器方法获取对象时消失(即在创建后不立即调用它) 我通常从不使用与 JPA/Hibernate 相同的对象并将它们公开为 JSON 对象。通常我在两者之间有一个映射以确保它们不是同一个对象,所以我从来没有这个问题。 我明白了。我觉得这对我的应用程序来说可能有点矫枉过正,除非这样可以为我节省很多时间。请问您如何映射它们?您在 JSON 对象中是否有一个构造函数,它接收 JPA 对象作为参数并在 JSON 对象的构造函数中逐字段映射它?以上是关于Spring Boot Jackson ResponseEntity 找不到类的序列化程序的主要内容,如果未能解决你的问题,请参考以下文章
Jackson 在我的 Spring Boot 应用程序中忽略了 spring.jackson.properties
如何在 Spring Boot 1.4 中自定义 Jackson
Spring Boot没有使用Jackson Kotlin插件