Как я могу отправить данные в теле POST без установки автоматически сгенерированных значений первичного ключа в Spring Boot? - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть два класса / таблицы --- Клиент и Адрес, имеющие двунаправленное отношение один к одному. Address_id - это внешний ключ.

Вот диаграмма объекта

enter image description here

Я пытаюсь отправить данные через почтальона, но я хочу отправить значения без установки атрибутов первичного ключа в теле сообщения. Это работает, если я опущу атрибут id только для клиента. Но это не работает, если я делаю то же самое для адреса.

Это тело сообщения, для которого данные успешно вставляются.

<Customer>
<firstName>Dave</firstName>
<lastName>Bautista</lastName>
<gender>M</gender>
<date>2012-01-26T09:00:00.000+0000</date>
<addressdto>
<id>7</id>
<city>BANKURA</city>
<country>WEST BENGAL</country>
</addressdto>
</Customer>

, если я опускаю <id></id> in addressdto тогда я получаю эту ошибку в почтальоне -

Failed to add customer due to could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

Ошибка в консоли -

2020-04-23 23:10:12.093 ERROR 3824 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper   : 
Cannot add or update a child row
: a foreign key constraint fails (`liqbtest`.`customers`, CONSTRAINT `FK_DETAIL` FOREIGN KEY 
(`address_id`) REFERENCES `address` (`id`))

CustomerDto

package com.spring.liquibase.demo.dto;

import java.util.Date;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.sun.xml.txw2.annotation.XmlElement;


@JacksonXmlRootElement(localName = "Customer")
public class CustomerDto {

    private int id;
    private String firstName;
    private String lastName;
    private String gender;
    private Date date;
    private AddressDto addressdto;


    public CustomerDto() {
        super();
    }
..getters and setters

addressDto

public class AddressDto {

    private int id;
    private String city;
    private String country;


    public AddressDto() {
        super();
    }

EntityToDtoMapper

public Customer mapToEntity(CustomerDto customerDto) {
        Address address=new Address();
        address.setCity(customerDto.getAddressdto().getCity());
        address.setCountry(customerDto.getAddressdto().getCountry());
        address.setId(customerDto.getAddressdto().getId());

        Customer customer=new Customer();
        customer.setId(customerDto.getId());
        customer.setFirstName(customerDto.getFirstName());
        customer.setLastName(customerDto.getLastName());
        customer.setGender(customerDto.getGender());
        customer.setDate(customerDto.getDate());
        customer.setAddress(address);
        return customer;    
    }

HomeController

@PostMapping("/customer")
     public ResponseEntity<String> addCustomer(@RequestBody CustomerDto customerDto){
        String message="";
        ResponseEntity<String> finalMessage=null;
        try {

        Customer customer=mapper.mapToEntity(customerDto);
        customerService.addCustomer(customer);
        message="Customer with "+customer.getId()+" sucessfully added";
        finalMessage= new ResponseEntity<>(message, HttpStatus.OK);

    }catch(Exception e) {
        message="Failed to add customer due to "+e.getMessage();
        finalMessage= new ResponseEntity<>(message, HttpStatus.NOT_ACCEPTABLE);
    }
        return finalMessage;
    }

Скажите, пожалуйста, как это правильно сделать, я не думаю, что нам нужно укажите поля идентификатора. Как я могу подойти к этому? В методе EntityToDtoMapper mapToEntity(), если я опускаю setId() из addressDto, он вообще не будет работать.

Адресная сущность

@Entity
public class Address {
    @Id
    private int id;
    private String city;
    private String country; 
    @OneToOne(mappedBy="address",cascade=CascadeType.ALL)
    private Customer customer;
    public Address() {
        super();
    }
    ...getters and setters

Клиентская сущность

@Entity
@Table(name="customers")
public class Customer {

    @Id
    private int id;
    @Column(name="first_name")
    private String firstName;
    @Column(name="last_name")
    private String lastName;
    private String gender;

    @Temporal(TemporalType.TIMESTAMP)
    private Date date;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="address_id")
    private Address address;

    public Customer() {
        super();
    }
...getters an setters

Ответы [ 2 ]

1 голос
/ 23 апреля 2020

Добавьте @GeneratedValue в поля идентификатора, чтобы правильно автоматически генерировать идентификаторы сущности. Пожалуйста, измените

@Id
private int id;

на

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)

на обеих ваших сущностях.

Затем в вашем методе mapToEntity добавьте строку:

address.setCustomer(customer);

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

Измените свою Customer сущность, добавив новую переменную поля как addressId

@Entity
@Table(name="customers")
public class Customer {

    @Id
    private int id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    private String gender;

    @Column(name="address_id")
    private int addressId;

    @Temporal(TemporalType.TIMESTAMP)
    private Date date;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="address_id")
    private Address address;

    public Customer() {
        super();
    }
}

и измените EntityDTOMapper, как показано ниже

public Customer mapToEntity(CustomerDto customerDto) {
    Address address=new Address();
    address.setCity(customerDto.getAddressdto().getCity());
    address.setCountry(customerDto.getAddressdto().getCountry());
    address.setId(customerDto.getAddressdto().getId());

    Customer customer=new Customer();
    customer.setId(customerDto.getId());
    customer.setFirstName(customerDto.getFirstName());
    customer.setLastName(customerDto.getLastName());
    customer.setGender(customerDto.getGender());
    customer.setDate(customerDto.getDate());

    customer.setAddressId(customerDto.getAddressdto().getId());
    //customer.setAddress(address);

    return customer;    
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...