Search code examples
javahibernatespring-bootdto

Post Method using DTO


I want to use DTO to communicate with the Angular, but actually it doesn't work. I want to create POST request to add data from my application to the database using Dto model.

You can see my errors on the picture: enter image description here

enter image description here

My class Customer:

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

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

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

@OneToMany
private List<Ticket> ticket;
...

Class CustomerDto:

public class CustomerDto {
private String name;
private List<TicketDto> ticket;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public List<TicketDto> getTicket() {
    return ticket;
}

public void setTicket(List<TicketDto> ticket) {
    this.ticket = ticket;
}
}

Class CustomerController:

@Autowired
CustomerService customerService;

@PostMapping(value = "/customers/create")
public Customer postCustomer(@RequestBody CustomerDto customerDto, List<TicketDto> ticketDtos) {
    //ArrayList<TicketDto> tickets = new ArrayList<>();
    ticketDtos.add(customerDto.getName());
    ticketDtos.add(customerDto.getTicket());
    Customer _customer = customerService.save(new Customer(customerDto.getName(), ticketDtos ));
    return _customer;
}

CustomerService:

public interface CustomerService {

void save(CustomerDto customerDto, List<TicketDto> ticketDtos);
}

CustomerServiceImpl:

@Service
public class CustomerServiceImpl implements CustomerService {

@Autowired
CustomerRepository repository;

@Override
public void save(CustomerDto customerDto, List<TicketDto> ticketDtos) {
    Customer customer = new Customer();
    customer.setName(customerDto.getName());
    customer.setTicket(customerDto.getTicket());

    List<Ticket> tickets = new ArrayList<>();
    for (TicketDto ticketDto : ticketDtos) {
        Ticket ticket = new Ticket();
        ticket.setDestinationCity(ticketDto.getDepartureCity());
        ticket.setDestinationCity(ticketDto.getDestinationCity());
        tickets.add(ticket);
    }
}

Solution

  • Since you CustomerServiceImpl is taking CustomerDto and list of TicketDtos, you need to change your method call on controller as below:

    Class CustomerController:

    @Autowired
    CustomerService customerService;
    
    @PostMapping(value = "/customers/create")
    public Customer postCustomer(@RequestBody CustomerDto customerDto) {
        Customer _customer = customerService.save(customerDto));
        return _customer;
    }
    

    And update CustomerServiceImpl as:

    @Service
    public class CustomerServiceImpl implements CustomerService {
    
        @Autowired
        CustomerRepository repository;
    
        // change save to return saved customer
        @Override
        public Customer save(CustomerDto customerDto) {
            Customer customer = new Customer();
            customer.setName(customerDto.getName());
            // customer.setTicket(customerDto.getTicket()); // remove this
    
            List<Ticket> tickets = new ArrayList<>();
            for (TicketDto ticketDto : customerDto.getTicketDtos) {
                Ticket ticket = new Ticket();
                ticket.setDestinationCity(ticketDto.getDepartureCity());
                ticket.setDestinationCity(ticketDto.getDestinationCity());
                tickets.add(ticket);
            }
            customer.setTickets(tickets); // add this to set tickets on customer
            return repository.save(customer);
        }
    

    Obviously, you need to change your interface as well:

    public interface CustomerService {
    
         Customer save(CustomerDto customerDto);
    }