2016-12-06 5 views
4

Когда я использую Ломбки в моем приложении Spring Data REST определять сложные типы, как:Spring Data REST: «нет строки-аргумент метода конструктора/завода не десериализации из строкового значения»

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

    // ... 
} 

с Spring Data REST контроллеры нравятся:

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

я некрасивая ошибка:

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

использование Spring Data Rest о Джексон с POST книги, как:

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

Ошибка де-сериализации происходит, когда Джексон пытается разрешить /people/123 локальный URI, который должен решить в один, уникальный Person. Если я удалю свой @RepositoryRestController, все будет хорошо. Любая идея, что не так с моим определением контроллера REST?

+0

Эй, Ян, почему вы используете suppressConstructorProperties = true в AllArgsConstructor? Lombok dosumentation говорит: «Если установлено значение true, то lombok пропустит добавление @ java.beans.ConstructorProperties к сгенерированным конструкторам. Это полезно в разработке Android и GWT, где эта аннотация обычно недоступна ». Кажется, что вы не попадаете в рекомендуемые случаи. Что произойдет, если вы удалите эту конфигурацию? – avi613

+0

Пожалуйста, проверьте аннотацию @Data в Ломбоке. Он генерирует равные и хэш-коды. – avi613

+0

@ avi613 - к сожалению, десериализация Джексона вызывает вышеупомянутую ошибку без '@AllArgsConstructor (suppressConstructorProperties = true)' - это, вероятно, ошибка Ломбока. –

ответ

10

В @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.

+1

Я подвергаю свои репозитории с помощью @RepositoryRestResource (в качестве ресурсов ресурсов HATEOAS для данных Spring-Data) У меня нет RepositoryRestController. Но я получаю ту же ошибку. Как я могу обойти это? – Robert

+0

@Robert - это, вероятно, та же самая фундаментальная проблема: Джексон не может де-сериализовать ваши данные; но решение будет отличаться для вашего случая. Я предлагаю вам открыть новый вопрос со всеми подробностями ... –

+0

@Robert - вы также можете прочитать раздел [Представление объектов домена в ссылке Spring REST] (http://docs.spring.io/spring-data/ остальные/Docs/текущие/задания/HTML/# представления). –

 Смежные вопросы

  • Нет связанных вопросов^_^