Java Primavera Bota API REST - Remendo - "java.util.LinkedHashMap não pode ser convertido para xxx"

lvndsky:


Eu tenho duas entidades - Concerto e ConcertDetail conectado in One-To-One relação unidirecional (um concerto tem um detalhe).
digite descrição da imagem aqui

@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

O que não funciona, é a atualização parcial com @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);
    }

Se eu quiser atualizar os campos como artista, cidade ou lugar - ele funciona bem. Mas quando eu passar o concertDetail como JSON para atualizar o concerto dado com ele - eu recebo a seguinte exceção:

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]

Meu método patch em 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 eu passar em Postman:
digite descrição da imagem aqui

Eu já tentei Primavera REST e método PATCH

Luke Woodward:

O seu método de controlador updatePartOfConcertleva um Map<String, Object>parâmetro, então você não está dizendo a Primavera que tipo de objeto para desserializar ele. Como resultado, ele não pode desserializar propriedades filho seja: será que ser necessariamente correto para serializar o concertDetailobjeto visto acima em sua resposta JSON para um ConcertDetailobjeto? Existem outras classes possíveis que esses três campos pode desserializar a uma instância de?

Primavera não pode saber disso, então updates.get("concertDetail")será uma Mapque contém os concerto Detalhes campos atualizados.

Se você está sempre atualizando toda a ConcertDetailinstância de uma só vez, você pode olhar para usando um Jackson ObjectMapperpara converter o Mapem um ConcertDetailobjeto. Veja por exemplo esta questão .

No entanto, se você só quer atualizar alguns dos campos do detalhe concerto (que você pode fazer, uma vez que você estiver usando uma solicitação PATCH), então você terá que escrever um método separado para atualização que:

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

    // ... repeat for other fields.    
}

Você, então, chamar esse método de seu partialUpdatemétodo:

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

Acho que você gosta

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