Can not save object to MySQL DB using Java Spring Boot - spring

I've got ENTITY Country with all getters and setters + Constructor with no args. Getters and setter are all written by IDEA, not Lombok.
#Entity
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Country {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String code;
private String capital;
private String description;
private String nationality;
private String continent;
#OneToMany(mappedBy="country")
private List<State> states;
public Country() {
}`
Here goes CountryRepository:
#Repository
public interface CountryRepository extends JpaRepository<Country, Integer> {}
Here goes CountryService:
#Service
public class CountryService {
#Autowired
private CountryRepository countryRepository;
public List<Country> getListOfCountries() {
return countryRepository.findAll();
}
public void addNewCountry(Country country) {
countryRepository.save(country);
}
}
and CountryController:
#Controller
public class CountryController {
#Autowired
private CountryService countryService;
#GetMapping("/countries")
private String getListOfCountries(Model model) {
List<Country> listOfCountries = countryService.getListOfCountries();
model.addAttribute("countries", listOfCountries);
return "countries";
}
#PostMapping("/countries/addNew")
private String addNewCountry(#RequestParam String code,
#RequestParam String capital,
#RequestParam String description,
#RequestParam String nationality,
#RequestParam String continent) {
Country country = new Country();
country.setCode(code);
country.setCapital(capital);
country.setDescription(description);
country.setNationality(nationality);
country.setContinent(continent);
countryService.addNewCountry(country);
return "redirect:/countries";
}
}
and here is the form that's supposed to take input, but unfortunately nothing happens(
<div class="modal-body">
<form th:action="#{/countries/addNew}" method="post">
<div class="form-group">
<label for="recipient-name" class="col-form-label">Code:</label>
<input type="text" class="form-control" id="recipient-name" name="code">
</div>
<div class="form-group">
<label for="recipient-name1" class="col-form-label">Capital:</label>
<input type="text" class="form-control" id="recipient-name1" name="capital">
</div>
<div class="form-group">
<label for="recipient-name2" class="col-form-label">Description:</label>
<input type="text" class="form-control" id="recipient-name2" name="description">
</div>
<div class="form-group">
<label for="recipient-name3" class="col-form-label">Nationality:</label>
<input type="text" class="form-control" id="recipient-name3" name="nationality">
</div>
<div class="form-group">
<label for="recipient-name4" class="col-form-label">Continent:</label>
<input type="text" class="form-control" id="recipient-name4" name="continent">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" data-dismiss="modal">Add</button>
</div>
</form>
</div>
If I add data manually to the DB everything works fine, but when using this form nothing happens. At the same time I didn't get to errors or whatever. Server runs OK. Instead of JPARepository I tried using CRUDRepository. Also doblechecked the names of the form so they have the same values as Country fields. Realy lost here...

Related

Sending new entity object to or DTO to form in Thymeleaf

I would like to what is best practice when creating a form using Thymeleaf. Should I add a new entity or its DTO version to the model that the view containing the form will use, where in the mentioned view I will use th:object. Thank you.
My entity:
#Setter
#Getter
#RequiredArgsConstructor
#Entity
#Table(name = "users")
public class User {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Lob
private Byte[] profilePicture;
private String username;
private String firstName;
private String lastName;
private String email;
private String password;
private String biography;
private LocalDate dateOfBirth;
private String telephoneNumber;
private String city;
private String country;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<Picture> pictures = new ArrayList<>();
}
My DTO:
#Data
#AllArgsConstructor
#NoArgsConstructor
public class UserDTO {
private long id;
private String username;
private String biography;
private String city;
private String country;
private List<PictureDTO> pictures;
private Byte[] profilePicture;
}
My Controller function:
#GetMapping("/user/new")
public String newUser(Model model) {
model.addAttribute("user", new User());
return "user/user-form";
}
My View:
<form class="form-with-previewer" th:object="${user}" th:action="#{/user/}" method="post" enctype="multipart/form-data">
<!-- <input type="hidden" th:field="*{user.id}">-->
<div>
<label for="username"><b>Username</b></label>
<input id="username" type="text" th:field="*{username}">
</div>
<div>
<label for="email"><b>Email</b></label>
<input id="email" type="text" th:field="*{email}">
</div>
<div>
<label for="password"><b>Password</b></label>
<input id="password" type="password" th:field="*{password}">
</div>
<div>
<label><b>Profile picture</b></label>
<input type="file" accept="image/*" name="inpFile" id="inpFile">
<div class="image-preview" id="imagePreview">
<img src="" alt="Image Preview" class="image-preview__image">
<span class="image-preview__default-text">Image Preview</span>
</div>
</div>
<div>
<label for="biography"><b>Biography</b></label>
<input id="biography" type="text" th:field="*{biography}">
</div>
<button type="submit">Submit</button>
</form>

How to iterate and save 2 objects with thymeleaf?

I dont know how fix this error, i saw some articles about that but nothing works.
Error
Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errorsField error in object 'pupil' on field 'curse': rejected value [ModelCurse(id=2, name=PHP, division=2da, pupilList=[], teacherList=[])];
[Failed to convert property value of type 'java.lang.String' to required type 'com.example.administrator.administrator.model.ModelCurse' for property 'curse';
HTML
<form th:action="#{/pupilController/add}" th:object="${pupil}" method="post">
<div class="form-row">
<div class="form-group col-md-6">
<label>Name</label>
<input type="text" class="form-control" th:field="*{name}" placeholder="Name">
</div>
<div class="form-group col-md-6">
<label>Last Name</label>
<input type="text" class="form-control" th:field="*{lastName}" placeholder="Last Name">
</div>
<div class="form-group col-md-6">
<label>Age</label>
<input type="number" class="form-control" th:field="*{age}" placeholder="Age">
</div>
<div class="form-group col-md-6">
<label>Phone Number</label>
<input type="text" class="form-control" th:field="*{phoneNumber}" placeholder="Phone Number">
</div>
<div class="form-group col-md-6">
<select th:field="*{curse}" class="form-control">
<option th:each="curso : ${curses}"
th:value="${curso}"
th:text="${curso.name}"></option>
</select>
</div>
</div>
<input type="submit" name="btnInsert" class="btn btn-primary" value=AƱadir>
</form>
Controller
#GetMapping("/addPupil")
public ModelAndView login(Model model){
ModelAndView mav = new ModelAndView("addpupil");
List<ModelCurse> modelCurses = curseService.getAllCurses();
mav.addObject("pupil",new ModelPupil());
mav.addObject("curses",modelCurses);
return mav;
}
#PostMapping("/add")
public RedirectView addPupil(#ModelAttribute("pupil")ModelPupil modelPupil){
pupilService.addPupil(modelPupil);
return new RedirectView("/pupilController/pupilList");
}
DTO
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#ToString
public class ModelCurse {
private long id;
private String name;
private String division;
private List<ModelPupil> pupilList;
private List<ModelTeacher> teacherList;
}
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#ToString
public class ModelPupil {
private long id;
private String name;
private String lastName;
private int age;
private int phoneNumber;
private ModelCurse curse;
}
When we submit the form, the value of selected option is sent as Text or String in HTTP POST. So, if you are expecting that Spring would automatically convert that String value of curse to object of type ModelCurse, then your assumption is wrong. But Spring does provide us a way to do it using Java beans PropertyEditorSupport. Here you can extend this class, and provide your own implementation on how to convert that String to the required object.

Neither BindingResult nor plain target object for bean name 'user' available as request attribute during form implemetntaion

I am getting this error when I run my Project and I tried all the fixes online but it did not work.
Neither BindingResult nor plain target object for bean name 'user' available as request attribute during form implementation
I am pasting the code below
Do I have to create a table in my database or how do I fix this?
I am trying to read the values entered from the form to another jsp page using spring mvc but without using annotations. And while doing so I am getting this error: Neither BindingResult nor plain target object for bean name 'user' available as request attribute My Controller Class code is as follows:
User.java
package User;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
private Integer age;
private String gender;
private String email;
private String city;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
UserController.java
package Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import User.User;
#Controller
public class UserController {
#Autowired
private UserRepository userRepository;
#GetMapping("/greeting")
public String greetingForm(Model model) {
model.addAttribute("user", new User());
return "greeting";
}
#PostMapping("/greeting")
public String greetingSubmit(#ModelAttribute User user , Model model) {
User newUser = new User();
newUser.setName(user.getName());
newUser.setAge(user.getAge());
newUser.setGender(user.getGender());
newUser.setEmail(user.getEmail());
newUser.setCity(user.getCity());
userRepository.save(user);
return "result";
}
#GetMapping("/all")
public String getMeassage(Model model ) {
Iterable<User> users = userRepository.findAll();
model.addAttribute("users", users);
return "all";
}
}
greeting.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Form Submission</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<br><br>
<h2 style="color:green">Form</h2>
<br><br>
<form class="form-horizontal" role="form" action="#" th:action="#{/greeting}" th:object="${user}" modelAttribute="user" method="post">
<div class="form-group" style="width:300px">
<label for="name" class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<input type="text" th:field="*{name}" class="form-control" id="name" placeholder="Enter name">
</div>
</div>
<div class="form-group" style="width:300px">
<label for="age" class="col-sm-2 control-label">Age</label>
<div class="col-sm-10">
<input type="text" th:field="*{age}" class="form-control" id="age" placeholder="Enter age">
</div>
</div>
<div class="form-group" style="width:300px">
<label for="gender" class="col-sm-2 control-label">Gender</label>
<div class="col-sm-10">
<input type="text" th:field="*{gender}" class="form-control" id="gender" placeholder="Enter gender(M or F)">
</div>
</div>
<div class="form-group" style="width:300px">
<label for="email" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="text" th:field="*{email}" class="form-control" id="email" placeholder="Enter email">
</div>
</div>
<div class="form-group" style="width:300px">
<label for="city" class="col-sm-2 control-label">City</label>
<div class="col-sm-10">
<input type="text" th:field="*{city}" class="form-control" id="city" placeholder="Enter city">
</div>
</div>
<div class="form-group">
<div>
<button type="submit" class="btn btn-primary" id="btn">Submit</button>
<input type="reset" class="btn btn-warning" value="Reset" />
</div>
</div>
</form>
</body>
</html>
Thanks in advance for the help

How to assign entity to another entity in a form using ThymeLeaf?

I am working on MVC Java project and am using Spring Boot with ThymeLeaf. The issue I have is, that when creating a Task, I want to select and save a User, that will be assign to the task. I managed to do the selection correctly, but am unable to save the selected user. It always saves without the User assigned.
Here is my Task entity class:
#Entity
public class Task extends BaseEntity {
private String name;
private String description;
private Date dateOfCreation;
#DateTimeFormat(pattern = "yyyy-MM-dd")
private Date dueDate;
#ManyToOne
private User assignee;
public Task() {
this.dateOfCreation = new Date(System.currentTimeMillis());
}
}
My User entity is as follows:
#Entity
public class User extends BaseEntity {
private String username;
private String password;
#OneToMany(mappedBy = "assignee")
private List<Task> assignedTasks;
}
Where BaseEntity contains
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Version
private Integer version;
My controller function, that is responsible for my taskform.html is:
#RequestMapping("/new")
public String newTask(Model model){
model.addAttribute("task", new Task());
model.addAttribute("users", userService.getAllUsers());
return "task/taskform";
}
And my taskform.html looks like this:
<form class="form-horizontal" th:object="${task}" th:action="#{/task}" method="post">
<input type="hidden" th:field="*{id}"/>
<input type="hidden" th:field="*{version}"/>
<div class="form-group">
<label class="col-sm-2 control-label">Name:</label>
<div class="col-sm-10">
<input type="text" class="form-control" th:field="*{name}"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Description:</label>
<div class="col-sm-10">
<input type="text" class="form-control" th:field="*{description}"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Description:</label>
<div class="col-sm-10">
<input type="date" th:value="*{dueDate}" th:field="*{dueDate}" id="dueDate" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Select user:</label>
<div class="col-sm-10">
<select class="form-control">
<option th:field="*{assignee}" th:each="assignee : ${users}" th:value="${assignee}" th:text="${assignee.username}">
</option>
</select>
</div>
</div>
<div class="row">
<button type="submit" class="btn btn-default">Submit</button>
</div>
I am trying to pass the object from users list as the value, but it does not work Any idea, how to do it?
Showing the users works as expected:
Working frontend
Null is being assigned to assignee column, where the user should be assigned.
Null in H2 Database
EDIT
Here is my POST method from Task Controller:
#RequestMapping(method = RequestMethod.POST)
public String saveOrUpdate(Task task){
taskService.persistTask(task);
return "redirect:/task/list";
}

Spring Boot, Thymeleaf Form Error

I am trying to create a task creation page. There is a form where the user can enter the name, description and task status and save it. However, when I go to the page it shows me this error
There was an unexpected error (type=Internal Server Error, status=500).
Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (index)
I also have a delete task in my program and that seems to work perfectly fine.
This is what my mainController looks like
#RequestMapping(value = "/save-task")
public String saveTask(#ModelAttribute("task") Task task, BindingResult bindingResult, Model model) {
task.setDateCreated(new Date());
taskService.save(task);
model.addAttribute("tasks", taskService.findAll());
model.addAttribute("task", new Task());
model.addAttribute("mode", "MODE_TASKS");
return "index";
}
#RequestMapping( value = "/delete-task")
public String deleteTask(#RequestParam (required = false) int id, Model model){
taskService.delete(id);
model.addAttribute("tasks", taskService.findAll());
model.addAttribute("mode", "MODE_TASKS");
return "index";
}
Here is the form
<div class="container text-center">
<h3>Manage Task</h3>
<hr/>
<form class="form-horizontal" method="POST" th:action="#{/save-task}" th:object="${task}">
<input type="hidden" name="id" th:field="*{id}"/>
<div class="form-group">
<label class="control-label col-md-3">Name</label>
<div class="col-md-7">
<input type="text" class="form-control" name="name" th:field="*{name}"/>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">Description</label>
<div class="col-md-7">
<input type="text" class="form-control" name="description" th:field="*{description}"/>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">Finished</label>
<div class="col-md-7">
<input type="radio" class="col-sm-1" th:name="finished" value="true"/>
<div class="col-sm-1">Yes</div>
<input type="radio" class="col-sm-1" th:name="finished" value="false"/>
<div class="col-sm-1">No</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save"/>
</div>
</div>
</form>
</div>
</div>
Delete Task html
<tr th:each="task: ${tasks}">
<td th:text="${task.id}"></td>
<td th:text="${task.name}"></td>
<td th:text="${task.description}"></td>
<td th:text="${task.dateCreated}"></td>
<td th:text="${task.finished}"></td>
<td><a th:href="#{'delete-task?id=' + ${task.id}}"><span class="glyphicon glyphicon-trash"></span></a> </td>
</tr>
Here is a part of my Task entity
#Entity
#Table(name = "T_TASKS")
public class Task implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private int id;
#Column(name = "NAME")
private String name;
#Column(name = "DESCRIPTION")
private String description;
#Column(name = "DATE_CREATED")
#Temporal(TemporalType.TIMESTAMP)
private Date dateCreated;
#Column(name = "FINISHED")
private boolean finished;
Here is the error in the slack trace
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'task' available as request attribute
Change your controller mapping to accept GET and POST requests. You're getting the error because Spring can't bind a bean to the form. So add a bean when GET is called.
#GetMapping("/save-task")
public String addTask(Model model) {
Task task = new Task();
task.setDateCreated(new Date();
model.addAttribute("task", task);
return "save-task"; //or whatever the page is called
}
Then do your processing:
#PostMapping("/save-task")
public String saveTask(#ModelAttribute("task") Task task,
BindingResult bindingResult,
Model model) {
taskService.save(task);
model.addAttribute("mode", "MODE_TASKS");
return "index";
}
Your bean looks fine. I don't see that you use tasks in your HTML snippet, but that would go in the method mapped with #GetMapping if you're looking to just display all tasks.
Add the following to your controller class:
#ModelAttribute("task")
public Task newTaskObject() {
return new Task();
}
It will solve the binding problem. Also you need a post controller to handle the form submission.

Resources