Десериализация из числового значения в int (ошибка — нет конструктора int / Int-argument / заводского метода для десериализации из числового значения)

#java

#java

Вопрос:

У меня есть два класса Promotion и PromotionZona и имеют эту ошибку.

Вот мой запрос json, который я хочу сохранить в базе данных.

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

Вы можете увидеть продвижение, но я не могу сохранить его в своей базе данных, у меня такая ошибка:

 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"])]
  

Моя зона продвижения объекта:

 @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; ```
  

Комментарии:

1. Не уверен, связано ли это, но у вас есть Promocion в вашей сущности и promotion в вашем запросе.

2. Это не имеет значения, я меняю сейчас, но та же ошибка

3. Ваш json на самом деле не является допустимым json. Вам нужно будет обернуть его в {}, чтобы сделать его действительным.

Ответ №1:

Ошибка возникает, когда spring mvc не удается десериализовать данные json для вашего класса Promotion , точнее, это сбой "promotion":0 -> instance of class Promotion , поскольку Promotion это класс, он должен выглядеть примерно так:

 public class Promotion {

    private int field1;
    
    //getters and setters
}
  

затем в ваших данных json это должно быть:

 "promotion":{"filed1": 0}
  

Итак, есть несколько способов решить эту проблему:

  1. в настоящее время вы можете изменить свой запрос на:
 "promotionZona":{"localidad":{"latitud":0.0,"longitud":0.0},"provincia":{},"todoElPais":true,"promotion":{"field1":0},"promoZonaId":0}

  
  1. добавьте конструктор int-argument в класс Promotion :
 public class Promotion {

    private int field1;

    public Promotion(int field1) {
        this.field1 = field1;
    }
    
    //getters and setters
}
  
  1. добавьте пользовательский 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 аннотируйте поле promotion с помощью PromotionJsonDeserializer :

 
@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;