P
P
postya2019-04-24 20:16:27
Java
postya, 2019-04-24 20:16:27

How to save text from fields to database with Thymeleaf and Spring Boot?

I'm building a simple web application with SpringBoot. Front end on Thymeleaf. There is a page with fields and a button, when you click on the button, the text from the fields should be saved to the database (I use PostgreSQL)
At the moment, when the application starts, errors immediately appear in the stack trace:
5cc0970b86ae1998163215.jpeg
=============== =================================================
5cc0971154fbe637099072.jpeg
_ ======================================
5cc097174387a480852658.jpeg
How to save information from text fields to the database correctly?
Can you show at least one example of saving from one text field to the database on button click?
My project structure:
5cc097a634afa196282771.jpeg
Car class:

import javax.persistence.*;

@Entity
public class Car {

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

  @Column(name = "vehicle_id")
  private int vehicleID;

  private String color;

  private int year;

  private int seatCapacity;

  private String make;

  private int mileage;

  private double rate;

  public Car() {
  }

  public Car(int vehicleID, String color, int year, int seatCapacity, String make, int mileage, double rate) {
    this.vehicleID = vehicleID;
    this.color = color;
    this.year = year;
    this.seatCapacity = seatCapacity;
    this.make = make;
    this.mileage = mileage;
    this.rate = rate;
  }

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public int getVehicleID() {
    return vehicleID;
  }

  public void setVehicleID(int vehicleID) {
    this.vehicleID = vehicleID;
  }

  public String getColor() {
    return color;
  }

  public void setColor(String color) {
    this.color = color;
  }

  public int getYear() {
    return year;
  }

  public void setYear(int year) {
    this.year = year;
  }

  public int getSeatCapacity() {
    return seatCapacity;
  }

  public void setSeatCapacity(int seatCapacity) {
    this.seatCapacity = seatCapacity;
  }

  public String getMake() {
    return make;
  }

  public void setMake(String make) {
    this.make = make;
  }

  public int getMileage() {
    return mileage;
  }

  public void setMileage(int mileage) {
    this.mileage = mileage;
  }

  public double getRate() {
    return rate;
  }

  public void setRate(double rate) {
    this.rate = rate;
  }
}

CarRepository interface:
import com.kentforth.car.entity.Car;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CarRepository extends CrudRepository<Car, Long> {
}

CarService interface:
import com.kentforth.car.entity.Car;

public interface CarService {

  Iterable<Car> getAllCars();

  Car createCar(Car car);
}

CarServiceImpl class:
import com.kentforth.car.entity.Car;
import com.kentforth.car.repository.CarRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CarServiceImpl implements CarService {

  @Autowired
  private CarRepository carRepository;

  @Override
  public Iterable<Car> getAllCars() {
    return carRepository.findAll();
  }

  @Override
  public Car createCar(Car car) {
    return carRepository.save(car);
  }
}

MainController class:
import com.kentforth.car.entity.Car;
import com.kentforth.car.service.CarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class MainController {

  @Autowired
  private CarService carService;

  @GetMapping("/")
  public String showPage(Model model) {
    return "main";
  }

  @GetMapping("/cars")
  public String getAllCars(@ModelAttribute Car car, Model model) {
    carService.getAllCars();
    model.addAttribute("cars", carService.getAllCars());
    return "cars";
  }

  @PostMapping("/cars")
  public String addCar(@ModelAttribute("car") Car car) {
    carService.createCar(car);
//    model.addAttribute("car", car);
    return "main";
  }
}

html file:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <title>Car Edit</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    </head>
    <body>

        <form class="container mt-md-5 needs-validation"
              data-toggle="validator" novalidate action="#" th:action="@{/cars}" th:object="${car}" method="post">
            <div class="form-row">
                <div class="form-group col-md-6">
                    <label for="vehicleID">VehicleID</label>
                    <input type="number" class="form-control" id="vehicleID" required th:field="*{vehicleID}">
                    <div class="invalid-feedback">
                        Please provide Vehicle ID.
                    </div>
                </div>

                <div class="form-group col-md-6">
                    <label for="color">Color</label>
                    <input type="text" class="form-control" id="color" required th:field="*{color}">
                    <div class="invalid-feedback">
                        Please provide a valid color.
                    </div>
                </div>

                <div class="form-group col-md-6">
                    <label for="year">Year</label>
                    <input type="number" class="form-control" id="year" required th:field="*{year}">
                    <div class="invalid-feedback">
                        Please type year.
                    </div>
                </div>

                <div class="form-group col-md-6">
                    <label for="seat-capacity">Seat Capacity</label>
                    <input type="number" class="form-control" id="seat-capacity" required th:field="*{seatCapacity}">
                    <div class="invalid-feedback">
                        Please provide number of seats.
                    </div>
                </div>

                <div class="form-group col-md-6">
                    <label>Make</label>
                    <select class="custom-select mr-sm-2" required th:field="*{make}">
                        <option value="">Choose...</option>
                        <option value="1">Dodge</option>
                        <option value="2">BMW</option>
                        <option value="3">Honda</option>
                        <option value="4">Tesla</option>
                    </select>
                    <div class="invalid-feedback">Please select make</div>
                </div>

                <div class="form-group col-md-6">
                    <label for="mileage">Current Mileage</label>
                    <input type="number" class="form-control" id="mileage" required th:field="*{mileage}">
                    <div class="invalid-feedback">
                        Please provide a valid mileage.
                    </div>
                </div>

                <div class="form-group col-md-2">
                    <label for="rate">Rate</label>
                    <input type="number" class="form-control" id="rate" required th:field="*{rate}">
                    <div class="invalid-feedback">
                        Please provide rate.
                    </div>
                </div>

            </div>
            <button type="submit" class="btn btn-primary mt-2 col-md-1">Add</button>
            <button type="submit" class="btn btn-success mt-2 ml-3 col-md-2">Show Cars</button>
        </form>


        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
         
    <script src="/validate.js"></script>
    </body>
</html>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Orkhan, 2019-04-25
@postya

Hello!
You are throwing an exception associated with the thymeleaf template engine
+ you did not specify the name attribute for the inputs
And now, a simple example

@Entity
Car {
  
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  	private Long id;

  	private String carModel;

  	private String carName;

  public Car() {}
  //getters & setters & no args constructor
}

<form method="post" th:action="@{/cars/add}">
  
  <input type="text" name="carModel">
  <input type="text" name="carName">
  <input type="submit" value="Добавить машину">

</form>

@Autowired
private CarRepository carRepository

@PostMapping("/cars/add")
public String addNewCar(
 @ModelAttribute("carModel") String carModel,
 @ModelAttribute("carName") String carName,
 Car car
) {
 // тут конечно можно в carService создать метод и передать ему эти аргументы
  car.setCarModel(carModel);
  car.setCarName(carName);
  carRepository.save(car);

  return "main"; 
}

Video - https://www.youtube.com/watch?v=jH17YkBTpI4&list=P...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question