Hi I am new to Spring Mvc i have 3 tables first is role,resources,roleresource tables respectively. I have a created a jsp in which a list of resources are shown along with check boxes and also rolename where user enters,my prob is i need to insert rolename to role table and generated roleid to roleresource table with selected resources ids. problem here is i am not able to bind selected checkbox values here is my controller
package com.steadyground.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.steadyground.constants.URLConstants;
import com.steadyground.entity.Organization;
import com.steadyground.entity.Resources;
import com.steadyground.form.RoleResourceForm;
import com.steadyground.service.ResourcesService;
#Controller
public class RoleResoucesMappingController {
#Autowired
private ResourcesService resourcesService;
#RequestMapping(value = URLConstants.ROLERESOURCEMAPPING_PAGE, method = RequestMethod.GET)
public String landRoleResourceMapping(ModelMap map)
{
map.addAttribute("roleResourceForm",new RoleResourceForm());
return "roleResourcesMapping";
}
#RequestMapping(value = URLConstants.ROLERESOURCEMAPPING_ADD, method = RequestMethod.POST)
public String createRoleResourceMapping(#ModelAttribute(value="roleResourceForm") RoleResourceForm roleResourceForm, BindingResult result, ModelMap map)
{
System.out.println(roleResourceForm.getResources());
System.out.println(roleResourceForm.getResources().size());
//System.out.println(roleResourceForm.getRole().getRoleResources());
return "roleResourcesMapping";
}
#ModelAttribute("resources")
public List<Resources> getAllResources() {
List<Resources> listResources = new ArrayList<Resources>();
listResources = resourcesService.getAllResources();
return listResources;
}
}
here is my role.java file
#Entity
#Table(name = "role", catalog = "steadyground")
public class Role implements java.io.Serializable {
private Integer roleId;
private String roleName;
private Set<RoleResource> roleResources = new HashSet<RoleResource>(0);
public Role() {
}
public Role(String roleName) {
this.roleName = roleName;
}
public Role(String roleName, String applicationName,
Set<RoleResource> roleResources) {
this.roleName = roleName;
this.roleResources = roleResources;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "role_id", unique = true, nullable = false)
public Integer getRoleId() {
return this.roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
#Column(name = "role_name", nullable = false, length = 100)
public String getRoleName() {
return this.roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "role")
public Set<RoleResource> getRoleResources() {
return this.roleResources;
}
public void setRoleResources(Set<RoleResource> roleResources) {
this.roleResources = roleResources;
}
}
here is my resources.java
#Entity
#Table(name = "resources", catalog = "steadyground")
public class Resources implements java.io.Serializable {
private Integer resourceId;
private String url;
private String urlName;
public Resources() {
}
public Resources(String url, String urlName) {
this.url = url;
this.urlName = urlName;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "resource_id", unique = true, nullable = false)
public Integer getResourceId() {
return this.resourceId;
}
public void setResourceId(Integer resourceId) {
this.resourceId = resourceId;
}
#Column(name = "url", length = 100)
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
#Column(name = "url_name", length = 200)
public String getUrlName() {
return this.urlName;
}
public void setUrlName(String urlName) {
this.urlName = urlName;
}
}
here is my roleresource.java
#Entity
#Table(name="role_resource"
,catalog="steadyground"
)
public class RoleResource implements java.io.Serializable {
private Integer roleResourceId;
private Role role;
private Integer resourceId;
public RoleResource() {
}
public RoleResource(Role role, Integer resourceId) {
this.role = role;
this.resourceId = resourceId;
}
#Id #GeneratedValue(strategy=IDENTITY)
#Column(name="role_resource_id", unique=true, nullable=false)
public Integer getRoleResourceId() {
return this.roleResourceId;
}
public void setRoleResourceId(Integer roleResourceId) {
this.roleResourceId = roleResourceId;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="role_id")
public Role getRole() {
return this.role;
}
public void setRole(Role role) {
this.role = role;
}
#Column(name="resource_id")
public Integer getResourceId() {
return this.resourceId;
}
public void setResourceId(Integer resourceId) {
this.resourceId = resourceId;
}
}
and my jsp page
<springform:form method="post" action="createRoleResourcesMapping" class="form-horizontal" commandName="roleResourceForm" >
<div class="span12">
<div class="center">
<div class="control-group span6">
<label class="control-label" for="Role_Id">Role Id</label>
<div class="control-group span6">
<label class="control-label" for="url_Name">Role Name</label>
<div class="controls">
<div class="span12">
<springform:input path="role.roleName"/>
</div>
</div>
</div>
<div class="page-header position-relative"></div>
<table id="sample-table-2" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Resources</th>
</tr>
</thead>
<tbody>
<tr>
<td><springform:checkboxes path="resources" items="${resources}" itemLabel="urlName" itemValue="resourceId"/>
</td></tr></tbody>
</table>
<div class="controls">
<div class="span12">
<input type="submit" class="btn btn-primary" value="Submit">
<input type="button" class="btn " value="Cancel">
</div>
</div>
</div>
</div>
</springform:form>
could someone help me in how to receive the data and save it in two tables
<springform:checkboxes path="resources" items="${resources}" itemLabel="urlName" itemValue="resourceId"/>
From your code, what I've understood, the RoleResourcesForm is more like a wrapper of the 2 entities Resource & Role with another object resources.
I think, to use form:checkboxes you better give it an object List in the path.
And what's this variable resources?
If it's really an List object in the RoleResourcesForm wrapper, in the items, you should use
items="${roleResourceForm.resources}"
When you commit it, it will send the form model attribute with only checked checkbox values.
Related
So, my entire project seems to work for now. It is a simple system that holds records of all products of a shop. When a new product is made, a barcode will be generated. Now, this works, but I wanted to see my barcode(I can see the longblob in my db) in the output to be sure. I am probably doing it wrong, but I cannot get the image displayed.
The controller and html pages are quit irrelevant for now cause I just made them to see if I would see the barcode, but I don't. So what html tags do I need to use to get this barcode image displayed? I got the barcode object from here:
<dependency>
<groupId>net.sourceforge.barbecue</groupId>
<artifactId>barbecue</artifactId>
<version>1.5-beta1</version>
</dependency>
I will display the code from the html, controller and the object. You can find the entire project on git. https://github.com/Muschke/scruplesAntwerpenTwee.
html:
<html lang="nl" xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments::head(title='Index', css=#{/css/css.css})"></head>
<th:block th:if="${producten}">
<table>
<thead>
<th>Gebruiker</th>
<th>Consignatiebon</th>
<th>Eigenschap</th>
<th>Kleur</th>
<th>Merk</th>
<th>Maat</th>
<th>Soort</th>
<th>Barcode</th>
<th>Beschrijving</th>
<th>aankoopprijs</th>
<th>verkoopprijs</th>
<th>status</th>
<th>gestolen</th>
<th>solden</th>
</thead>
<tbody>
<tr th:each="product:${producten}" th:object="${product}">
<td th:text="*{getGebruiker().getNaam()}"></td>
<td th:text="*{getConsignatiebon().getidConsignatiebon()}"></td>
<td th:text="*{getEigenschap().getSubEigenschap()}"></td>
<td th:text="*{getKleur().getKleur()}"></td>
<td th:text="*{getMerk().getNaam()}"></td>
<td th:text="*{getMaat().getNaam()}"></td>
<td th:text="*{getSoort()}"></td>
<td>
<img class='img-thumbnail' th:src="'data:image/jpeg;base64,' + ${imgUtil.getImgData(product.getBarcode())}" />
</td>
<td th:text="*{getBeschrijving()}"></td>
<td th:text="*{getAankoopprijs()}"></td>
<td th:text="*{getVerkoopprijs()}"></td>
<td th:text="*{getStatus()}"></td>
<td th:text="*{getGestolen()}"></td>
<td th:text="*{getSolden()}"></td>
</tr>
</tbody>
</table>
<form th:action="#{/verwerken}" method="post">
<button name="barcodebutton">Genereer barcode</button>
</form>
</th:block>
</html>
controller:
#Controller
#RequestMapping("/")
class IndexController {
private final ProductService productService;
public IndexController(ProductService productService) {
this.productService = productService;
}
#GetMapping
public ModelAndView findAllProducts() {
return new ModelAndView("index").addObject("producten", productService.findAllProducts());
}
#PostMapping("/verwerken")
public ModelAndView barcodeToevoegen() {
var idnu = 52L;
productService.genereerBarcode(idnu);
return new ModelAndView("redirect:/");
}
}
object:
#Table(name = "producten")
public class Product {
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
private long productId;
#ManyToOne(fetch = FetchType.LAZY, optional = false) #JoinColumn(name = "gebruikerId")
private Gebruiker gebruiker;
#ManyToOne(fetch = FetchType.LAZY, optional = false) #JoinColumn(name = "consignatiebonId")
private Consignatiebon consignatiebon;
#OneToOne #JoinColumn(name = "eigenschapId")
private Eigenschap eigenschap;
#OneToOne #JoinColumn(name = "kleurId")
private Kleur kleur;
#OneToOne #JoinColumn(name = "merkId")
private Merk merk;
#OneToOne #JoinColumn(name = "maatId")
private Maat maat;
#Enumerated(EnumType.STRING)
private Soort soort;
private Barcode barcode;
/*de barcode mag null zijn bij input?, na input van alles, invoke methode creeër barcode.
* dat MOET dan na create worden uitgevoerd in transactional*/
private String beschrijving;
private BigDecimal aankoopprijs;
#Enumerated(EnumType.STRING)
private Status status;
private boolean gestolen;
private boolean solden;
public Product(Gebruiker gebruiker, Consignatiebon consignatiebon, Eigenschap eigenschap, Kleur kleur, Merk merk, Maat maat, Soort soort, Barcode barcode,
String beschrijving, BigDecimal aankoopprijs, Status status,boolean gestolen, boolean solden) {
this.gebruiker = gebruiker;
this.consignatiebon = consignatiebon;
this.eigenschap = eigenschap;
this.kleur = kleur;
this.merk = merk;
this.maat = maat;
this.soort = soort;
this.barcode = barcode;
this.beschrijving = beschrijving;
this.aankoopprijs = aankoopprijs;
this.status = status;
this.gestolen = gestolen;
this.solden = solden;
}
protected Product() {};
public Consignatiebon getConsignatiebon() {
return consignatiebon;
}
public Gebruiker getGebruiker() {
return gebruiker;
}
public long getProductId() {
return productId;
}
public Eigenschap getEigenschap() {
return eigenschap;
}
public Kleur getKleur() {
return kleur;
}
public Merk getMerk() {
return merk;
}
public Maat getMaat() {
return maat;
}
public Soort getSoort() {
return soort;
}
public Barcode getBarcode() {
return barcode;
}
public String getBeschrijving() {
return beschrijving;
}
public BigDecimal getAankoopprijs() {
return aankoopprijs;
}
public BigDecimal getVerkoopprijs() {
return aankoopprijs.multiply(BigDecimal.valueOf(2.5));
}
public Status getStatus() {
return status;
}
public boolean getGestolen() {
return gestolen;
}
public boolean getSolden() {
return solden;
}
/*setters voor vkp en gestolen, en voor elke OTO*/
public void setEigenschap(Eigenschap eigenschap) {
this.eigenschap = eigenschap;
}
public void setKleur(Kleur kleur) {
this.kleur = kleur;
}
public void setMerk(Merk merk) {
this.merk = merk;
}
public void setMaat(Maat maat) {
this.maat = maat;
}
public void setGestolen(boolean gestolen) {
this.gestolen = gestolen;
}
/*equals en hashtagcode maken*/
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Product)) return false;
Product product = (Product) o;
return Objects.equals(eigenschap, product.eigenschap) && Objects.equals(kleur, product.kleur) && Objects.equals(merk, product.merk) && Objects.equals(maat, product.maat) && soort == product.soort && Objects.equals(beschrijving, product.beschrijving) && Objects.equals(aankoopprijs, product.aankoopprijs);
}
#Override
public int hashCode() {
return Objects.hash(eigenschap, kleur, merk, maat, soort, beschrijving, aankoopprijs);
}
/*methode om barcode te genereren als er nog geen barcode is:
* we steken het id erin, laten aanvullen met nullen tot aan 12 getallen, 13e wordt automatisch gemaakt*/
//eventueel via #þostload automatisch laten invullen
public void generateAndSetEAN13BarcodeImage() throws Exception {
if(barcode != null) {
throw new IllegalArgumentException();
} else {
var lengte = String.valueOf(getProductId()).length();
StringBuilder langeId = new StringBuilder(String.valueOf(productId));
if (lengte < 12) {
var verschil = 12 - lengte;
for (int i = 0; i < verschil; i++) {
langeId.append(0);
}
}
barcode = BarcodeFactory.createEAN13(String.valueOf(langeId));
}
}
}
So, question again: how can I make the barcode be displayed on the html page?
I have stucked with the problem: How to retrieve a data from 2 separate classes using Java, MySQL DB and Thymeleaf?
I'd like to show content of the messages and user details such as First Name and Second Name plus time on the one web page using Thymleaf.
I used to do that with one class but with 2 different classes I have a problem...... :-(
My code is below. Please give me some advice :-)
There are classes:
#Entity
#Table(name = "messages")
public class Message {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(length = 400)
private String message;
private String uploadDir;
#DateTimeFormat(pattern = "dd-MMM-yyyy")
private String localDate;
#ManyToOne
#JoinColumn(name = "user_id",
referencedColumnName = "id"
)
private User user;
public Message(){}
...
getters and setters
}
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String login;
private String firstName;
private String lastName;
private String mail;
private String password;
private LocalDate birthDate;
private String role;
#OneToMany(mappedBy = "user",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Message> message = new ArrayList<>();
public User(){}
}
getters and setters
.......
There are DTO Classes:
public class MessageDTO {
private UserDTO userDTO;
private Long id;
private String message;
private String uploadDir;
private String localDate;
getters and setters
......
}
public class UserDTO {
private Long id;
private String login;
private String firstName;
private String lastName;
private String mail;
private String password;
private LocalDate birthDate;
private String role;
private List<Message> message = new ArrayList<>();
getters and setters
......
}
public class MessegeService{
.....
public List<MessageDTO> getAllMessagesS(){
return messageRepository
.findAll()
.stream()
.map(message -> modelMapper.map(message, MessageDTO.class))
.collect(Collectors.toList());
}
}
public class UserService{
public List<UserDTO> getAllUsers() {
return userRepository
.findAll().stream()
.map(user -> modelMapper.map(user, UserDTO.class))
.collect(Collectors.toList());
}
.....
}
And finally a web page. Here are the problems below for me. I need to pull login, first name, second name from the MySQL DB. The field are in two separate classes.
What am I doing wrong?
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>Messages:</title>
</head>
<body>
<div class="container" name="container">
<div class="balloon" name="balloon">
<table class="table" name="text-messages">
<thead class="thead-dark">
<th scope="col" th:width="20px">Id</th>
<th scope="col" align="center" th:width="50px">Date & time</th>
<th scope="col" align="center">Message</th>
<th scope="col" align="center">Message lenght</th>
</thead>
<tbody>
<tr th:each="usermessage : ${userShowMessage} ">
<form action="#{/show-messages}" method="post", th:object="${usermessage}">
<td type="number" th:text="${usermessage.id}"></td>
<td th:text="${usermessage.localDate}"></td>
<td th:text="${usermessage.message}"></td>
<td th:text="${usermessage.userDTO.firstName}"></td> <!--That doesn't work. Please give me some advice here -->
<td th:text="${usermessage.message.length()}"></td>
</form>
</tbody>
</table>
</div>
</div>
</body>
</html>
That line of the code doesn't work: usermessage.userDTO.firstName
How can I retrieve information on one web page using Thymeleaf in that example?
Thank you for your advice :-)
This is my Message and User Controllers:
#Controller
public class MessageController {
private static final Logger logger = LoggerFactory.getLogger(MessageController.class);
private MessageService messageService;
public MessageController(MessageService messageService) {
this.messageService = messageService;
}
#GetMapping("/useraddcontent")
public ModelAndView getAddNewMessage(){
logger.warn("Before add a new message");
return new ModelAndView("useraddcontent", "userAddMessage", new MessageDTO());
}
#PostMapping("/useraddcontent")
public String addNewMessage(#ModelAttribute MessageDTO messageDTO){
logger.warn("Creating a new message");
System.out.println(messageDTO.getMessage());
messageService.addMessageS(messageDTO);
return "redirect:/userpage";
}
#GetMapping("/show-messages")
public ModelAndView readMessages(){
logger.warn("Reading messages");
List<MessageDTO> messageDTOList = messageService.getAllMessagesS();
return new ModelAndView("show-messages", "userShowMessage", messageDTOList);
}
}
#RestController
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
private UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
#GetMapping("/finduser")
public ModelAndView findUser() {
logger.warn("List the users");
return new ModelAndView("finduser", "finduser", new UserDTO());
}
#GetMapping("/finduserbylastname")
public ModelAndView findUserByLastName(#ModelAttribute UserDTO userDTO) {
logger.warn("Find a user by a last name");
List<UserDTO> userDTOList = userService.findUserByLastName(userDTO.getLastName());
return new ModelAndView("users", "userList", userDTOList);
}
#GetMapping("/users")
ResponseEntity<List<UserDTO>> findAllUsers() {
logger.warn("Exposing all users!");
return ResponseEntity.ok(userService.getAllUsers());
}
#GetMapping("/users/{id}")
ResponseEntity<UserDTO> findUserById(#PathVariable Integer id) {
logger.warn("Exposing specific user!");
return userService.getUserById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
#PostMapping("/users")
ResponseEntity<User> createUser(#RequestBody UserDTO userDTO) {
logger.info("Created new user!");
User result = userService.create(userDTO);
return ResponseEntity.created(URI.create("/" + result.getId())).build();
}
}
I have a cinema reservation system where user can add movies and then they can add date to each movie. It works fine, but when a user adds a date, there is no error, but it saves to the database with movie_id = null.
How can I solve it?
Movie.java
#Data
#Entity
public class Movie {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
#Column(name = "id")
private Long id;
#Column(unique = true)
private String title;
private String category;
#Column( columnDefinition = "TEXT")
private String description;
private Integer lenght;
private Integer minAge;
#Column(columnDefinition = "TEXT")
private String imageUrl;
#OneToMany(mappedBy = "movie", orphanRemoval = true)
private List<Repertoire> repertoires;
public Movie() {
}
}
Repertoire.java
#Data
#Entity
public class Repertoire {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
#Column(name = "id")
private Long id;
#DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
private LocalDateTime date;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "movie_id")
private Movie movie;
}
MovieController.java
#Controller
#RequestMapping("/movies")
public class MovieController {
private MovieRepo movieRepo;
private RepertoireRepo repertoireRepo;
#Autowired
public MovieController(MovieRepo movieRepo, RepertoireRepo repertoireRepo) {
this.movieRepo = movieRepo;
this.repertoireRepo = repertoireRepo;
}
#GetMapping("showForm")
public String showStudentForm(Movie movie) {
return "add-movie";
}
#GetMapping("list")
public String getMovies(Model model) {
model.addAttribute("movies", movieRepo.findAll());
return "movieIndex";
}
#PostMapping("add")
public String movies(#Validated Movie movie, BindingResult result, Model model) {
if(result.hasErrors()) {
return "add-movie";
}
movieRepo.save(movie);
return "redirect:/movies/list";
}
#GetMapping("edit/{id}")
public String showUpdateForm(#PathVariable ("id") long id, Model model) {
Movie movie = movieRepo.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Nieprawidłowe ID: " + id));
model.addAttribute("movie", movie);
return "update-movie";
}
#PostMapping("update/{id}")
public String updateMovie(#PathVariable("id") long id, #Validated Movie movie, BindingResult result, Model model) {
if(result.hasErrors()) {
movie.setId(id);
return "update-movie";
}
movieRepo.save(movie);
model.addAttribute("movies", movieRepo.findAll());
return "movieIndex";
}
#GetMapping("delete/{id}")
public String deleteMovie(#PathVariable ("id") long id, Model model) {
List<Repertoire> repertoires = repertoireRepo.findByMovieId(id);
repertoires.forEach(r -> repertoireRepo.deleteById(r.getId()));
Movie movie = movieRepo.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Nieprawidłowe ID : " + id));
movieRepo.delete(movie);
model.addAttribute("movies", movieRepo.findAll());
return "movieIndex";
}
// HERE'S WHERE I ADD THE TIME:
#GetMapping("/admin/{movieName}/newRepertoire")
public String showRepertoireForm(Model model, #PathVariable ("movieName") String movieName) {
Movie movieRepertoire = movieRepo.findByTitle(movieName);
model.addAttribute("movieRepertoire", movieRepertoire);
model.addAttribute("repertoire", new Repertoire());
return "repertoire";
}
#PostMapping("/admin/newRepertoire")
#Transactional
public String addRepertoire(#ModelAttribute ("repertoire") Repertoire repertoire,
#ModelAttribute("movieRepertoire") Movie movie, BindingResult result) {
// if(result.hasErrors()) {
// return "repertoire";
// }
repertoire.setMovie(movieRepo.findByTitle(movie.getTitle()));
repertoireRepo.save(repertoire);
return "redirect:/movies/list";
}
}
RepertoireRepo.java
#Repository
public interface RepertoireRepo extends JpaRepository<Repertoire, Long> {
List<Repertoire> findByMovieId(Long movieId);
}
MovieRepo.java
#Repository
public interface MovieRepo extends JpaRepository<Movie, Long> {
Movie findByTitle(String title);
}
repertoire.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>c</title>
</head>
<body>
<div class="container my-5">
<div class="card">
<div class="card-body">
<div class="col-md-10">
<h1 th:text="${movieRepertoire.title}"> MovieName</h1>
<form action="#" th:action="#{/movies/admin/newRepertoire}" th:object="${repertoire}" method="post">
<div class="row">
<div class="form-group col-md-8">
<label for="date" class="col-form-label">Date</label>
<input type="datetime-local" th:field="*{date}" class="form-control" id="date" value="2021-01-20T13:01">
<span th:if="${#fields.hasErrors('date')}" th:errors="*{date}" class="text-danger"></span>
</div>
<div class="col-md-6">
<input type="submit" class="btn btn-primary" value="Add">
</div>
<div class="form-group col-md-8"></div>
</div>
<!-- <input type = "hidden" th:value="${movieRepertoire}">-->
</form>
</div>
</div>
</div>
</div>
</body>
</html>
Movie structure:
id | category | description | imageurl| lenght| minage| title
-------------------------
36 | Action | Simple desc. | photo.jpg | 137 | 7 | Iron Man |
Repertoire structure:
id | date | movie_id
-------------------------
37 | 2021-01-01 14:00:00 | null |
Both sides of the relationship must be updated and you should cascade save from the parent. Your code:
repertoire.setMovie(movieRepo.findByTitle(movie.getTitle()));
repertoireRepo.save(repertoire);
Should become:
Movie movie = movieRepo.findByTitle(movie.getTitle());
movie.getRepertoires().add(repertoire);
repertoire.setMovie(movie);
session.saveOrUpdate(movie);
In fact really you should add a helper method to Movie that performs both actions to ensure both sides of the relationship are always in sync:
public void addRepertoire(Repertoire repertoire) {
repertoires.add(repertoire);
repertoire.setMovie(this);
}
I am writing a SpringBoot application for an e-commerce website project where I'm creating a form to change the current password of the user account. I am getting the following two errors when the form gets submitted.
ERROR-1
An error happened during template parsing (template: "class path resource [templates/myprofile.html]")
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "user.id" (template: "myprofile" - line 110, col 68)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "user.id" (template: "myprofile" - line 110, col 68)
ERROR-2
Property or field 'id' cannot be found on object of type 'java.lang.Boolean' - maybe not public or not valid?
HomeController
#RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
public String updateUserInfo(
#ModelAttribute("user") user user,
#ModelAttribute("newPassword") String newPassword,
Model model
) throws Exception{
user currentUser = userService.findById(user.getId());
if(currentUser == null) {
throw new Exception ("User not found.");
}
if(userService.findByEmail(user.getEmail())!=null) {
if(userService.findByEmail(user.getEmail()).getId() != currentUser.getId()) {
model.addAttribute("emailExists", true);
return "myprofile";
}
}
if(userService.findByUsername(user.getUsername())!=null) {
if(userService.findByUsername(user.getUsername()).getId() != currentUser.getId()) {
model.addAttribute("usernameExists", true);
return "myprofile";
}
}
if(newPassword != null && !newPassword.isEmpty() && !newPassword .equals("")) {
BCryptPasswordEncoder passwordEncoder = SecurityUtility.passwordEncoder();
String dbPassword = currentUser.getPassword();
if(passwordEncoder.matches(user.getPassword(), dbPassword)) {
currentUser.setPassword(passwordEncoder.encode(newPassword));
}else {
model.addAttribute("invalidPassword", true);
return "myprofile";
}
}
currentUser.setFirstName(user.getFirstName());
currentUser.setLastName(user.getLastName());
currentUser.setUsername(user.getUsername());
currentUser.setEmail(user.getEmail());
userService.save(currentUser);
model.addAttribute("updateSuccess", true);
model.addAttribute("user", true);
model.addAttribute("classActiveEdit", true);
UserDetails userDetails = userSecurityService.loadUserByUsername(currentUser.getUsername());
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
return "myprofile";
}
myprofile.html
<form th:action="#{/updateUserInfo}" method="post" >
<input type="hidden" name="id" th:value="${user.id}" />
<div class="bg-info" th:if="${updateUserInfo}">User info updated</div>
<div class="form-group">
<div class="row">
<div class="col-xs-6">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName" name="firstName" th:value="${user.firstName}" />
</div>
<div class="col-xs-6">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName" name="lastName" th:value="${user.lastName}" />
</div>
</div>
</div>
<div class="form-group">
<label for="userName">Username</label>
<input type="text" class="form-control" id="userName" name="username" th:value="${user.username}" />
</div>
<div class="form-group">
<label for="currentPassword">Current Password</label>
<input type="password" class="form-control" id="currentPassword" name="password" th:value="${currentPassword}" />
</div>
<p style="color: #828282">Enter your current password to change the email address or password</p>
<div class="form-group">
<label for="email">Email Address</label>
<input type="text" class="form-control" id="email" name="email" th:value="${user.email}" />
</div>
<p style="color: #828282">A valid email address. All
emails from the system will be sent to this address.The
email address is not make public and will only be used if
you wish to receive a new password or wish to receive
certain notification</p>
<div class="form-group">
<label for="txtNewPassword">Password</label> <span id="checkPasswordMatch" style="color:red;"></span>
<input type="password" class="form-control" id="txtNewPassword" name="txtNewPassword" />
</div>
<div class="form-group">
<label for="txtConfirmPassword">Confirm Password</label>
<input type="password" class="form-control" id="txtConfirmPassword" />
</div>
<p style="color: #828282">To change the current user password, enter new password in both fileds </p>
<button id="updateUserInfobutton" type="submit" class="btn btn-primary">Save All</button>
</form>
User Class
package com.eshop.domian;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
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.OneToMany;
import javax.persistence.OneToOne;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.eshop.security.UserRole;
import com.eshop.security.auth;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
public class user implements UserDetails{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id", nullable = false, updatable = false)
private Long id;
private String firstName;
private String lastName;
private String username;
private String password;
#Column(name="email", nullable = false, updatable = false)
private String email;
private String phone;
private boolean enabled=true;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "user")
private ShoppingCart shoppingCart;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserShipping> userShippingList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserPayment> userPaymentList;
#OneToMany(mappedBy = "user", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JsonIgnore
private Set<UserRole> userRoles= new HashSet<>();
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 getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
public ShoppingCart getShoppingCart() {
return shoppingCart;
}
public void setShoppingCart(ShoppingCart shoppingCart) {
this.shoppingCart = shoppingCart;
}
public List<UserShipping> getUserShippingList() {
return userShippingList;
}
public void setUserShippingList(List<UserShipping> userShippingList) {
this.userShippingList = userShippingList;
}
public List<UserPayment> getUserPaymentList() {
return userPaymentList;
}
public void setUserPaymentList(List<UserPayment> userPaymentList) {
this.userPaymentList = userPaymentList;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<>();
userRoles.forEach(ur -> authorities.add(new auth(ur.getRole().getName())));
return authorities;
}
#Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isEnabled()
{
return enabled;
}
}
User Service
package com.eshop.service;
import java.util.Set;
import com.eshop.domian.UserBilling;
import com.eshop.domian.UserPayment;
import com.eshop.domian.UserShipping;
import com.eshop.domian.user;
import com.eshop.security.PasswordResetToken;
import com.eshop.security.UserRole;
public interface UserService {
PasswordResetToken getPasswordResetToken(final String token);
void createPasswordResetTokenForUser(final user user, final String token);
user findByUsername(String username);
user findByEmail(String email);
user findById(Long Id);
user createUser(user user, Set<UserRole> userRoles) throws Exception;
user save(user user);
void updateUserBilling(UserBilling userBilling, UserPayment userPayment, user user);
void setUserDefaultPayment(Long userPaymentId, user user);
void updateUserShipping(UserShipping userShipping, user user);
void setUserDefaultShipping(Long userShippingId, user user);
}
User Service Implementation
package com.eshop.service.impl;
#Service
public class UserServiceImpl implements UserService{
private static final Logger LOG = LoggerFactory.getLogger(UserService.class);
#Autowired
private PasswordResetTokenRepository passwordResetTokenRepository;
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#Autowired
private UserPaymentRepository userPaymentRepository;
#Autowired
private UserShippingRepository userShippingRepository;
#Override
public PasswordResetToken getPasswordResetToken(final String token) {
return passwordResetTokenRepository.findByToken(token);
}
#Override
public void createPasswordResetTokenForUser(final user user, final String token) {
final PasswordResetToken myToken = new PasswordResetToken(token, user);
passwordResetTokenRepository.save(myToken);
}
#Override
public user findByUsername(String username) {
// TODO Auto-generated method stub
return userRepository.findByusername(username);
}
#Override
public user findById(Long id) {
return userRepository.findById(id).get();
}
#Override
public user findByEmail(String email) {
// TODO Auto-generated method stub
return userRepository.findByEmail(email);
}
}
Here you try to access the id field of the user model attribute:
<input type="hidden" name="id" th:value="${user.id}" />
Here you set the user model attribute to true, therefore it's of type boolean:
model.addAttribute("user", true);
As a variable of type boolean does not have a field called id, trying to access it gives the error you see. I assume what's going on is that you didn't want to set that model attribute to true (perhaps you wanted to set it to currentUser?), or that the id field that you want to access belongs to another model attribute.
I have a local Oracle database with which I've established a solid connection. Now I just want to POST data from an HTML input form using a Controller to handle said data.
My form looks like this:
<form action="/request/save" method="post">
<input type="text" id="dateInput" name="requestDate" value="1" style="display: none;"/>
<input type="text" name="description" value="This is a test request." style="display: none;"/>
<input type="text" name="status" value="false" style="display: none;"/>
<div style="width: 200px;"><input type="submit" value="Submit Request" style="display: block;"></div>
</form>
Controller:
#RequestMapping(value = "/save", method = RequestMethod.POST)
String saveRequest(Principal principal, #ModelAttribute Request request, Model model) {
// Set UserId to Request Field USER_ID
Users user = usersRepository.findOneByInitialName(principal.getName());
Request requestObj = new Request(user, new Date());
requestObj.setId(user.getId());
// Set Additional Request Fields
requestObj.setDescription("Test");
requestObj.setStatus(false);
requestObj.setRequestDate(new Date());
// Save Request Object
requestRepository.save(requestObj);
return "requests";
}
Entity (for completion):
#Entity
public class Request {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="request_id")
private Long id;
private Date requestDate;
private String description;
private Boolean status;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="user_id", nullable = false)
private Users users;
public Request() {}
public Request(Users user, Date requestDate) {
this.setUsers(user);
this.setRequestDate(requestDate);
}
#Override
public String toString() {
return String.format(
"Request[id=%d, inital='%s', requestDate='%s']",
getId()
, getUsers().getInitialName()
, getRequestDate());
}
public Date getRequestDate() {
return requestDate;
}
public void setRequestDate(Date requestDate) {
this.requestDate = requestDate;
}
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Users getUsers() {
return users;
}
public void setUsers(Users users) {
this.users = users;
}
}
How can I send the data from the form to my database?
Error:
Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
You might have configured csrf filter in your web.xml, so you need to pass "X-CSRF-TOKEN" in your request header.