Java primavera de arranque API REST - Patch - "java.util.LinkedHashMap no se puede convertir a xxx"

lvndsky:


Tengo dos entidades - Concierto y ConcertDetail conectados en uno-a-uno relación unidireccional (un concierto tiene un detalle).
introducir descripción de la imagen aquí

@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

Lo que no funciona, es la actualización parcial con @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);
    }

Si quiero actualizar los campos como artista, ciudad o lugar - que funciona bien. Pero cuando paso el concertDetail como JSON para actualizar el concierto dado con ella - Me da la siguiente excepción:

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]

Mi método de parches en RestController :

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

JSON que pase en el cartero:
introducir descripción de la imagen aquí

Ya he probado la primavera y el método PARCHE DE DESCANSO

Lucas Woodward:

Su método de control updatePartOfConcerttoma un Map<String, Object>parámetro, por lo que no está diciendo la primavera qué tipo de objeto para deserializar a. Como resultado de ello no puede deserializar propiedades secundarias o bien: habría que ser necesariamente correcta para serializar el concertDetailobjeto visto anteriormente en su respuesta JSON a un ConcertDetailobjeto? ¿Hay otras clases posibles que estos tres campos podrían deserializar a una instancia de?

La primavera no puede saber esto, por lo que updates.get("concertDetail")será una Mapque contiene los detalles del concierto campos actualizados.

Si siempre está actualizando toda la ConcertDetailinstancia de una sola vez, se podría contemplar la utilización de un Jackson ObjectMapperpara convertir la Mapen un ConcertDetailobjeto. Véase, por ejemplo esta pregunta .

Sin embargo, si sólo desea actualizar algunos de los campos del concierto detalle (que se puede hacer, ya que estás usando una solicitud parche), entonces usted tendrá que escribir un método separado de actualización que:

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

    // ... repeat for other fields.    
}

A continuación, llama a este método de su partialUpdatemétodo:

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

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=361851&siteId=1
Recomendado
Clasificación