gpt4 book ai didi

Java Spring Boot REST API - 补丁 - "java.util.LinkedHashMap cannot be cast to xxx"

转载 作者:行者123 更新时间:2023-12-02 08:48:46 27 4
gpt4 key购买 nike


我有两个实体 - ConcertConcertDetail 以一对一单向关系连接(一场音乐会有一个细节)。
enter image description here

@Entity
@Table(name = "concert")
public class Concert {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;

@Column(name = "artist")
private String artist;

@Column(name = "city")
private String city;

@Column(name = "place")
private String place;

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "concert_detail_id")
private ConcertDetail concertDetail;

public Concert() {
}

public Concert(String artist,
String city,
String place) {
this.artist = artist;
this.city = city;
this.place = place;
}
//skipping the setters and getters

@Entity
@Table(name = "concert_detail")
public class ConcertDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;

@Column(name = "description")
private String description;

@Column(name = "date")
private LocalDate date;

@Column(name = "time")
private LocalTime time;

public ConcertDetail() {
}

public ConcertDetail(String description,
LocalDate date,
LocalTime time) {
this.description = description;
this.date = date;
this.time = time;
}
//skipping the setters and getters

不起作用的是使用@PatchMapping进行部分更新。

@PatchMapping("/concerts/{id}")
public ResponseEntity<Concert> updatePartOfConcert(@RequestBody Map<String,Object> updates,
@PathVariable("id") int id) {
Concert concert = concertRepository.findById(id);
if (concert == null) {
System.out.println("Concert with id: " + id + " not found in the system!");
return new ResponseEntity<Concert>(HttpStatus.NOT_FOUND);
}
partialUpdate(concert, updates);
return new ResponseEntity<Concert>(HttpStatus.NO_CONTENT);
}

private void partialUpdate(Concert concert, Map<String,Object> updates) {
if(updates.containsKey("artist")) {
concert.setArtist((String) updates.get("artist"));
}
if(updates.containsKey("city")) {
concert.setCity((String) updates.get("city"));
}
if(updates.containsKey("place")) {
concert.setPlace((String) updates.get("place"));
}
if(updates.containsKey("concertDetail")) {
concert.setConcertDetail((ConcertDetail) updates.get("concertDetail"));
}
concertRepository.save(concert);
}

如果我想更新艺术家、城市地点等字段 - 它工作正常。但是,当我将 concertDetail 作为 JSON 传递以用它更新给定的 Concert 时 - 我收到以下异常:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.musicao.app.entity.ConcertDetail
at com.musicao.app.restController.ConcertRestController.partialUpdate(ConcertRestController.java:109) ~[classes/:na]
at com.musicao.app.restController.ConcertRestController.updatePartOfConcert(ConcertRestController.java:94) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_242]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_242]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_242]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_242]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:880) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]

RestController 中的我的 Patch 方法:

@PatchMapping("/concerts/{id}")
public ResponseEntity<Concert> updatePartOfConcert(@RequestBody Map<String,Object> updates,
@PathVariable("id") int id) {
Concert concert = concertRepository.findById(id);
if (concert == null) {
System.out.println("Concert with id: " + id + " not found in the system!");
return new ResponseEntity<Concert>(HttpStatus.NOT_FOUND);
}
partialUpdate(concert, updates);
return new ResponseEntity<Concert>(HttpStatus.NO_CONTENT);
}

private void partialUpdate(Concert concert, Map<String,Object> updates) {
if(updates.containsKey("artist")) {
concert.setArtist((String) updates.get("artist"));
}
if(updates.containsKey("city")) {
concert.setCity((String) updates.get("city"));
}
if(updates.containsKey("place")) {
concert.setPlace((String) updates.get("place"));
}
if(updates.containsKey("concertDetail")) {
concert.setConcertDetail((ConcertDetail) updates.get("concertDetail"));
}
concertRepository.save(concert);
}

我在 Postman 中传递的 JSON:
enter image description here

我已经尝试过Spring REST and PATCH method

最佳答案

您的 Controller 方法updatePartOfConcert需要 Map<String, Object>参数,因此您没有告诉 Spring 将其反序列化为什么类型的对象。因此,它也无法反序列化子属性:序列化 concertDetail 是否一定是正确的?上面在对 ConcertDetail 的 JSON 响应中看到的对象目的?这三个字段是否可以反序列化为其他可能的类的实例?

Spring 无法知道这一点,所以 updates.get("concertDetail")将是 Map其中包含更新的音乐会详细信息字段。

如果您总是更新整个ConcertDetail一次性实例,您可以看看使用 Jackson ObjectMapper转换Map进入ConcertDetail目的。例如,参见this question .

但是,如果您只想更新音乐会详细信息的某些字段(鉴于您使用的是 PATCH 请求,您可以这样做),那么您必须编写一个单独的方法来更新:

private void partialUpdateConcertDetail(ConcertDetail concertDetail, Map<String, Object> detailUpdates) {
if (detailUpdates.containsKey("description")) {
concertDetail.setDescription((String) detailUpdates.get("description"));
}

// ... repeat for other fields.
}

然后您可以从 partialUpdate 调用此方法方法:

    if (updates.containsKey("concertDetail")) {
partialUpdateConcertDetail(concert.getConcertDetail(), (Map<String, Object>) updates.get("concertDetail"));
}

关于Java Spring Boot REST API - 补丁 - "java.util.LinkedHashMap cannot be cast to xxx",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60914107/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com