Save a form in jsp with dropdown listfrom from database in Spring MVC - spring

I'm trying to save Account object in the hibernate .please find the following code.
#RequestMapping(value = "/saveAccount", method = RequestMethod.POST)
public ModelAndView saveAccount(#ModelAttribute("account") Account account,
BindingResult result) {
Session session = sessionFactory.openSession();
System.out.println(account.getFirstName());
System.out.println(account.getLastName());
System.out.println(account.getSubject());
System.out.println(account.getCity().getCityName());
session.save(account);
return new ModelAndView("redirect:/form.html");
}
My jsp page have a form with First Name,Last Name ,city and subject fields.
I'm getting city dropdown fromatabase.
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib
prefix="c"
uri="http://java.sun.com/jsp/jstl/core"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h3>Contact Form</h3>
<div class="container">
<form method="post" action="/sdnext/saveAccount.html">
<label for="fname">First Name</label>
<input type="text" id="fname" name="firstName" placeholder="Your name..">
<label for="lname">Last Name</label>
<input type="text" id="lname" name="lastName" placeholder="Your last name..">
<label for="country">City</label>
<select name="city" id="cityName" >
<c:forEach var="cityname" items="${lists}">
<option value="${cityname.cityName}">${cityname.cityName}</option>
</c:forEach>
</select>
<label for="subject">Subject</label>
<textarea id="subject" name="subject" placeholder="Write something.." style="height:200px"></textarea>
<input type="submit" value="Submit">
</form>
</div>
</body>
</html>
DataBase bean classes are here
package test.*;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name= "Account")
public class Account implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
public int getId() {
return id;
}
public void setId(int 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) {
LastName = lastName;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
private String firstName;
private String LastName;
#OneToOne
private City city;
private String subject;
}
package test.*;
#Entity
#Table(name= "City")
public class City implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private String cityName;
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
}
I have used one to one mapping to city object.But i'm not able to save city object in database,rest all firstNme,LastName and subjects are getting saved.its showing in network console,but data is not getting saved in database.Please help me fix this.Thanking you..

By creating the dto we can persists the values selected from the dropdown.and its working for me .

<option value="${cityname}">${cityname.cityName}</option>
The problem is you are sending cityname.cityName (String) which cannot be mapped to City object so,
send the complete city object as the value. Hibernate will take care of mapping.

Related

Problem with populating a dropdown list ManyToOne - Spring

I have a problem populating a drop down list with a ManyToOne relationship.
I have two entities, Product referencing Category with Category ID ...
But I can't populate the category list with the Spring form tag and get the pointer to the category in the product table of the database.
Can anyone kindly explain to me how to solve this problem?
DB Product Category Structure
JSP Form Output
PRODUCT CLASS
package it.relazioni.one;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(length = 100, nullable = false)
private String nameProduct;
#Column
private int price;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "idCategory")
private Category category;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNameProduct() {
return nameProduct;
}
public void setNameProduct(String nameProduct) {
this.nameProduct = nameProduct;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}
CATEGORY CLASS
package it.relazioni.one;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Category {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(length = 45, nullable = false, unique = true)
private String nameCategory;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNameCategory() {
return nameCategory;
}
public void setNameCategory(String nameCategory) {
this.nameCategory = nameCategory;
}
public Category(Integer id, String nameCategory) {
super();
this.id = id;
this.nameCategory = nameCategory;
}
public Category(Integer id) {
super();
this.id = id;
}
public Category(String nameCategory) {
super();
this.nameCategory = nameCategory;
}
}
CONTROLLER CODE
#GetMapping("/createProd")
public ModelAndView createProduct(#ModelAttribute("newProduct") Product p, Model model) {
List<Category> categories = (List<Category>) catRep.findAll();
model.addAttribute("categories", categories);
return new ModelAndView("createProduct", "newProduct", new Product());
}
#PostMapping("/createProductForm")
public ModelAndView createProductForm(#ModelAttribute("newProduct") Product p) {
System.out.println(p.getNameProduct() + " " + p.getCategory());
pdRep.save(p);
return new ModelAndView("createProduct", "newProduct", p);
}
JSP CODE
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form:form action="createProductForm" method="post" modelAttribute="newProduct">
<form:input path="nameProduct"/>
<form:input path="price" type="number"/>
<form:select path="category">
<form:options items="${categories}"></form:options>
</form:select>
<form:button>Create Product!</form:button>
</form:form>
</body>
</html>

Cannot resolve 'name'

Hi all, I'm currently doing a crud app using spring mvc, hibernate and thymeleaf. I am trying to create a new user but the compiler is complaining that it can't recognize the name field, even though I have this field in the User class. What can be the problem?
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>New User</title>
</head>
<body>
<form th:method="POST" th:action="#{/users}" th:object="${user}">
<input type="text" th:field="*{name}" id="name">
</form>
</body>
</html>
User class:
package web.model;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#GenericGenerator(name = "increment", strategy = "increment")
private int id;
#Column(name = "name", nullable = false, length = 50)
private String name;
public User() {}
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
}
UserController:
package web.controller;
import jdk.internal.icu.text.NormalizerBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import web.model.User;
import web.service.UserService;
#Controller
#RequestMapping("/users")
public class UserController {
#Autowired
private UserService userService;
#GetMapping
public String listUsers(Model model) {
model.addAttribute("users", userService.getAllUsers());
return "users";
}
#GetMapping("/{id}")
public String show(#PathVariable("id") int id, Model model) {
model.addAttribute("user", userService.getUserById(id));
return "show";
}
#GetMapping("/new")
public String newUser(Model model) {
model.addAttribute("user", new User());
return "new";
}
#PostMapping()
public String create(#ModelAttribute("user") User user) {
userService.add(user);
return "redirect:/users";
}
}
What could be the problem?

thymeleaf passing a parameter from a form to a controller using a post

Im making an app where i have users and some of them have a role Mentor. Users can choose a mentor, who will in time add a personal program and food regime for the user. So far I am printing all the users, having the Mentor role in an html file, but i cant seem to pass the parameter (the current userID) in the post method to the controller.
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.persistence.*;
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true, length = 45)
private String email;
#Column(nullable = false, unique = true, length = 45)
private String username;
#Column(nullable = false, length = 64)
private String password;
#Column(name = "first_name", nullable = false, length = 20)
private String firstName;
#Column(name = "last_name", nullable = false, length = 20)
private String lastName;
#Column(name = "age", nullable = false, length = 20)
private int age;
#Column(name = "sex")
private String sex;
#Column(name = "mentor_id", nullable = true)
private Long mentorid;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="account_id")
private accountInfo accountinfo;
public User() {}
#OneToMany(mappedBy="user")
private List<Blog> blogs= new ArrayList<Blog>();
#ManyToOne(optional = false,fetch = FetchType.LAZY)
#JoinColumn(name="role_id")
private UserRole role;
#OneToOne(mappedBy = "user")
private PersonalProgram personalprogram;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
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 getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public accountInfo getAccountinfo() {
return accountinfo;
}
public void setAccountinfo(accountInfo accountinfo) {
this.accountinfo = accountinfo;
}
public List<Blog> getBlogs() {
return blogs;
}
public void setBlogs(List<Blog> blogs) {
this.blogs = blogs;
}
public UserRole getRole() {
return role;
}
public void setRole(UserRole role) {
this.role = role;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Optional<Long> getMentorid() {
return Optional.ofNullable(mentorid);
}
public void setMentorid(Long mentorid) {
this.mentorid = mentorid;
}
public PersonalProgram getPersonalprogram() {
return personalprogram;
}
public void setPersonalprogram(PersonalProgram personalprogram) {
this.personalprogram = personalprogram;
}
}
this is my user class
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>List of Trainers</title>
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css" />
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
<script>
function getUser(userid) {
$.ajax({
url: "/trainers/choose?userId="+userid,
type: "get",
});
}
</script>
</head>
<body>
<div class="container text-center">
<div>
<h1>List of Trainers</h1>
</div>
<div>
<table class="table table-striped table-bordered">
<thead class="thead-dark">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
<tr th:each="user,index: ${listUsers}"> ///i print each user from the list User
<td th:text="${user.firstName}">First Name</td>
<td th:text="${user.lastName}">Last Name</td>
<td th:text="${user.age}">Age</td>
<td th:text="${user.email}">Email</td>
<td>
<form th:action="#{/trainers/choose}" th:object="${user}" method="post"> //Im trying to pass the id of the user on this row
<input type="hidden" th:field="*{id}" />
<button type="submit">Choose</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
and this is my html
and i guess the controllers handler about the post Method going to look something like this
#RequestMapping(value="trainers/choose", method = RequestMethod.POST)
public String processTrainersChoose (#RequestParam Long mentorid) {
and the get method for visualising the html page is
#GetMapping("/trainers")
public String listTrainers(Model model) {
List<User> listUsers = userRepo.findAllByRole(userRoleRepo.findByName("ROLE_MENTOR"));
model.addAttribute("listUsers", listUsers);
model.addAttribute("user", new User());
return "trainers";
}
```

How to save the image file associated with user in springboot, thymeleaf

I am trying to save the image file and the item details to mysql database, However i got an
error.
I am using thymeleaf for the front end.
Here is my item upload form:
#GetMapping("/itemUploadForm")
public String itemUploadForm(Model theModel) {
Item theItem = new Item();
theModel.addAttribute("item", theItem);
return "fileUploadForm";
}
This part is to process the image and the item details once taken from the user.
#PostMapping("/itemUploadProcess")
public String itemUploadProcess(#ModelAttribute("item") Item theItem,#RequestParam("imagefile") MultipartFile imageFile) throws Exception {
String folder = "/photos";
byte[] bytes = imageFile.getBytes();
Path path = Paths.get(folder + imageFile.getOriginalFilename());
Files.write(path, bytes);
itemService.save(theItem);
return "redirect:/";
}
This is a class item.
I dont know if the problem is in this properties or in mysql.
I have mysql column for file set as imagefile blob not null;
package com.rentyou.projectdemo.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import org.springframework.web.multipart.MultipartFile;
#Entity
#Table(name = "item")
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public int id;
#Column(name = "name")
public String name;
#Column(name = "description")
public String description;
#Column(name = "conditiontype")
public String type;
#Column(name = "price")
public String price;
#Column(name = "contact")
public String contact;
#Column(name = "itemimage")
public MultipartFile itemImage;
public Item() {
}
public Item(String name, String description, String type, String price, String contact, MultipartFile itemImage) {
this.name = name;
this.description = description;
this.type = type;
this.price = price;
this.contact = contact;
this.itemImage = itemImage;
}
public Item(int id, String name, String description, String type, String price, String contact,
MultipartFile itemImage) {
this.id = id;
this.name = name;
this.description = description;
this.type = type;
this.price = price;
this.contact = contact;
this.itemImage = itemImage;
}
public MultipartFile getItemImage() {
return itemImage;
}
public void setItemImage(MultipartFile itemImage) {
this.itemImage = itemImage;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
}
This part is the form to take image file and the item details:
<form th:action="#{/itemUploadProcess}"
th:object="${item}" method="POST" enctype="multipart/form-data">
<input type="text" th:field="*{name}"
class="form-control mb-4 col-4" placeholder="Name">
<input type="text" th:field="*{description}"
class="form-control mb-4 col-4" placeholder="Description">
<input type="text" th:field="*{type}"
class="form-control mb-4 col-4" placeholder="Condition">
<input type="text" th:field="*{price}"
class="form-control mb-4 col-4" placeholder="Price">
<input type="text" th:field="*{contact}"
class="form-control mb-4 col-4" placeholder="Contact">
<input type="file" th:field="*{itemImage}" class="form-control mb-4 col-4" placeholder="Contact" name="imagefile">
<button type="submit" class="btn btns-info col-2">Save</button>
</form>
Remove that attribute name="imagefile" from your form. Its giving the file the wrong name. The th:field attribute will supply the correct name attribute.

How pass field from html that is not part of pojo?

In my spring-boot app:
POJO:
#Entity
#Table(name = "usr") // PostgreSQL not work with table "user"
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#NotNull
private String username;
#NotNull
private String password;
#NotNull
private boolean active;
#NotNull
#ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
#CollectionTable(name = "user_role", joinColumns = #JoinColumn(name = "user_id"))
#Enumerated(EnumType.STRING)
private Set<Role> roles;
here Controller:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import ru.otus.software_architect.eshop.repo.UserRepository;
import java.util.Collections;
#Controller
public class RegistrationController {
#Autowired
private UserRepository userRepository;
#Value("${spring.application.name}")
private String appName;
private static Logger logger = LogManager.getLogger(RegistrationController.class);
#GetMapping("/registration.html")
public String registration(Model model) {
logger.info("open_registration.html");
model.addAttribute("appName", appName);
return "registration.html";
}
#PostMapping("/registration.html")
public String registartionNewUser(User user, Model model) {
logger.info("user = " + user);
if (user.getUsername().trim().isEmpty()
|| user.getPassword().trim().isEmpty()
) {
model.addAttribute("registrationError", "Аll fields are required!");
return "registration.html";
}
user.setActive(true);
user.setRoles(Collections.singleton(Role.USER));
User userFromDb = userRepository.findByUsername(user.getUsername());
if (userFromDb != null) {
model.addAttribute("registrationError", "User already exist!");
return "registration.html";
}
userRepository.save(user);
return "redirect:/login.html";
}
}
here html template:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${appName}">Template title</title>
<link th:href="#{/public/style.css}" rel="stylesheet"/>
</head>
<body>
<div id="container">
<h2 align="center">Registration new user</h2>
<form th:action="#{/registration.html}" method="post">
<label for="username">Username</label>
<input type="text" id="username" name="username" autofocus="autofocus"/>
<label for="password">Password</label>
<input type="password" id="password" name="password"/>
<label for="retypePassword">Retype password</label>
<input type="password" id="retypePassword" name="retypePassword"/>
<input id="submit" type="submit" value="Registration"/>
</form>
<p th:if="${registrationError}" th:text="${registrationError}" class="error"></p>
</div>
</body>
</html>
As you can see I pass POJO User from html and check is username and password was filled.
Nice.
But I also need to check is password and retypePassword are equals.
The problem is that retypePassword is not part of POJO User (no property retypePassword).
How I can pass retypePassword from html to method registartionNewUser to check password and retypePassword ?
have retypePassword as another argument in method registartionNewUser.
public String registartionNewUser(User user, String retypePassword, Model model)

Resources