Ad

Failed To Convert Value Of Type 'java.lang.String' To Required Type 'java.sql.Date'

There is a Spring MVC app where the customer has the option to place an order. You can set the date and time of the order in the order. I don't have a frontend at all so I'm testing methods via swagger. When I enter a date in the swagger field how should it be stored in the database by default 2020-03-11 09:25:00.000000 returns a json error, and in the application console, it issues a warning. I don't know what to do. Please help me solve this problem.

JSON:

{
  "timestamp": "2020-05-21T07:57:50.511+0000",
  "status": 400,
  "error": "Bad Request",
  "message": "Failed to convert value of type 'java.lang.String' to required type 'java.sql.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.sql.Date] for value '2020-03-11 09:25:00.000000'; nested exception is java.lang.IllegalArgumentException",
  "path": "/customer/make/order"
}

Class Order:

import java.sql.Date;

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

    public Order() { 

    }


    // Поля
    private @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    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)
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private Customer customer;


    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "basket_id", referencedColumnName = "id") // Join without Cook in User class
    private Basket basket;


    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private Cook cook;
}

CustomerService:

public void makeOrder(String address, String phoneNumber,
                          Long cookId, Long basketId, Date dateInput) {

        double coast = calculateCoast(basketId);

        Customer customer = customerRepository
                .findByIdAndUserRole(User.getCurrentUser().getId(), User.ROLE_CUSTOMER);

        if (coast <= customer.getWallet()) {
            customer.setWallet(customer.getWallet() - coast);
        } else {
            throw new MainIllegalArgument("There is not enough money in the account!");
        }

        Order order = new Order();
        order.setPhoneNumber(phoneNumber);
        order.setAddress(address);
        java.sql.Date date= new java.sql.Date((dateInput).getTime());
        order.setDateOrder(date);
        order.setOrderStatus(true);
        order.setCustomer(customerRepository.findByIdAndUserRole(User.getCurrentUser().getId(), User.ROLE_CUSTOMER));
        order.setCook(cookRepository.findByIdAndUserRole(cookId, "COOK"));
        order.setBasket(basketRepository.getById(basketId));
        orderRepository.save(order);
    }

CustomerController:

@PostMapping("/make/order")
    public void makeOrder(String address, String phoneNumber,
                          Long cookId, Long basketId, Date dateInput) {

        customerService.makeOrder(address, phoneNumber, cookId, basketId, dateInput);
    }

My Test datas: enter image description here

Im ny project I use: Spring Boot + Spring MVC + Spring Security + Jpa + Hibernate + PostgreSQL

Ad

Answer

You are missing the @Temporal annotation at your date fields

@Column(name = "date_order")
@Temporal(TemporalType.TIMESTAMP)
private Date dateOrder;

Temporal.DATE : This provides the SQL Date without the time Temporal.TIME : Provides the time of the day with hours minutes and seconds Temporal.TIMESTAMP : Provides the timestamp (date and time ) SQL type upto nanosecond precision

You can do the conversion at the controller level

   @PostMapping("/make/order")
   public void date(@RequestParam("dateInput") 
      @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date dateInput, //other request params.) {
        // Call to service.
    }

You can use your own format as well @DateTimeFormat(pattern="yyyy-MM-dd") Date fromDate Or you can format the date in your service layer. For more information, read here.

Ad
source: stackoverflow.com
Ad