英文:
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` 时,具体来说,它在 `"promotion":0 -> instance of class Promotion` 处失败,因为 `Promotion` 是一个类,它必须类似这样:
```java
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}
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 "promotion":0 -> 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:
"promotion":{"filed1": 0}
So there are several ways to solve this problem:
- apprently you can change your request to:
"promotionZona":{"localidad":{"latitud":0.0,"longitud":0.0},"provincia":{},"todoElPais":true,"promotion":{"field1":0},"promoZonaId":0}
- 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
}
- add a custom
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;
}
}
then in PromotionZona, annotate the field promotion
with 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;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论