I am a new self taught programmer, I am making my first independent project and running into some problems. I am making a quiz app, and I want create a class for a quiz, and another class for questions that are mapped to each quiz. I created what I think should be the appropriate models, views, and controllers, but in mysql, there is nothing mapping the questions and quiz together. I did a similar-ish tutorial and it seems like hibernate connects the data, but it is not happening this time.
I have tried to rewrite my processCreateNewQuiz method in QuizCreateController, and so far have had no success. Any ideas on what I should look into to move forward?
Below is what I think is the relevant code:
Quiz class
package org.launchcode.trivia.models;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
#Entity
public class Quiz extends AbstractEntity {
public String name;
#OneToMany (mappedBy = "quiz")
private List<QuestionAnswerInfo> questions = new ArrayList<>();
public Quiz(){}
public Quiz(String name, ArrayList<QuestionAnswerInfo> questions) {
super();
this.name = name;
this.questions = questions;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<QuestionAnswerInfo> getQuestions() {
return questions;
}
public void setQuestions(List<QuestionAnswerInfo> questions) {
this.questions = questions;
}
public void addQuestions(List<QuestionAnswerInfo> questions, QuestionAnswerInfo question) {
questions.add(question);
}
}
QuestionAnswerInfo class
package org.launchcode.trivia.models;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
#Entity
public class QuestionAnswerInfo extends AbstractEntity{
private String question;
private String answer;
private String questionType;
private String additionalAnswerInfo;
#ManyToOne
private Quiz quiz;
public QuestionAnswerInfo (){}
public QuestionAnswerInfo(String question, String answer, String questionType, String additionalAnswerInfo,
Quiz quiz) {
super();
this.question = question;
this.answer = answer;
this.questionType = questionType;
this.additionalAnswerInfo = additionalAnswerInfo;
this.quiz = quiz;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public String getQuestionType() {
return questionType;
}
public void setQuestionType(String questionType) {
this.questionType = questionType;
}
public String getAdditionalAnswerInfo() {
return additionalAnswerInfo;
}
public void setAdditionalAnswerInfo(String additionalAnswerInfo) {
this.additionalAnswerInfo = additionalAnswerInfo;
}
}
QuizCreateController
package org.launchcode.trivia.controllers;
import org.launchcode.trivia.models.QuestionAnswerInfo;
import org.launchcode.trivia.models.Quiz;
import org.launchcode.trivia.models.data.QuestionRepository;
import org.launchcode.trivia.models.data.QuizRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.ArrayList;
import java.util.List;
#Controller
public class QuizCreateController {
#Autowired
private QuestionRepository questionRepository;
#Autowired
private QuizRepository quizRepository;
#RequestMapping("create")
public String displayCreateNewQuiz(Model model) {
model.addAttribute(new Quiz());
model.addAttribute("questions", new QuestionAnswerInfo());
return "create";
}
#PostMapping("create")
public String processCreateNewQuiz(#ModelAttribute Quiz newQuiz, #ModelAttribute QuestionAnswerInfo questions,
Model model) {
List<QuestionAnswerInfo> quizQuestions = new ArrayList<>();
quizQuestions.add(questions);
newQuiz.setQuestions(quizQuestions);
quizRepository.save(newQuiz);
questionRepository.save(questions);
return "index";
}
}
create.html View
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<h1>Create a Quiz</h1>
<form method="post">
<div>
<label th:for="name">Quiz Name</label>
<input th:field="${quiz.name}"/>
</div>
<br>
<div>
<label th:for="question">Add a Question</label>
<input th:field="${questions.question}"/>
</div>
<div>
<label th:for="answer">Add an Answer</label>
<input th:field="${questions.answer}"/>
</div>
<div>
<label th:for="questionType">Question Type</label>
<input th:field="${questions.questionType}"/>
</div>
<div>
<label th:for="additionalAnswerInfo">Add Additional Information</label>
<input th:field="${questions.additionalAnswerInfo}"/>
</div>
<input type="submit" value="Create Quiz"/>
</form>
</body>
</html>
Let me know if you need more info to help me. I am still learning how to even ask for help!
Thanks!
I made this work, at least unidirectionally. I am not sure I needed bidirectional. I needed to change the annotations in #OneToMany in Quiz, and changed the controller method.
Quiz Model code to note:
#OneToMany (cascade = CascadeType.ALL)
#JoinColumn(name = "quiz_question_foreign_id", referencedColumnName = "id")
private List<QuestionAnswerInfo> questions = new ArrayList<>();
Controller
#PostMapping("create")
public String processCreateNewQuiz(#ModelAttribute Quiz newQuiz, #ModelAttribute QuestionAnswerInfo questions,
Model model) {
newQuiz.getQuestions().add(questions);
quizRepository.save(newQuiz);
return "index";
}
Related
I'm attempting to build a twitter clone website using spring boot. I'm getting an error and looked through my code. I'm not sure what I'm doing wrong:
2022-03-15 12:23:51.067 WARN 4580 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'com.example.demo.Tweet'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value 'Test'; nested exception is java.lang.NumberFormatException: For input string: "Test"]
This is a springboot application using postgres as its database. I also have a User repository in the code that does sign me in properly. I would appreciate any assistance with this. Thank you.
Edit: Added full stacktrace.
Edit2: Added an image of the tweeting.html to show where the string "Test" came from.
Tweet.java
package com.example.demo;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
#Entity
#Table(name="tweets")
public class Tweet {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id",unique=true, nullable = false)
private Integer id;
#Column(name="userid", unique=true, nullable=false)
private Integer userid;
#Column(name="tweet", nullable=false)
private String tweet;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userid;
}
public void setUserId(Integer userid) {
this.userid = userid;
}
public String getTweet() {
return tweet;
}
public void setTweet(String tweet) {
this.tweet = tweet;
}
}
TweetRepository.java
package com.example.demo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface TweetRepository extends JpaRepository<Tweet, Integer>{
public Tweet findAllById(Integer userid);
}
TwitterController.java
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
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 org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#Controller
public class TwitterController{
#Autowired
private UserRepository userRepo;
private TweetRepository tweetRepo;
#RequestMapping("/")
public String index(Model model) {
//model.addAttribute("message", "Welcome to spring!");
return "index";
}
#RequestMapping("/testing")
public String testing(Model model) {
model.addAttribute("message", "Welcome to spring boot!");
return "testing";
}
#GetMapping("/register")
public String signup(Model model) {
User user = new User();
model.addAttribute("user", user);
return "register";
}
#RequestMapping("/login")
public String login(Model model) {
return "login";
}
#RequestMapping("/tweeting")
public String tweeting(Model model) {
Tweet tweet = new Tweet();
model.addAttribute("tweet", tweet);
return "tweeting";
}
#PostMapping("/process_register")
public String processRegister(User user) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(user.getPassword());
user.setPassword(encodedPassword);
userRepo.save(user);
return "register_success";
}
#PostMapping("/process_tweet")
public String processTweet(Tweet tweet) {
tweetRepo.save(tweet);
return "tweet_success";
}
}
tweeting.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Tweet</title>
<link href="webjars/bootstrap/5.1.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container col-xl-10 col-xxl-8 px-4 py-5">
<div class="row align-items-center g-lg-5 py-5">
<div class="col-md-10 mx-auto col-lg-5">
<form class="p-4 p-md-5 border rounded-3 bg-light" th:action="#{/process_tweet}" th:object="${tweet}" method="post">
<div class="form-floating mb-3">
<input type="text" class="form-control" id="floatingInput" placeholder=tweet th:field="*{tweet}">
<label for="floatingInput">Tweet</label>
</div>
<button class="w-100 btn btn-lg btn-info" type="submit">Post</button>
</form>
</div>
</div>
</div>
<script src="webjars/jquery/3.6.0/jquery.min.js"></script>
<script src="webjars/bootstrap/5.1.0/js/bootstrap.min.js"></script>
<script>
</script>
</body>
</html>
1.This is my entity class.
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Leads {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String firstName;
private String lastname;
private String email;
private String source;
private String mobile;
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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
}
This is my controller layer
package com.mento1.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.mento1.entities.Leads;
import com.mento1.service.LeadsService;
#Controller
public class LeadsController {
#Autowired
private LeadsService leadService;
#RequestMapping("/leads")
public String showLeadsPage() {
return "saveLeads";
}
#RequestMapping("/saveLead")
public String saveLead(#ModelAttribute("lead")Leads lead, ModelMap modelMap) {
leadService.saveLead(lead);
modelMap.addAttribute("msg", "Lead is saved");
return "saveLeads";
}
}
3.This is my view layer
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>lead</title>
</head>
<body>
<h2>Create new leads</h2>
<form action="saveLead" method="post">
<pre>
first name <input type="text" name="firstName"/>
last name <input type="text" name= "lastName"/>
email <input type="text" name="email" />
source <select name="source">
<option value="News Paper">News Paper</option>
<option value="TV Commercial">TV Commercial</option>
<option value="Online">Online</option>
<option value="radio">radio</option>
</select>
mobile <input type="text" name="mobile" />
<input type="Submit" value="save" />
</pre>
</form>
</body>
</html>
application properties file- here I have configure my data base
spring.datasource.url=jdbc:mysql://localhost:3306/mentoDB
spring.datasource.username=root
spring.datasource.password=Subrat02
spring.mvc.view.suffix=.jsp
spring.mvc.view.prefix=/WEB-INF/jsps/
This is my Repository layer extended jpa repository
package com.mento1.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import com.mento1.entities.Leads;
public interface LeadsRepository extends JpaRepository<Leads, Long> {
}
6.This is my service layer interface
package com.mento1.service;
import com.mento1.entities.Leads;
public interface LeadsService {
public void saveLead(Leads lead);
}
This is my service layer class.
package com.mento1.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mento1.entities.Leads;
import com.mento1.repositories.LeadsRepository;
#Service
public class LeadsServiceImpl implements LeadsService {
#Autowired
private LeadsRepository leadRepo;
#Override
public void saveLead(Leads lead) {
leadRepo.save(lead);
}
}
Error Coming:-
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Feb 13 09:24:29 IST 2022
There was an unexpected error (type=Not Found, status=505)
The problem is I am not able to save the data in the data base.
I reviewed your codes. I think your problem is related to entity class. You don't have got constructor methods in Leads class. You must be add this methods with parameter and non-parameter. This really a huge problem.
And you haven't got all annotations. I recommend to use"Lombok" dependencies for constructor and annotations. You don't need to write getter/setter or constructor methods if you use Lombok.
Then you add Lombok to dependencies and set up it. (You can search to how install lombok to spring-boot project). You just should add some annotations to your entity.
I write my entity class as an example.
package datum....entities.concretes;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Data
#Entity
#Table(name = "column_table")
#AllArgsConstructor
#NoArgsConstructor
public class ColumnTable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "clmn_id")
public int clmnId;
#Column(name = "database_id")
public int databaseId;
#Column(name = "schema_id")
public int schemaId;
#Column(name = "table_id")
public int tableId;
#Column(name = "column_id")
public int columnId;
#Column(name = "column_name")
public String columnName;
#Column(name = "type_name")
public String typeName;
#Column(name = "max_len")
public int maxLen;
#Column(name = "prec")
public int prec;
#Column(name = "nullable")
public int nullable;
#Column(name = "columnDescription")
public String columnDescription;
#Column(name = "sample_name")
public String sampleName;
}
Flight
package com.shahbaz.flightreservation.entities;
import java.sql.Timestamp;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
public class Flight extends AbstractEntity {
private String flightNumber;
private String operatingAirlines;
private String departureCity;
private String arrivalCity;
#Temporal(TemporalType.DATE)
private Date dateOfDeparture;
private Timestamp estimatedDepartureTime;
public String getFlightNumber() {
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
this.flightNumber = flightNumber;
}
public String getOperatingAirlines() {
return operatingAirlines;
}
public void setOperatingAirlines(String operatingAirlines) {
this.operatingAirlines = operatingAirlines;
}
public String getDepartureCity() {
return departureCity;
}
public void setDepartureCity(String departureCity) {
this.departureCity = departureCity;
}
public String getArrivalCity() {
return arrivalCity;
}
public void setArrivalCity(String arrivalCity) {
this.arrivalCity = arrivalCity;
}
public Date getDateOfDeparture() {
return dateOfDeparture;
}
public void setDateOfDeparture(Date dateOfDeparture) {
this.dateOfDeparture = dateOfDeparture;
}
public Timestamp getEstimatedDepartureTime() {
return estimatedDepartureTime;
}
public void setEstimatedDepartureTime(Timestamp estimatedDepartureTime) {
this.estimatedDepartureTime = estimatedDepartureTime;
}
}
AbstractEntity
package com.shahbaz.flightreservation.entities;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
#MappedSuperclass
public class AbstractEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
FlightRepository
package com.shahbaz.flightreservation.repos;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Repository;
import com.shahbaz.flightreservation.entities.Flight;
#Repository
public interface FlightRepository extends JpaRepository<Flight,Long> {
#Query("from Flight where departureCity=:departureCity and arrivalCity=:arrivalCity and dateOfDeparture=:dateOfDeparture")
List<Flight> findFlights(#Param("departureCity") String from, #Param("arrivalCity") String to,
#Param("dateOfDeparture") Date departureDate);
#Query("from Flight where id=:id")
Flight findOne(#Param("id") Long flightId);
}
ReservationController
package com.shahbaz.flightreservation.controllers;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.shahbaz.flightreservation.entities.Flight;
import com.shahbaz.flightreservation.repos.FlightRepository;
#Controller
public class ReservationController {
#Autowired
FlightRepository flightRepository;
#RequestMapping("/showCompleteReservation")
public String showCompleteReservation(#RequestParam("flightId") Long flightId,ModelMap modelMap)
{
System.out.println("Welcome Home");
Flight flight = flightRepository.findOne(flightId);
modelMap.addAttribute("flights", flight);
System.out.println(flight.getArrivalCity());
System.out.println(flight.getDepartureCity());
return "completeReservation";
}
}
completeReservation
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Complete Reservation</title>
</head>
<body>
<h2>Complete Reservation</h2>
Airline: <span th:text="${flight.operatingAirlines}"> <br/>
Departure City: <span th:text="${flight.departureCity}"><br/>
Arrival City:<spanp th:text="${flight.arrivalCity}"><br/>
<form action="completeReservation" method="post">
<pre>
<h2>Passenger Details:</h2>
First Name:<input type="text" name="passengerFirstName"/>
Last Name:<input type="text" name="passengerLastName"/>
Email:<input type="text" name="passengerEmail"/>
Phone:<input type="text" name="passengerPhone"/>
<h2>Card Details:</h2>
Name on the card:<input type="text" name="nameOnTheCard"/>
Card No:<input type="text" name="cardNumber"/>
Expiry Date:<input type="text" name="expirationDate"/>
Three Digit Sec Code:<input type="text" name="securityCode"/>
<input type="hidden" name="flightId" th:value="${flight.id}"/>
<input type="submit" value="confirm"/>
</pre>
</form>
</body>
</html>
While Debugging the code I am Getting Values from database But i am not getting all values while sending request in chrome.I am Getting only Airline value.If anyone can help me to find out the error I tried but unable to come up with solution as i am new to thymeleaf
You are adding your flight instance under the flights key to the model while in the Thymeleaf template, you use ${flight....}.
Changing this:
modelMap.addAttribute("flights", flight);
to
modelMap.addAttribute("flight", flight);
should help.
When I send some data using form it sends null object to controller and I don't know why. I think I have done everything like it was in tutorial but my program does not work properly. Please help :(
I could bet that it is some obvious mistake in code that I don't see because of lack of experience.
Model (I have decided to not use constructor because I don't know how to use it in Spring yet)
import java.math.BigDecimal;
public class Product {
public String name;
public String description;
public BigDecimal price;
public Product(String name, String description, BigDecimal price) {
this.name = name;
this.description = description;
this.price = price;
}
public Product() {
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public BigDecimal getPrice() {
return price;
}
}
DAO
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import com.example.sklepp.service.Product;
import org.springframework.stereotype.Repository;
#Repository
public class ProductDao {
private List<Product> products = Arrays.asList(
new Product("Tea", "green", new BigDecimal("25.00")),
new Product("Coffee", "black", new BigDecimal("30.00")));
public List<Product> all() {
return products;
}
public void addProduct(Product product) {
this.products.add(product);
}
public Product byName(String name) {
for (Product product : products) {
if (name.equals(product.getName())) {
return product;
}
}
return null;
}
}
My controller
import com.example.sklepp.dao.ProductDao;
import com.example.sklepp.service.Product;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("admin")
public class AdminController {
private final ProductDao productDao;
public AdminController(ProductDao productDao) {
this.productDao = productDao;
}
#GetMapping("/")
public String admin(Model model) {
model.addAttribute("newProduct", new Product());
return "admin/admin";
}
#PostMapping("/add-product")
public String addProduct(#ModelAttribute Product product) {
System.out.println(product.getName());
return "redirect:/sklep";
}
}
My template
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
<meta charset="UTF-8">
<title>Admin service</title>
</head>
<body>
<h1>ADMIN</h1>
<p>+++++++++++++++++++++</p>
<form th:action="#{/admin/add-product}" th:object="${newProduct}" method="post">
<p>Adding new product: </p>
<p>Name: <input type="text" th:field="*{name}"></p>
<p>Price: <input type="text" th:field="*{price}"></p>
<p>Description: <input type="text" th:field="*{description}"></p>
<p><input type="submit" value="Add product"></p>
</form>
</body>
</html>
Im learning Spring MVC and Thymeleaf, currently I can make a page to create an OBJ and save it in my DB, also i can make a list of all of the obj and show it on the page.
What im trying to do is to be able to introduce and id in the page and search the matching id OBJ and show it on screen.
This is my Entity:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
int dni;
String name;
String surname;
public int getDni() {
return dni;
}
public void setDni(int dni) {
this.dni = dni;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
This is my Repository:
package com.demolorenzo.user;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface UserRepository extends CrudRepository<User, String> {
List<User>findAll();
List<User>findByName(String name);
List<User>findByDni(int dni);
}
And my Controller:
package com.demolorenzo.user;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
#Controller
public class DemoController {
#Autowired
UserRepository userrepo;
#GetMapping("/Home")
public String userForm(Model model) {
model.addAttribute("user", new User());
return "Home";
}
#PostMapping("/Home")
public String userSubmit(#ModelAttribute User user, Model model) {
model.addAttribute("user", user);
userrepo.save(user);
return "users";
}
#GetMapping("/search")
public String searchForm(Model model) {
model.addAttribute("user", new User());
return "search";
}
#PostMapping("/search")
public String searchSubmit(#ModelAttribute User user, Model model) {
model.addAttribute("user", userrepo.findByDni(user.getDni()));
return "users";
}
}
This is the View (/search):
<form action="#" th:action="#{/search}" th:object="${user}" method="post">
<p> DNI: <input type="number" th:field="*{dni}"/> </p>
<p> <input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
And the last View (/users):
<h1>Result</h1>
<p th:text="'Dni: ' + ${user.dni}" />
<p th:text="'Name: ' + ${user.name}" />
<p th:text="'Surname: ' + ${user.surname}" />
Submit another message
And this is the error im getting:
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'dni' cannot be found on object of type 'java.util.ArrayList' - maybe not public or not valid?
Your view is trying to access the dni property of the user object:
<p th:text="'Dni: ' + ${user.dni}" />
However, in the controller, you are doing:
#PostMapping("/search")
public String searchSubmit(#ModelAttribute User user, Model model) {
model.addAttribute("user", userrepo.findByDni(user.getDni()));
return "users";
}
You are adding the result of the userrepo.findByDni() method as user. But that method returns a List<User>, not a single user.
So user in the view is a List<User> which obviously has not dni property.
You should probably update the controller method to put the result of the repository method in a variable users for example. And use th:each to iterate over those users.