Deserialize from Number value to int (error – no int/Int-argument constructor/factory method to deserialize from Number value)

huangapple go评论115阅读模式
英文:

Deserialize from Number value to int (error - no int/Int-argument constructor/factory method to deserialize from Number value)

问题

我有两个类,Promotion 和 PromotionZona,出现了以下错误。

这是我要保存在数据库中的 JSON 请求。

"promotionZona":{"localidad":{"latitud":0.0,"longitud":0.0},"provincia":{},"todoElPais":true,"promotion":0,"promoZonaId":0}

你可以看到有 promotion,但是我无法将其保存到数据库中,出现了以下错误:

2020-10-25 20:06:50.024  INFO 5550 --- [           main] .d.s.w.r.o.CachingOperationNameGenerator : 正在生成唯一操作名称:find_3
2020-10-25 20:06:50.113  INFO 5550 --- [           main] o.s.s.quartz.SchedulerFactoryBean        : 正在启动 Quartz 调度程序
2020-10-25 20:06:50.113  INFO 5550 --- [           main] org.quartz.core.QuartzScheduler          : 调度程序 quartzScheduler_$_NON_CLUSTERED 已启动。
2020-10-25 20:06:50.133  INFO 5550 --- [           main] a.c.b.s.s.SuipBackofficeApplication      : 在 31.486 秒内启动了 SuipBackofficeApplication(JVM 运行时间为 57.573 秒)
2020-10-25 20:06:50.323  INFO 5550 --- [           main] org.apache.jasper.servlet.TldScanner     : 至少已扫描一个 JAR 以获取 TLD,但其中不包含 TLD。对于此记录器启用调试日志记录,以获取已扫描的所有 JAR 的完整列表,但在其中未找到 TLD。在扫描期间跳过不需要的 JAR 可以提高启动时间和 JSP 编译时间。
2020-10-25 20:06:50.419  INFO 5550 --- [           main] org.apache.coyote.ajp.AjpNioProtocol     : 正在启动 ProtocolHandler ["ajp-nio-8109"]
2020-10-25 20:06:50.430  INFO 5550 --- [           main] org.apache.catalina.startup.Catalina     : 服务器在 [47,370] 毫秒内启动
2020-10-25 20:07:21.325  INFO 5550 --- [nio-8180-exec-3] o.a.c.c.C.[.[.[/suip-backoffice]         : 正在初始化 Spring DispatcherServlet 'dispatcherServlet'
2020-10-25 20:07:21.327  INFO 5550 --- [nio-8180-exec-3] o.s.web.servlet.DispatcherServlet        : 正在初始化 Servlet 'dispatcherServlet'
2020-10-25 20:07:21.413  INFO 5550 --- [nio-8180-exec-3] o.s.web.servlet.DispatcherServlet        : 在 86 毫秒内完成初始化
2020-10-25 20:07:21.759  WARN 5550 --- [nio-8180-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : 已解析 [org.springframework.http.converter.HttpMessageNotReadableException: JSON 解析错误:无法构造 us.com.model.Promocion 的实例(尽管至少存在一个 Creator):没有 int/Int 参数构造函数/工厂方法可以从 Number 值(0)反序列化;嵌套异常是 com.fasterxml.jackson.databind.exc.MismatchedInputException: 无法构造 us.com.model.suipportalmodel.model.Promotion 的实例(尽管至少存在一个 Creator):没有 int/Int 参数构造函数/工厂方法可以从 Number 值(0)反序列化
 at [Source: (PushbackInputStream); line: 1, column: 2650] (通过引用链:ar.com.model.suipportalmodel.dto.PromotionDTO["promotionZona"]->java.lang.Object[][0]->PromotionZona["promotion"])]

我的实体 PromotionZona:

@Entity
@Table(name="promotion_zona")
public class PromotionZona implements Serializable {

   @Id 
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id_promotion_zona", unique = true, nullable= false)
   private Long idPromotionZona;
   
   @Column(name="todo_el_pais")
   private Boolean todoElPais;
   
   @Column(name="fecha_desde_solicitada")
   private Date fechaDesdeSolicitada;
   
   @Column(name="fecha_hasta_solicitada")
   private Date fechaHastaSolicitada;
   
   @Column(name="fecha_desde_confirmada")
   private Date fechaDesdeConfirmada;
   
   @Column(name="fecha_hasta_confirmada")
   private Date fechaHastaConfirmada;
   
   @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
   @JoinColumn(name="id_localidad",nullable=false)
   private Localidad localidad;
   
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "id_provincia", nullable = true)
   private Provincia provincia;
   
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name="id_promocion",nullable=false)
   private Promotion promotion; 
英文:

I have two classes Promotion and PromotionZona and hava this error.

Here is my json request which I want to save in the database.

"promotionZona":{"localidad":{"latitud":0.0,"longitud":0.0},"provincia":{},"todoElPais":true,"promotion":0,"promoZonaId":0}

You can see promotion, but I can't save it to my database, I've got such an error:

2020-10-25 20:06:50.113  INFO 5550 --- [           main] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now
2020-10-25 20:06:50.113  INFO 5550 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler quartzScheduler_$_NON_CLUSTERED started.
2020-10-25 20:06:50.133  INFO 5550 --- [           main] a.c.b.s.s.SuipBackofficeApplication      : Started SuipBackofficeApplication in 31.486 seconds (JVM running for 57.573)
2020-10-25 20:06:50.323  INFO 5550 --- [           main] org.apache.jasper.servlet.TldScanner     : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2020-10-25 20:06:50.419  INFO 5550 --- [           main] org.apache.coyote.ajp.AjpNioProtocol     : Starting ProtocolHandler ["ajp-nio-8109"]
2020-10-25 20:06:50.430  INFO 5550 --- [           main] org.apache.catalina.startup.Catalina     : Server startup in [47,370] milliseconds
2020-10-25 20:07:21.325  INFO 5550 --- [nio-8180-exec-3] o.a.c.c.C.[.[.[/suip-backoffice]         : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-10-25 20:07:21.327  INFO 5550 --- [nio-8180-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-10-25 20:07:21.413  INFO 5550 --- [nio-8180-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 86 ms
2020-10-25 20:07:21.759  WARN 5550 --- [nio-8180-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `us.com.model.Promocion` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (0); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `us.com.model.suipportalmodel.model.Promotion` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (0)
 at [Source: (PushbackInputStream); line: 1, column: 2650] (through reference chain: ar.com.model.suipportalmodel.dto.PromotionDTO["promotionZona"]->java.lang.Object[][0]->.PromotionZona["promotion"])]

My Entity PromotionZona:

@Table(name="promotion_zona")
public class PromotionZona implements Serializable {


   @Id 
   @GeneratedValue(strategy = GenerationType.IDENTITY)//9
   @Column(name = "id_promotion_zona", unique = true, nullable= false)
   private Long idPromotionZona;
   
   
   @Column(name="todo_el_pais")
   private Boolean todoElPais;
   
   @Column(name="fecha_desde_solicitada")
   private Date fechaDesdeSolicitada;
   
   @Column(name="fecha_hasta_solicitada")
   private Date fechaHastaSolicitada;
   
   @Column(name="fecha_desde_confirmada")
   private Date fechaDesdeConfirmada;
   
   @Column(name="fecha_hasta_confirmada")
   private Date fechaHastaConfirmada;
   
   @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
   @JoinColumn(name="id_localidad",nullable=false)
   private Localidad localidad;
   
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "id_provincia", nullable = true)
   private Provincia provincia;
   
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name="id_promocion",nullable=false)
   private Promotion promotion; ```


</details>


# 答案1
**得分**: 5

错误发生在 Spring MVC 尝试将 JSON 数据反序列化为你的类 `Promotion` 时,具体来说,它在 `&quot;promotion&quot;:0 -&gt; instance of class Promotion` 处失败,因为 `Promotion` 是一个类,它必须类似这样:

```java
public class Promotion {

   private int field1;
   
   // getters and setters
}

然后在你的 JSON 数据中应该是这样的:

&quot;promotion&quot;:{&quot;filed1&quot;: 0}

所以有几种方法可以解决这个问题:

1)显然,你可以将请求更改为:

&quot;promotionZona&quot;:{&quot;localidad&quot;:{&quot;latitud&quot;:0.0,&quot;longitud&quot;:0.0},&quot;provincia&quot;:{},&quot;todoElPais&quot;:true,&quot;promotion&quot;:{&quot;field1&quot;:0},&quot;promoZonaId&quot;:0}

2)为类 Promotion 添加一个带有 int 参数的构造函数:

public class Promotion {

    private int field1;

    public Promotion(int field1) {
        this.field1 = field1;
    }
    
    // getters and setters
}

3)添加一个自定义的 JsonDeserializer

public class PromotionJsonDeserializer extends JsonDeserializer<Promotion> {
    @Override
    public Promotion deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        if(jsonParser == null) return null;

        Promotion promotion = new Promotion();
        promotion.setField1(Integer.valueOf(jsonParser.getText()));
        return promotion;
    }
}

然后在 PromotionZona 中,使用 @PromotionJsonDeserializer 注解标注字段 promotion

@Table(name="promotion_zona")
public class PromotionZona implements Serializable {

   ...
 
   @JsonDeserialize(using = PromotionJsonDeserializer.class)
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name="id_promocion",nullable=false)
   private Promotion promotion;
英文:

The error happens when spring mvc fails to deserialize json data to your class Promotion, to be specific, it fails at &quot;promotion&quot;:0 -&gt; instance of class Promotion, since Promotion is a class, it must look something like this:

public class Promotion {

    private int field1;
    
    //getters and setters
}

then in your json data, it should be:

&quot;promotion&quot;:{&quot;filed1&quot;: 0}

So there are several ways to solve this problem:

  1. apprently you can change your request to:
&quot;promotionZona&quot;:{&quot;localidad&quot;:{&quot;latitud&quot;:0.0,&quot;longitud&quot;:0.0},&quot;provincia&quot;:{},&quot;todoElPais&quot;:true,&quot;promotion&quot;:{&quot;field1&quot;:0},&quot;promoZonaId&quot;:0}

  1. add an int-argument constructor to the class Promotion:
public class Promotion {

    private int field1;

    public Promotion(int field1) {
        this.field1 = field1;
    }
    
    //getters and setters
}
  1. add a custom JsonDeserializer:
public class PromotionJsonDeserializer extends JsonDeserializer&lt;Promotion&gt; {
    @Override
    public Promotion deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        if(jsonParser == null)return null;

        Promotion promotion = new Promotion();
        promotion.setField1(Integer.valueOf(jsonParser.getText()));
        return promotion;
    }
}

then in PromotionZona, annotate the field promotion with PromotionJsonDeserializer:


@Table(name=&quot;promotion_zona&quot;)
public class PromotionZona implements Serializable {

   ...
 
   @JsonDeserialize(using = PromotionJsonDeserializer.class)
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name=&quot;id_promocion&quot;,nullable=false)
   private Promotion promotion;

huangapple
  • 本文由 发表于 2020年10月26日 07:22:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/64529816.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定