Несколько свойств обратной ссылки с именем defaultReference! Почему? - PullRequest
0 голосов
/ 21 апреля 2020

В классе Customer у меня есть метод Post. Все правильно написано в контроллере и репозитории, ошибок нет. По какой-то причине, когда я выполняю запрос через Swagger, я получаю сообщение об ошибке, точнее, предупреждение:

2020-04-21 14:18:39.427  WARN 5672 --- [nio-8080-exec-7] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class com.tinychiefdelights.model.Customer]]: com.fasterxml.jackson.databind.JsonMappingException: Multiple back-reference properties with name 'defaultReference'
2020-04-21 14:18:39.428  WARN 5672 --- [nio-8080-exec-7] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class com.tinychiefdelights.model.Customer]]: com.fasterxml.jackson.databind.JsonMappingException: Multiple back-reference properties with name 'defaultReference'
2020-04-21 14:18:39.430  WARN 5672 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported]

Сам проект написан Spring MVC + hibernate + JPA + PostgreSql database.

* 1007. * В классе Customer у меня есть отношения с другими классами @ OnetoMany @ OnetoOne .

Клиент:

package com.tinychiefdelights.model;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.Data;

import javax.persistence.*;
import java.util.List;

@Data
@Entity
@Table(name = "customer", schema = "public")
public class Customer {

    public Customer() { // Пустой конструктор для Hibernate

    }


    // Поля

    // name, lastName, login, password берем от класса User через связи;

    private @Id
    @GeneratedValue
    Long id;

    @Column(name = "wallet")
    private double wallet;


    //Relationships
    //
    @OneToOne
    @JoinColumn(name = "user_id", referencedColumnName = "id") // Join without Customer in User class
    private User user;

    //Лист заказов
    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
    @JsonManagedReference // Таким образом я предотвратил рекурсию
    private List<Order> orderList;

}

CustomerController:

package com.tinychiefdelights.controller;

import com.tinychiefdelights.exceptions.NotFoundException;
import com.tinychiefdelights.model.Customer;
import com.tinychiefdelights.repository.CustomerRepository;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Api(value = "Работа с Заказчиком", tags = {"Заказчик"})
@RestController
public class CustomerController {

    private final CustomerRepository customerRepository;

    public CustomerController(CustomerRepository customerRepository) {
        this.customerRepository = customerRepository;
    }


    // Aggregate Root
    @GetMapping("/customers")
    List<Customer> all(){
        return customerRepository.findByUserRole("customer");
    }

    @PostMapping("/customers")
    Customer newCustomer(@RequestBody Customer newCustomer){
        return customerRepository.save(newCustomer);
    }

    //Single Item
    @GetMapping("/customers/{id}")
    Customer one(@PathVariable Long id) {
        return customerRepository.findById(id)
                .orElseThrow(() -> new NotFoundException(id));
    }

    @PutMapping("/customers/{id}")
    Customer replaceCustomer(@RequestBody Customer newCustomer, @PathVariable Long id){
        return customerRepository.findById(id)
                .map(customer -> {
                    customer.setUser(newCustomer.getUser());
                    customer.setWallet(newCustomer.getWallet());
                    customer.setOrderList(newCustomer.getOrderList());
                    return customerRepository.save(customer);
                })
                .orElseGet(() -> {
                    newCustomer.setId(id);
                    return customerRepository.save(newCustomer);
                });
    }

    @DeleteMapping("/customers/{id}")
    void deleteCustomer(@PathVariable Long id){
        customerRepository.deleteById(id);
    }

}

Заказ:

package com.tinychiefdelights.model;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import lombok.Data;

import javax.persistence.*;
import java.util.Date;
import java.util.List;

@Data
@Entity
@Table(name = "pg_order", schema = "public")
public class Order {

    public Order(){ // Пустой конструктор для Hibernate

    }

    public Order(Customer customer, String address,
                 String phoneNumber, Date dateOrder, Cook cook,
                 List<Dish> dishes, boolean orderStatus) { // Базовый конструктор

        this.customer = customer;
        this.address = address;
        this.phoneNumber= phoneNumber;
        this.dateOrder = dateOrder;
        this.cook = cook;
        this.dishes = dishes;
        this.orderStatus = orderStatus;
    }


    // Поля
    private @Id @GeneratedValue Long id;

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

    @Column(name = "phone_number")
    private String phoneNumber;

    @Column(name = "date_order")
    private Date dateOrder;

    @Column(name = "order_status")
    private boolean orderStatus;


    //Relationships
    //Заказчик
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JsonBackReference(value = "customer") // Таким образом я предотвратил рекурсию
    private Customer customer;

    //Лист блюд
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(
            name = "order_dish",
            joinColumns = @JoinColumn(name = "dish_id"),
            inverseJoinColumns = @JoinColumn(name = "order_id"))
    @JsonManagedReference(value = "order") // Таким образом я предотвратил рекурсию
    private List<Dish> dishes;

    //Повар
    @ManyToOne(fetch= FetchType.LAZY, cascade= CascadeType.ALL)
    @JsonBackReference(value = "cook") // Таким образом я предотвратил рекурсию
    private Cook cook;
}

1 Ответ

0 голосов
/ 24 апреля 2020

@ JsonBackReference и @ JsonManagedReference не особенно любят работать с коллекциями, поэтому там, где произошла ошибка, я просто изменил @ JsonIgnore к аннотации.

...