Springs form null values - spring

I have a small problem with my form in spring, it is a simple form with title, username and password, validation works as if I try to submit an empty form I get an error however if I input values in and submit the form, it is submitted but it displays that values inserted are "null".
Domain:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
#NotNull
#Size(min=2, max=30)
private String username;
#NotNull
#Size(min=6)
private String password;
public String getTitle() { return title; }
public String getUsername() { return username; }
public String getPassword() { return password; }
public Long getId() { return id; }
public void setId(Long id) {
this.id = id;
}
public void setUsername(String username) { this.username = username; }
public void setPassword(String password) { this.password = password; }
public void setTitle(String title) { this.title = title; }
public List<Note> getNotes() {
return notes;
}
#OneToMany
private List<Note> notes = new ArrayList<Note>();
}
Form:
<form action="#" th:action="#{/create/user}" th:object="${user}" method="post">
<input type="hidden" th:field="*{id}" />
<p>Title: <input type="text" th:field="*{title}" /></p>
<p>Username: <input type="text" th:field="*{username}" /></p>
<p>Password: <input type="password" th:field="*{password}" /></p>
<p><input type="submit" value="Submit" /></p>
</form>
<div class="form-group">
<ol class="list-group">
<li class="list-group-item list-group-item-info" th:each="user : ${user}">
<span th:text=" ${user.title} + ${user.username} + ${user.password} "></span>
delete
</li>
</ol>
</div>
Controller:
#Controller
public class UserController {
#Autowired
protected UserService userService;
#RequestMapping(value = "/create/user", method = RequestMethod.POST)
public String createUser(Model model, #Valid #ModelAttribute("user") User user, BindingResult bindingResult){
if(bindingResult.hasErrors()){
model.addAttribute("user", user);
model.addAttribute("users", userService.findAll());
model.addAttribute("type", "danger");
model.addAttribute("message", "Please fill in all the fields" +
"Username needs to be at least 2 characters" +
"Passwords needs to contain at least 6 characters");
return "user";
}
userService.save(user);
model.addAttribute("user", new User());
model.addAttribute("cards", userService.findAll());
model.addAttribute("type", "success");
model.addAttribute("message", "A new user has been added");
return "user";
}
If any additional code in needed please let me know, I am still newbie in Spring

Found an error by reviewing the code:
In the form when outputting registered users it was:
<li class="list-group-item list-group-item-info" th:each="user : ${user}">
While it should be:
<li class="list-group-item list-group-item-info" th:each="user : ${users}">

Related

When I put the list with the specific drugs on the controller I have problem but when I put the name of drugs in mySQL I don't have

2023-01-28 13:55:33.706 WARN 17396 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors<EOL>Field error in object 'patient' on field 'drugs': rejected value [panadol]; codes [typeMismatch.patient.drugs,typeMismatch.drugs,typeMismatch.java.util.Set,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [patient.drugs,drugs]; arguments []; default message [drugs]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Set' for property 'drugs'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'panadol'; nested exception is java.lang.NumberFormatException: For input string: "panadol"]]
package com.example.prescription.model;
import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
#Entity
#Table(name = "patients")
public class Patient implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "dob")
private String dateOfBirth;
#NotEmpty(message = "Phone number may not be empty")
#Size(min = 10, max = 10)
#Column(name = "phone")
private String phone;
#NotEmpty(message = "Email may not be empty")
#Size(min = 7, max = 50)
#Column(name = "email")
private String email;
#Column(name = "fathers_name")
private String fathersName;
#Column(name = "mothers_name")
private String mothersName;
#Column(name = "amka")
#Size(min = 11, max = 11)
#Pattern(regexp = "^[0-9]+$", message = "AMKA must contain only numbers")
private String amka;
#Column(name = "id_card")
#Pattern(regexp = "^[a-zA-Z0-9]+$", message = "ID must contain only letters and numbers")
private String idCard;
#Column(name = "city")
private String city;
#Column(name = "postal_code")
#Size(min = 5, max = 5)
#Pattern(regexp = "^[0-9]+$", message = "PC must contain only numbers")
private String postalCode;
#Column(name = "symptoms")
private String symptoms;
#Column(name = "pharmacy")
private String pharmacy;
#Column(name = "doctor_name")
private String doctorsName;
#Column(name = "message")
private String message;
#ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE})
#JoinTable(name = "patient_drug",joinColumns = #JoinColumn(name = "patient_id"),
inverseJoinColumns = #JoinColumn(name = "drug_id"))
private Set<Drug> drugs;
public Patient(Patient patient, Drug drug, Date date) {
}
public Patient() {
}
public void addDrug(Drug drug){
this.drugs.add(drug);
drug.getPatients().add(this);
}
public void removeDrug(Drug drug) {
this.drugs.remove(drug);
drug.getPatients().remove(this);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFathersName() {
return fathersName;
}
public void setFathersName(String fathersName) {
this.fathersName = fathersName;
}
public String getMothersName() {
return mothersName;
}
public void setMothersName(String mothersName) {
this.mothersName = mothersName;
}
public String getAmka() {
return amka;
}
public void setAmka(String amka) {
this.amka = amka;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getSymptoms() {
return symptoms;
}
public void setSymptoms(String symptoms) {
this.symptoms = symptoms;
}
public String getPharmacy() {
return pharmacy;
}
public void setPharmacy(String pharmacy) {
this.pharmacy = pharmacy;
}
public String getDoctorsName() {
return doctorsName;
}
public void setDoctorsName(String doctorsName) {
this.doctorsName = doctorsName;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Set<Drug> getDrugs() {
return drugs;
}
public void setDrugs(Set<Drug> drugs) {
this.drugs = drugs;
}
public void removeDrugs() {
Iterator<Drug> iterator = this.drugs.iterator();
while (iterator.hasNext()) {
Drug drug = iterator.next();
drug.getPatients().remove(this);
iterator.remove();
}
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Patient patient = (Patient) o;
return Objects.equals(id, patient.id) && Objects.equals(firstName, patient.firstName) && Objects.equals(lastName, patient.lastName) && Objects.equals(dateOfBirth, patient.dateOfBirth) && Objects.equals(phone, patient.phone) && Objects.equals(email, patient.email) && Objects.equals(fathersName, patient.fathersName) && Objects.equals(mothersName, patient.mothersName) && Objects.equals(amka, patient.amka) && Objects.equals(idCard, patient.idCard) && Objects.equals(city, patient.city) && Objects.equals(postalCode, patient.postalCode) && Objects.equals(symptoms, patient.symptoms) && Objects.equals(pharmacy, patient.pharmacy) && Objects.equals(doctorsName, patient.doctorsName) && Objects.equals(message, patient.message) && Objects.equals(drugs, patient.drugs);
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("Patient{");
sb.append("id=").append(id);
sb.append(", firstName='").append(firstName).append('\'');
sb.append(", lastName='").append(lastName).append('\'');
sb.append(", dateOfBirth='").append(dateOfBirth).append('\'');
sb.append(", phone='").append(phone).append('\'');
sb.append(", email='").append(email).append('\'');
sb.append(", fathersName='").append(fathersName).append('\'');
sb.append(", mothersName='").append(mothersName).append('\'');
sb.append(", amka='").append(amka).append('\'');
sb.append(", idCard='").append(idCard).append('\'');
sb.append(", city='").append(city).append('\'');
sb.append(", postalCode='").append(postalCode).append('\'');
sb.append(", symptoms='").append(symptoms).append('\'');
sb.append(", pharmacy='").append(pharmacy).append('\'');
sb.append(", doctorsName='").append(doctorsName).append('\'');
sb.append(", message='").append(message).append('\'');
sb.append('}');
return sb.toString();
}
}
package com.example.prescription.controller;
import com.example.prescription.model.Drug;
import com.example.prescription.model.Patient;
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.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import com.example.prescription.service.DrugService;
import com.example.prescription.service.PatientService;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
#Controller
public class PatientController {
private final PatientService patientService;
private final DrugService drugService;
public PatientController(#Autowired PatientService patientService,
#Autowired DrugService drugService) {
this.patientService = patientService;
this.drugService = drugService;
}
//read
#GetMapping("/allPatients")
public String getAllPatients(Model model) {
List<Patient> patientList = patientService.getAllPatients();
model.addAttribute("patientList", patientList);
return "patients";
}
//edit
#GetMapping("/newPatient")
public ModelAndView register() {
ModelAndView mav = new ModelAndView("patientForm");
mav.addObject("patient", new Patient());
mav.addObject("drugs", drugService.getAllDrugs());
return mav;
}
//save
#PostMapping("/patient/save")
public String savePatient(Patient patient) {
patientService.savePatient(patient);
return "redirect:/allPatients";
}
//update
#GetMapping("/editPatient/{id}")
public ModelAndView editPatient(#PathVariable(value = "id") String id) {
ModelAndView mav = new ModelAndView("patientFormEditToUpdate");
Long pid = Long.parseLong(id);
Patient formPatient = patientService.findPatientById(pid);
mav.addObject("patient", formPatient);
return mav;
}
#PostMapping("/updatePatient/patient/{id}")
public String updatePatient(#PathVariable(value = "id") String id, Patient patient) {
Long pid = Long.parseLong(id);
Patient patient1 = patientService.findPatientById(pid);
patient1 = patient;
patientService.updatePatient(patient1);
return "redirect:/allPatients";
}
//delete
#GetMapping("/delete/{id}")
public String deleteById(#PathVariable(value = "id") String id) {
Long pid = Long.parseLong(id);
Patient deletedPatient = patientService.findPatientById(pid);
patientService.deletePatient(deletedPatient);
return "redirect:/allPatients";
}
#GetMapping("/prescribeDrugs/{id}")
public ModelAndView prescribeDrugs(#PathVariable("id") String id) {
Long pid = Long.parseLong(id);
ModelAndView mav = new ModelAndView("patientFormEdit");
Patient formPatient = patientService.findPatientById(pid);
mav.addObject("patient", formPatient);
mav.addObject("drugs", drugService.getAllDrugs());
mav.addObject("drugList",drugList);
return mav;
}
static List<String> drugList= null;
static{
drugList = new ArrayList<>();
drugList.add("depon");
drugList.add("aspirin");
drugList.add("panadol");
}
#PostMapping("/prescribeDrugs/Patient/{id}")
public String prescribePatientDrugs(#Valid Patient patient,String id, #ModelAttribute(value = "drugs")Long drugId ,BindingResult result)
{
if(result.hasErrors())
{
return "patients";
}
try {
Long pId = Long.parseLong(id);
Patient formPatient = patientService.findPatientById(pId);
Drug drug = drugService.findById(drugId);
formPatient.setCity(patient.getCity());
formPatient.setEmail(patient.getEmail());
formPatient.setPhone(patient.getPhone());
formPatient.setSymptoms(patient.getSymptoms());
formPatient.setPharmacy(patient.getPharmacy());
formPatient.setDoctorsName(patient.getDoctorsName());
formPatient.setMessage(patient.getMessage());
Drug patientDrug= new Drug(patient, drug, new Date());
drugService.save(drug);
formPatient.getDrugs().add(patientDrug);
patientService.updatePatient(formPatient);
}catch (NumberFormatException numberFormatException){
System.out.println("error");
}
return "redirect:/allPatients";
}
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link th:href="#{/css/webform.css}" href="/css/webform.css" rel="stylesheet" type="text/css"/>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>Update Patient</title>
</head>
<script type="text/javascript" th:src="#{/js/webform.js}"></script>
<form th:action="#{/prescribeDrugs/Patient/{id}(id = ${patient.id})}" method="post" th:object="${patient}">
<div class="container prescription-form">
<div class="row">
<div class="col-lg-12 col-12">
<form>
<h1>Electronic Prescription Form</h1>
<div class="row">
<div class="col-lg-6 col-12">
<label>
<span>Patient Name</span><input type="text" th:value="${patient.firstName}"
th:name="firstName" disabled/>
</label>
</div>
<div class="col-lg-6 col-12">
<label>
<span>Patient Email</span><input id="email" type="text" th:value="${patient.email}"
th:name="email"/>
</label>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-12">
<label>
<span>Patient Surname</span><input id="surname" type="text"
th:value="${patient.lastName}" th:name="surname"
disabled/>
</label>
</div>
<div class="col-lg-6 col-12">
<label>
<span>Patient Phone</span><input id="phone" type="text" th:value="${patient.phone}"
th:name="phone"/>
</label>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-12">
<label>
<span>Patient Symptoms</span><input id="symptoms" type="text" th:name="symptoms"
required/>
</label>
<span class="error_message">This field is required</span>
</div>
<span class="error_message">This field is required</span>
</div>
<div class="col-lg-6 col-12" >
<label>
<span>Drug*</span>
<select name="drugs">
<option th:each="drug : ${drugList}"
th:text="${drug}">
</select>
</label>
<span class="error_message">This field is required</span>
</div>
<div class="row">
<div class="col-lg-6 col-12">
<label>
<span>AMKA</span><input id="amka" type="text" th:value="${patient.amka}" th:name="amka"
disabled/>
</label>
</div>
<div class="col-lg-6 col-12">
<label>
<span>Patient ID</span><input id="patient_id" type="text" th:value="${patient.idCard}"
th:name="patient_id" disabled/>
</label>
<span class="error_message">This field is required</span>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-12">
<div class="message pharmacy">
<label class="miniTextfield">
<span>Pharmacy to deliver</span><textarea id="pharmacy" th:name="pharmacy" required></textarea>
</label>
<span class="error_message">This field is required</span>
</div>
</div>
<div class="col-lg-6 col-12">
<div class="message signature">
<label class="miniTextfield">
<span>Doctor Signature</span><textarea id="doctorSignature" th:name="doctorsName" required></textarea>
</label>
<span class="error_message">This field is required</span>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-12">
<label>
<span>City</span><input id="city" type="text" th:value="${patient.city}" th:name="city"
/>
</label>
</div>
</div>
<div class="message">
<div class="col-lg-12 col-12">
<label class="message_btn_wrapper">
<span>Message</span><textarea id="feedback" th:name="message"></textarea>
<input type="submit" value="Submit Form"/>
<div class="requiredMessage">Fields with * are mandatory</div>
</label>
</div>
</div>
</form>
</div>
</div>
</div>
</form>
In your controller, you are adding a list of Drug objects of type String, and they are not of type Drug. Your Patient is expecting a Set of Drug objects.
You have several other issues in this code too, but create a new Set of Drug objects, either using a constructor directly or using a Builder pattern.
E.g.: like:
Set.of(new Drug("depon"), new Drug("aspirin"), new Drug("panadol"));
But adjusted for your Drug constructor.
Take a look at my public repo for some working code.
https://github.com/vphilipnyc/For_Vasileios_Maziotis

How to populate dropdown list from one entity class to another in spring-boot?

Customer.java file
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String relative;
private String address;
private Long aadhar;
private Long contact;
public Long getAadhar() {
return aadhar;
}
public void setAadhar(Long aadhar) {
this.aadhar = aadhar;
}
#ManyToOne
#JoinColumn(name="town_name",insertable = false,updatable = false)
private Town town;
private String town_name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRelative() {
return relative;
}
public void setRelative(String relative) {
this.relative = relative;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Town getTown() {
return town;
}
public void setTown(Town town) {
this.town = town;
}
public String getTown_name() {
return town_name;
}
public void setTown_name(String town_name) {
this.town_name = town_name;
}
public Long getContact() {
return contact;
}
public void setContact(Long contact) {
this.contact = contact;
}
}
Town.Java
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Town {
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Id
private String townname;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTownname() {
return townname;
}
public void setTownname(String townname) {
this.townname = townname;
}
}
CustomerController.java file
#Controller
public class CutomerController {
#Autowired
private CutomerService customerService;
#GetMapping("/customer")
public String findAllCustomers(Model model) {
model.addAttribute("customers", customerService.findAllCustomers());
return "customer";
}
#PostMapping("/customer/addnew")
public String addNew(Customer customer) {
customerService.saveCustomer(customer);
return "redirect:/customer";
}
}
TownController.java file
#Controller
public class TownController {
#Autowired
private TownService townService;
#GetMapping("/town")
public String findAllTowns(Model model) {
model.addAttribute("towns", townService.findAllTown());
return "town";
}
}
My customer.html file
<!-- Multi Columns Form -->
<form class="row g-3" th:action="#{/customer/addnew}" method="post">
<div class="col-md-4">
<label for="aadhar" class="form-label">Aadhar No.</label>
<input type="number" min="0" max="999999999999" class="form-control" id="aadhar">
</div>
<div class="col-md-8">
<label for="customername" class="form-label">Customer Name</label>
<input type="text" class="form-control" id="name"onKeyup="this.value = this.value.toUpperCase()" required>
</div>
<div class="col-md-6">
<label for="relative" class="form-label">S/O,D/O,C/O</label>
<input type="text" class="form-control" id="relative"onKeyup="this.value = this.value.toUpperCase()" required>
</div>
<div class="col-md-6">
<label for="contact" class="form-label">Contact No.</label>
<input type="number" max="9999999999" class="form-control" id="contact">
</div>
<div class="col-12">
<label for="inputAddress5" class="form-label">Address</label>
<input type="text" class="form-control" id="address"onKeyup="this.value = this.value.toUpperCase()" placeholder="1234 Main St" required>
</div>
<div class="col-md-4">
<label for="inputTown" class="form-label" id="selecttown">Town/Area</label>
<select class="form-control" id="selecttown" name="townname" th:field="*{townname}" required>
<option selected>Choose...</option>
<option th:each="town:${towns}" th:value="${town.towname}" th:text="${town.towname}"></option>
</select>
</div>
<div class="text-center" style="margin-bottom:10px">
<button type="submit" class="btn btn-primary mx-1 my-1">Submit</button>
i am expecting populate the names of towns in dropdown list of customer modal form. But i am getting this error
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Nov 30 12:18:23 IST 2022
There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/customer.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/customer.html]")
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring6.processor.SpringSelectFieldTagProcessor' (template: "customer" - line 473, col 70)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring6.processor.SpringSelectFieldTagProcessor' (template: "customer" - line 473, col 70)
Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'townname' available as request attribute
Your are referencing wrong variable.
Modify your CustomerController class like this:
#Autowired
private CutomerService customerService;
#Autowired
private TownService townService;
#GetMapping("/customer")
public String findAllCustomers(Model model) {
model.addAttribute("customers", customerService.findAllCustomers());
model.addAttribute("towns", townService.findAllTown());
return "customer";
}
#PostMapping("/customer/addnew")
public String addNew(Customer customer) {
customerService.saveCustomer(customer);
return "redirect:/customer";
}

How to create java spring-mvc form with hibernate #OneToOne,#ManyToOne... annotations with #ModelAttribute

I want to create a controller with #ModelAttribute which allows me to insert to my Customer table data. I've done one with the employee but how can I save two hibernate mapped entities in JSP form with #ModelAttribute? also, I'm using basic generated repositories with JpaRepository interface. I want to make those two entities in relation saving it.
I tried to make #ModelAttribute JSP forms, but I don't know how to set other table entity in relation.
Employee
#Entity
#Table
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
#Digits(integer = 10, fraction = 0, message = "Must be a digit")
private Integer age;
private BigDecimal salary;
#Temporal(TemporalType.DATE)
#DateTimeFormat(pattern = "yyyy-MM-dd")
#PastOrPresent(message = "Date must be past or present")
private Date birthDate;
#Temporal(TemporalType.DATE)
#DateTimeFormat(pattern = "yyyy-MM-dd")
#PastOrPresent(message = "Date must be past or present")
private Date hireDate;
private boolean sex; //false - woman, true - man
#OneToOne(mappedBy = "employee")
private Address address;
public Employee() {
}
public Employee(String firstName, String lastName, Integer age, BigDecimal salary, Date birthDate, Date hireDate,
boolean sex) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.salary = salary;
this.birthDate = birthDate;
this.hireDate = hireDate;
this.sex = sex;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public BigDecimal getSalary() {
return salary;
}
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public Date getHireDate() {
return hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address
#Entity
#Table
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String country;
private String city;
private String street;
private Integer houseNumber;
private Integer local;
private String postalCode;
#OneToOne
#JoinColumn(name = "employee_id")
private Employee employee;
public Address() {
}
public Address(String country, String city, String street, Integer houseNumber, Integer local, String postalCode) {
this.country = country;
this.city = city;
this.street = street;
this.houseNumber = houseNumber;
this.local = local;
this.postalCode = postalCode;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public Integer getHouseNumber() {
return houseNumber;
}
public void setHouseNumber(Integer houseNumber) {
this.houseNumber = houseNumber;
}
public Integer getLocal() {
return local;
}
public void setLocal(Integer local) {
this.local = local;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}
Controller
#Controller
#RequestMapping("/user")
public class UserController {
#Autowired
public EmployeeService employeeService;
#Autowired
public AddressService addressService;
#GetMapping("/add")
public String addUser(Model model) {
model.addAttribute("employee", new Employee());
return "user/addEmployee";
}
#PostMapping("/add")
public String postAddUser(#Valid #ModelAttribute("employee") Employee employee, BindingResult bs) {
if(bs.hasErrors()) {
return "user/addAddress";
} else {
employeeService.saveOrUpdate(employee);
return "user/success";
}
}
#GetMapping("/address/add")
public String addAddress(Model model) {
List<Employee> employees = employeeService.findAll();
model.addAttribute("employees", employees);
model.addAttribute("address", new Address());
return "user/addAddress";
}
#PostMapping("/address/add")
public String postAddAddress(#ModelAttribute("address") Address address, #RequestParam("employee_id") Long id) {
Employee employee = employeeService.findById(id);
address.setEmployee(employee);
employee.setAddress(address);
addressService.saveOrUpdate(address);
employeeService.saveOrUpdate(employee);
return "user/addAddress";
}
}
addAddress.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head></head>
<body>
<h2>Address Form</h2>
<form:form action="/user/address/add" method="POST" modelAttribute="address">
City: <form:input path="city"/><br>
Street: <form:input path="street" /><br>
House Number: <form:input path="houseNumber"/><br>
Local: <form:input path="local"/><br>
Postal Code: <form:input path="postalCode" /><br>
<select name="employee_id">
<c:forEach var="employee" items="${employees}">
<option value="${employee.id}">${employee.id} ${employee.firstName} ${employee.lastName}</option>
</c:forEach>
</select><br>
<input type="submit" />
</form:form>
</body>
</html>
addEmployee.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head></head>
<body>
<h2>Employee Form</h2>
<form:form action="/user/add" method="POST" modelAttribute="employee">
First Name: <form:input path="firstName"/> <form:errors path="firstName"></form:errors><br>
Last Name: <form:input path="lastName"/> <form:errors path="lastName"></form:errors><br>
Age: <form:input path="age" /> <form:errors path="age" type="number"></form:errors><br>
Salary: <form:input path="salary" type="number"/> <form:errors path="salary"></form:errors><br>
Birth Date<form:input path="birthDate" type="date"/> <form:errors path="birthDate"></form:errors><br>
Hire Date<form:input path="hireDate" type="date" /> <form:errors path="hireDate"></form:errors><br>
Female: <form:radiobutton path="sex" value="0" /> Male: <form:radiobutton path="sex" value="1" /><br>
<input type="submit" value="Wyślij"/>
</form:form>
</body>
</html>
I need to create a result in the database with those two entities with a relationship using #ModelAttribute. Is it possible?
If I understood your problem correctly,
To set the associated entity -
you need to have unique value to identify the entity (for ex. Employeeid for employees),
fetch the details for the Employeeid, this will result in employee entity object
set the employee entity object into customer entity object
similarly for Invoices.
then save customer entity object.
Check - https://thoughts-on-java.org/ultimate-guide-association-mappings-jpa-hibernate/
You could try to combine them something like this:
<form:form action="add" method="POST" modelAttribute="employee">
<form:hidden path="id"/>
First Name: <form:input path="firstName"/> <form:errors path="firstName"></form:errors><br>
Last Name: <form:input path="lastName"/> <form:errors path="lastName"></form:errors><br>
Age: <form:input path="age" /> <form:errors path="age" type="number"></form:errors><br>
Salary: <form:input path="salary" type="number"/> <form:errors path="salary"></form:errors><br>
Birth Date<form:input path="birthDate" type="date"/> <form:errors path="birthDate"></form:errors><br>
Hire Date<form:input path="hireDate" type="date" /> <form:errors path="hireDate"></form:errors><br>
Female: <form:radiobutton path="sex" value="0" /> Male: <form:radiobutton path="sex" value="1" /><br>
<form:form action="add" method="POST" modelAttribute="address">
<form:hidden path="addressId"/> // <- need to rename in your entity Address class
City: <form:input path="city"/><br>
Street: <form:input path="street" /><br>
House Number: <form:input path="houseNumber"/><br>
Local: <form:input path="local"/><br>
Postal Code: <form:input path="postalCode" /><br>
<select name="employee_id">
<c:forEach var="employee" items="${employees}">
<option value="${employee.id}">${employee.id} ${employee.firstName} ${employee.lastName}</option>
</c:forEach>
</select><br>
<input type="submit" value="Submit"/>
</form:form>
<input type="submit" />
</form:form>
In controller method:
#PostMapping("/add")
public String postAdd(#ModelAttribute("employee") #Valid Employee employee
BindingResult empBindingResult,
#ModelAttribute("address") Address address,
BindingResult addressBindingResult) {
// other code
}
Although I didn't use radiobutton and selector elements in this combination, the rest of code should work fine.
Spring MVC Multiple ModelAttribute On the Same Form
Multiple modelattributes in a JSP with Spring

get selected value in controller - jsp/spring

I am trying to pass value from in jsp to POST controller.
i have the controller get:
#RequestMapping(value = "/matches/{pageNumber}/", method = RequestMethod.GET)
public String games( #PathVariable Integer pageNumber, Model model ) {
....
//build map for dropdown compatitions
HashMap<Integer, String> leaguesMap = new HashMap<Integer, String>();
leaguesMap.put(1, "Top Leagues");
leaguesMap.put(2, "All");
for (Competition competition : competitions) {
if(!leaguesMap.containsKey(competition.getApiId())){
leaguesMap.put(competition.getApiId(), competition.getName());
}
}
model.addAttribute("leaguesMap", leaguesMap);
.....
return "upcomingMatches";
}
And then in jsp:
<form:form modelAttribute="leaguesMap" action="drop" class="dropdown-leagues" method="POST">
<form:select path="${leaguesMap.value}" id="league-selection" onchange="this.form.submit()" class="form-control select-filter select2-hidden-accessible" aria-hidden="true">
<form:options items="${leaguesMap}" />
</form:select>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form:form>
I am trying to get the selected value in POST controller:
#RequestMapping(value = "/matches/{pageNumber}/drop", method = RequestMethod.POST)
public String games( #ModelAttribute("leaguesMap") String leaguesMap, #PathVariable Integer pageNumber, BindingResult result) {
String fff = leaguesMap;
System.out.println("asadasdadsa"+fff);
return "redirect:/matches/{pageNumber}/";
}
But getting always null.
If you can give me direction how to proceed , it will be great.
Thanks!
Create a model class League.class
public class League {
private Integer id;
private String name;
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;
}
}
Change your get controller:
#RequestMapping(value = "/matches/{pageNumber}/", method = RequestMethod.GET)
public String games( #PathVariable Integer pageNumber, Model model ) {
....
//build map for dropdown compatitions
HashMap<Integer, String> leaguesMap = new HashMap<Integer, String>();
leaguesMap.put(1, "Top Leagues");
leaguesMap.put(2, "All");
for (Competition competition : competitions) {
if(!leaguesMap.containsKey(competition.getApiId())){
leaguesMap.put(competition.getApiId(), competition.getName());
}
}
model.addAttribute("leaguesMap", leaguesMap);
model.addAttribute("league", new League());
.....
return "upcomingMatches";
}
Change your jsp:
<form:form modelAttribute="league" action="drop" class="dropdown-leagues" method="POST">
<form:select path="id" id="league-selection" onchange="this.form.submit()" class="form-control select-filter select2-hidden-accessible" aria-hidden="true">
<form:options items="${leaguesMap}" />
</form:select>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form:form>
And finally your post controller:
#RequestMapping(value = "/matches/{pageNumber}/drop", method = RequestMethod.POST)
public String games( #ModelAttribute("league") League league, #PathVariable Integer pageNumber, BindingResult result) {
System.out.println("asadasdadsa" + league.getId());
return "redirect:/matches/{pageNumber}/";
}

Spring MVC Pre Populate Checkboxes

First little background info. Got a fairly standard User Role relationship where the User can have many roles. I have roles defined as a set within the user class. Now I know that html forms have all the values as strings and trying to get values as my custom Role object does not work. I implemented an initbinder to convert the id's back into object so that I can retrieve the selected values off of my checkboxes, that part works.
But I can't seem to go back the other way. I retrieve a User from the database that already has roles and want to pre populate role checkboxes with all the roles that a user has. Based on this example :
Checkboxes example
They say that:
form:checkboxes items="${dynamic-list}" path="property-to-store"
For multiple checkboxes, as long as the “path” or “property” value is
equal to any of the “checkbox values – ${dynamic-list}“, the matched
checkbox will be checked automatically.
My interpretation of that is I should be able to feed it a Set of all the roles and define the path to be the roles from the User object and it should match them thus causing the check box to pre populate.
Every example out there seems to have the value of dynamic-list as a String[]. Well thats great and dandy but how does this work for custom objects that our defined as a Set? Can I still use this one line definition for checkboxes or do I need to do some kind of data binding heading into the view also?
Here is my user dto, user controller, custom form binder, and user edit page.
User DTO
#Entity
#Table
public class User extends BaseDto
{
#Column(updatable = false) #NotBlank
private String username;
#Column(name = "encrypted_password") #Size(min = 6, message = "password must be at least 6 characters") #Pattern(regexp = "^\\S*$", message = "invalid character detected")
private String password;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column #NotNull
private boolean enabled;
#Column #Email #NotBlank
private String email;
#Transient
private String confirmPassword;
#ManyToMany(targetEntity = Role.class, fetch = FetchType.EAGER, cascade = CascadeType.REFRESH) #JoinTable(name = "user_role", joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles;
public User()
{
}
public User(final String usernameIn, final String passwordIn, final String firstNameIn, final String lastNameIn, final String emailIn, final boolean enabledIn)
{
username = usernameIn;
password = passwordIn;
firstName = firstNameIn;
lastName = lastNameIn;
email = emailIn;
enabled = enabledIn;
}
public String getUsername()
{
return username;
}
public void setUsername(final String usernameIn)
{
username = usernameIn;
}
public String getPassword()
{
return password;
}
public void setPassword(final String passwordIn)
{
password = passwordIn;
}
public String getFirstName()
{
return firstName;
}
public void setFirstName(final String firstNameIn)
{
firstName = firstNameIn;
}
public String getLastName()
{
return lastName;
}
public void setLastName(final String lastNameIn)
{
lastName = lastNameIn;
}
public String getEmail()
{
return email;
}
public void setEmail(final String emailIn)
{
email = emailIn;
}
public String getConfirmPassword()
{
return confirmPassword;
}
public void setConfirmPassword(final String confirmPasswordIn)
{
confirmPassword = confirmPasswordIn;
}
public boolean isEnabled()
{
return enabled;
}
public void setEnabled(final boolean enabledIn)
{
enabled = enabledIn;
}
public Set<Role> getRoles()
{
return roles;
}
public void setRoles(final Set<Role> rolesIn)
{
roles = rolesIn;
}
}
User Controller
#Controller #RequestMapping("/user")
public class UserController
{
#Autowired private UserService userService;
#Autowired private UserDao userDao;
#Autowired private RoleDao roleDao;
#InitBinder
public void bindForm(final WebDataBinder binder)
{
binder.registerCustomEditor(Set.class, "roles", new CustomFormBinder<RoleDao>(roleDao, Set.class));
}
#RequestMapping(method = RequestMethod.GET)
public String index(final ModelMap modelMap)
{
return "/user/index";
}
#RequestMapping(value = "/create", method = RequestMethod.GET)
public String create(final ModelMap modelMap)
{
modelMap.addAttribute("userInstance", new User());
modelMap.addAttribute("validRoles", new HashSet<Role>(roleDao.findAll()));
return "/user/create";
}
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(final ModelMap modelMap, #Valid #ModelAttribute("userInstance") final User user, final BindingResult bindingResult)
{
// TODO move to service validation
if (user.getPassword() == null || !user.getPassword().equals(user.getConfirmPassword()) )
{
bindingResult.addError(new FieldError("userInstance", "password", "password fields must match"));
bindingResult.addError(new FieldError("userInstance", "confirmPassword", "password fields must match"));
}
if (user.getRoles() == null || user.getRoles().isEmpty())
{
bindingResult.addError(new FieldError("userInstance", "roles", "Must select at least one role for a User"));
}
if (bindingResult.hasErrors())
{
modelMap.addAttribute("validRoles", new HashSet<Role>(roleDao.findAll()));
return "/user/create";
}
userService.save(user);
return "redirect:/user/list";
}
#RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
public String edit(#PathVariable final Integer id, final ModelMap modelMap)
{
final User user = userDao.find(id);
if (user != null)
{
modelMap.addAttribute("userInstance", user);
modelMap.addAttribute("validRoles", new HashSet<Role>(roleDao.findAll()));
return "/user/edit";
}
return "redirect:/user/list";
}
#RequestMapping(value = "/edit", method = RequestMethod.GET)
public String editCurrent(final ModelMap modelMap)
{
return edit(userService.getLoggedInUser().getId(), modelMap);
}
#RequestMapping(value = "/update", method = RequestMethod.POST)
public String update(#Valid #ModelAttribute("userInstance") final User user, final BindingResult bindingResult)
{
if (bindingResult.hasErrors())
{
return "/user/edit";
}
userService.save(user);
return "redirect:/user/list";
}
#ModelAttribute("userInstances")
#RequestMapping(value = "/list", method = RequestMethod.GET)
public List<User> list()
{
return userDao.findAll();
}
}
Custom Form Binder
public class CustomFormBinder<T extends GenericDao> extends CustomCollectionEditor
{
private final T dao;
private static final Logger LOG = LoggerFactory.getLogger(CustomFormBinder.class);
public CustomFormBinder(final T daoIn, final Class collectionType)
{
super(collectionType, true);
dao = daoIn;
}
#Override
protected Object convertElement(final Object element)
{
try
{
// forms should return the id as the itemValue
return dao.find(Integer.valueOf(element.toString()));
}
catch (NumberFormatException e)
{
LOG.warn("Unable to convert " + element + " to an integer");
return null;
}
}
}
User Edit View
<html>
<head>
<title>Create User</title>
</head>
<body>
<c:url value="/user/update" var="actionUrl"/>
<form:form method="post" commandName="userInstance" action="${actionUrl}">
<h1>Edit User ${userInstance.username}</h1>
<div>
<form:label path="username">Username:</form:label>
<form:input path="username" id="username" readonly="true"/>
</div>
<div>
<form:label path="password">Password:</form:label>
<form:input path="password" id="password" type="password" readonly="true"/>
<tag:errorlist path="userInstance.password" cssClass="formError"/>
</div>
<div>
<form:label path="firstName">First Name:</form:label>
<form:input path="firstName" id="firstName"/>
<tag:errorlist path="userInstance.firstName" cssClass="formError"/>
</div>
<div>
<form:label path="lastName">Last Name:</form:label>
<form:input path="lastName" id="lastName"/>
<tag:errorlist path="userInstance.lastName" cssClass="formError"/>
</div>
<div>
<form:label path="email">Email:</form:label>
<form:input path="email" id="email" size="30"/>
<tag:errorlist path="userInstance.email" cssClass="formError"/>
</div>
<div>
**<%--Want to Pre Populate these checkboxed--%>
<form:checkboxes title="Assigned Roles:" path="roles" id="roles" items="${validRoles}" itemLabel="displayName" itemValue="id" element="div"/>**
<tag:errorlist path="userInstance.roles" cssClass="formError"/>
</div>
<form:hidden path="enabled"/>
<form:hidden path="id"/>
<form:hidden path="version"/>
<div class="submit">
<input type="submit" value="Update"/>
Cancel
</div>
</form:form>
</body>
</html>
You need a correct implemented equals method for Role!
If this is not enough have a look at class oorg.springframework.web.servlet.tags.form.AbstractCheckedElementTag. The method void renderFromValue(Object item, Object value, TagWriter tagWriter) is where the the checked flag is set.

Resources