Answer the question
In order to leave comments, you need to log in
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:
=============== =================================================
_ ======================================
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:
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;
}
}
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> {
}
import com.kentforth.car.entity.Car;
public interface CarService {
Iterable<Car> getAllCars();
Car createCar(Car car);
}
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);
}
}
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";
}
}
<!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
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";
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question