Spring Data REST: "no String-argument constructor / factory deserialization method from string value"

When I use Lombok in my Spring Data REST application to define complex types, for example:

@NoArgsConstructor
@AllArgsConstructor
@Data

@Entity
@Table(name = "BOOK")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(nullable = false)
    private Long id;

    private String title;

    @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
    private Person author;

    // ...
}

with Spring Data REST data controllers such as:

@RepositoryRestController
public class BookRepositoryRestController {

    private final BookRepository repository;

    @Autowired
    public BookRepositoryRestController(BookRepository repository) {
        this.repository = repository;
    }

    @RequestMapping(method = RequestMethod.POST,value = "/books")
    public @ResponseBody PersistentEntityResource post(
        @RequestBody Book book,
        PersistentEntityResourceAssembler assembler) {

        Book entity = processPost(book);

        return assembler.toResource(entity);
    }

    private Book processPost(Book book) {
        // ...
        return this.repository.save(book);
    }
}

I get an ugly error:

no String-argument constructor/factory method to deserialize from String value

from Spring Using REST data for Jackson with a POST book:

curl -X POST 
     -H 'content-type: application/json' 
     -d '{"title":"Skip Like a Pro", "author": "/people/123"}'
     http://localhost:8080/api/books/

A de-serialization error occurs when Jackson tries to resolve a local URI /people/123, which must be resolved for a single unique Person. If I delete mine @RepositoryRestController, everything will be fine. Any idea what is wrong with my definition of a REST controller?

+4
source share
1

@RepositoryRestController @RequestBody Book Resource<Book>:

import org.springframework.hateoas.Resource;

    // ...

    @RequestMapping(method = RequestMethod.POST,value = "/books")
    public @ResponseBody PersistentEntityResource post(
        @RequestBody Resource<Book> bookResource,             // Resource<Book>
        PersistentEntityResourceAssembler assembler) {

        Book book = bookResource.getContent()
        // ...
    }

Book AllArgsConstructor: @AllArgsConstructor(suppressConstructorProperties = true).

. Spring Data REST # 687.

+10

Source: https://habr.com/ru/post/1662913/


All Articles