Multiple select in thymeleaf + hibernate + spring boot - spring-mvc

Hello guys I'm using thymeleaf 3 with spring boot and spring data jpa. But here is the problem. When I try to save I get this error from Hibernate:
Hibernate: insert into consulta (medico_id) values (?)
Hibernate: insert into consulta_pacientes (consulta_id, pacientes_id) values (?, ?)
2016-12-12 16:06:53.963 WARN 11912 --- [nio-9393-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1364, SQLState: HY000
2016-12-12 16:06:53.963 ERROR 11912 --- [nio-9393-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : Field 'pct_id' doesn't have a default value
2016-12-12 16:06:53.965 INFO 11912 --- [nio-9393-exec-9] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2016-12-12 16:06:53.976 ERROR 11912 --- [nio-9393-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path
[] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibe
rnate.exception.GenericJDBCException: could not execute statement] with root cause
java.sql.SQLException: Field 'pct_id' doesn't have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:963) ~[mysql-connector-java-5.1.39.jar:5.1.39]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3966) ~[mysql-connector-java-5.1.39.jar:5.1.39]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3902) ~[mysql-connector-java-5.1.39.jar:5.1.39]
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2526) ~[mysql-connector-java-5.1.39.jar:5.1.39]
I already tried to use converter but didn't workout properly. Tried to look in this posts* ...but didn't solve either.
*1 http://forum.thymeleaf.org/th-selected-not-working-on-lt-select-gt-lt-option-gt-td4029201.html
*2
thymeleaf multiple selected on edit
Any tips? I'm kind of lost right now.
cadastro.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
...
<form action="#" th:action="#{salvar}" th:object="${consulta}" method="POST">
<div class="form-inline">
<label for="select-medico-consulta" class="form-group">Medico</label>
<select th:field="*{medico.id}" id="select-medico-consulta" >
<div>
<option th:each="medicoEntry : ${medicos}"
th:value="${medicoEntry.id}"
th:text="${medicoEntry.nome}"></option>
</div>
</select>
<div class="form-group">
<label id="paciente-label" for="select-paciente" > Paciente</label>
<select th:field="*{pacientes}" id="select-paciente" size="5" multiple="multiple" >
<div>
<option th:each="pacienteEntry : ${listaPacientes}"
th:field="*{pacientes}"
th:value="${pacienteEntry.id}"
th:text="${pacienteEntry.nome}"></option>
</div>
</select>
</div>
</div>
<div class="form-group">
<label for="comment">Consulta</label>
<textarea class="form-control" rows="5" id="comment"></textarea>
</div>
<button type="submit" class="btn btn-default">Salvar</button>
</form>
</div>
...
consultaController.java
package
and imports...
#Controller
#RequestMapping("/medclin")
public class ConsultaController {
#Autowired
private ConsultaDao consultadao;
#Autowired
private MedicoDao medicoDao;
#Autowired
private PacienteDao pacienteDao;
#RequestMapping("/consulta")
public ModelAndView Consulta() {
ModelAndView modelAndView = new ModelAndView("consulta/consulta");
ArrayList<Medico> medicos = (ArrayList<Medico>) medicoDao.findAll();
ArrayList<Paciente> pacientes = (ArrayList<Paciente>) pacienteDao.findAll();
modelAndView.addObject("medicos", medicos);
modelAndView.addObject("listaPacientes", pacientes);
modelAndView.addObject("consulta", new Consulta());
return modelAndView;
}
#RequestMapping(value = "/salvar", method = RequestMethod.POST)
public String salvar(#ModelAttribute Consulta consulta) {
consultadao.save(consulta);
return "redirect:medclin/home";
}
}
consultaDao.java
package br.com.medclin.boot.daos;
import java.io.Serializable;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import br.com.medclin.boot.models.Consulta;
#Repository
public interface ConsultaDao extends CrudRepository<Consulta , Integer>
{
}
EDIT:
as asked by #bphilipnyc
Paciente.java
#Entity
public class Paciente {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String nome;
private Calendar dataNascimento;
private String endereco;
#NotNull
private String cpf;
#ManyToOne
private Plano planoDeSaude;
public Paciente(String nome, Calendar dataNascimento, String endereco, String cpf, Plano plano) {
super();
this.nome = nome;
this.dataNascimento = dataNascimento;
this.endereco = endereco;
this.cpf = cpf;
this.planoDeSaude = plano;
}
public Paciente(String nome, Calendar dataNascimento, String endereco, String cpf) {
super();
this.nome = nome;
this.dataNascimento = dataNascimento;
this.endereco = endereco;
this.cpf = cpf;
}
public Paciente(String pctCpf) {
this.cpf = pctCpf;
}
public Paciente() {
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Calendar getDataNascimento() {
return this.dataNascimento;
}
public void setDataNascimento(Calendar dataNascimento) {
this.dataNascimento = dataNascimento;
}
public String getEndereco() {
return this.endereco;
}
public void setEndereco(String endereco) {
this.endereco = endereco;
}
public String getCpf() {
return this.cpf;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Plano getPlanoDeSaude() {
return planoDeSaude;
}
public void setPlanoDeSaude(Plano planoDeSaude) {
this.planoDeSaude = planoDeSaude;
}
public boolean equals(Paciente pct) {
if (this.id == pct.id)
return true;
else
return false;
}
#Override
public int hashCode() {
return super.hashCode();
}
#Override
public String toString() {
return "Paciente [id=" + id + ", nome=" + nome + ", dataNascimento=" + dataNascimento + ", endereco=" + endereco
+ ", cpf=" + cpf + ", planoDeSaude=" + planoDeSaude + "]";
}
}

The problem was solved. It seems that if you change your hibernate mapping, you must recreate the database. I did that and the problem was solved.

Related

Why iterate last data from ArrayList<>?

I get data from database perfectly and pass to the Thymeleaf(Template), but the problem is near mdl.addAttribute("number" ,request.getNumber()) in controller to detect last value from foreach loop iteration and send by model
Here down my code:
Dto
public interface ProfileDto {
public Integer getU_id();
public Integer getP_id();
public String getEmail();
public String getUsername();
public String getPassword();
public String getContact();
public String getDate();
public String getProfile();
public String getWebsite();
public String getBio();
public String getGender();
public String getPost();
}
Entity
#Entity
#Table(name = "request_master")
public class Request {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int req_id;
private int sender_id;
private int receiver_id;
private String status;
private String date;
#Transient
private int number;
// getter setter
}
Repository
public interface profileRepo extends JpaRepository<Request, Integer> {
#Query(nativeQuery = true, value = "SELECT * FROM registration_master rm INNER JOIN profile_master pm ON rm.u_id = pm.user_id WHERE rm.u_id != ?")
List<ProfileDto> findByIdUser(Integer Id);
public interface requestRepo extends JpaRepository<Request, Integer> {
#Query(nativeQuery = true, value="SELECT * FROM request_master WHERE sender_id = ? and receiver_id = ?")
List<Request> getSuggetionButton(Integer Sender_id, Integer Receiver_id);
}
Service
#Service
public class ServiceImpl implements Service {
#Autowired
private profileRepo profileRepo;
#Autowired
private requestRepo requestRepo;
#Override
public List<ProfileDto> getSuggestedList(Integer Id) {
return this.profileRepo.findByIdUser(Id);
}
#Override
public List<Request> getSuggestionButton(Integer Sender_id, Integer Receiver_id) {
return this.requestRepo.getSuggetionButton(Sender_id, Receiver_id);
}
}
Controller
#Controller
public class Controller {
#Autowired
private Service service;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Model mdl, Request request) {
int SessionId = Integer.parseInt(session.getAttribute("uid").toString());
List<ProfileDto> Suggestion_list = service.getSuggestedList(SessionId);
for(ProfileDto Suggestion_id : Suggestion_list)
{
List<Request> Friend_request = this.service.getSuggestionButton(SessionId, Suggestion_id.getU_id());
if(Friend_request.size() > 0)
{
request.setNumber(Friend_request.size());
}
else
{
request.setNumber(0);
}
}
mdl.addAttribute("number" ,request.getNumber());
mdl.addAttribute("suggestionList", Suggestion_list);
return "post";
}
}
Thymeleaf
<div class="follow-user-list" th:each="suggetionFriend : ${suggestionList}">
<div class="follow-user clearfix" th:id="'follow-user'+${suggetionFriend.u_id}">
<img th:src="${suggetionFriend.profile}" alt="" class="profile-photo-sm pull-left" />
<div class="name clearfix">
<h5>
</h5>
<div class='follow-unfollow-btn' th:id="'follow-unfollow-button'+${suggetionFriend.u_id}">
<div th:text="${number}">
</div>
</div>
</div>
</div>
</div>
in below image 1 is for condition matched and find data and 0 is for condition not matched and not find data
In My output i can get only last iterate data in both user
Output:
Expected output:
I think problem is to pass data from controller to thymeleaf
If you have good idea to transfer value from Controller to Template tell me please
You should maintain request for each profile/user instead of having single request, what I mean by that is you should have number of request for each profileId/userId, you can maintain a map of profileId/userId and number of request for that profile/user, and use that map in your template, try to modify your code as below
Controller
#Controller
public class Controller {
#Autowired
private Service service;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Model mdl, Request request) {
Map<Integer, Integer> profileToNoOfRequestMap = new HashMap<>();
int SessionId = Integer.parseInt(session.getAttribute("uid").toString());
List<ProfileDto> Suggestion_list = service.getSuggestedList(SessionId);
for(ProfileDto Suggestion_id : Suggestion_list)
{
List<Request> Friend_request = this.service.getSuggestionButton(SessionId, Suggestion_id.getU_id());
profileToNoOfRequestMap.put(Suggestion_id.getU_id(), Friend_request.size());
}
mdl.addAttribute("profileToNoOfRequestMap", profileToNoOfRequestMap);
mdl.addAttribute("suggestionList", Suggestion_list);
return "post";
}
}
Thymeleaf
<div class="follow-user-list" th:each="suggetionFriend : ${suggestionList}">
<div class="follow-user clearfix" th:id="'follow-user'+${suggetionFriend.u_id}">
<img th:src="${suggetionFriend.profile}" alt="" class="profile-photo-sm pull-left" />
<div class="name clearfix">
<h5>
</h5>
<div class='follow-unfollow-btn' th:id="'follow-unfollow-button'+${suggetionFriend.u_id}">
<div th:text="${profileToNoOfRequestMap.get(suggetionFriend.u_id)}">
</div>
</div>
</div>
</div>
</div>

Thymeleaf inserting new item in database generates error Property or field cannot be found on null

I'm in the process of learning spring. I'm using thymeleaf to create a simple web app that adds, edits and removes users from a database.
I'm using an html page to display the database and two separate pages for editing and adding new users.
Edit and remove work perfectly but whenever i try to add a user i get an error in new.html (new.html contains the form to add a new user)
Property or field xxxx cannot be found on null
The error shows up in the from at th:text="#{user.name}" .From what I've found online thymelaf does not take null values, however as this is a new object I am trying to add all values are null.
Is there any way to solve this. Code.
new.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>New User</title>
</head>
<body>
<form method="post" name="comment_form" id="comment_form" th:action="#{/create}" role="form">
Name:<br>
<input type="text" name="name" th:text="${user.name}"><br>
Age:<br>
<input type="text" name="age" th:text="${user.age}"><br>
Email: <br>
<input type="text" name="email" th:text="${user.email}"><br>
<button type="submit" id="submit" class="btn btn-primary">Submit</button>
</form>
</body>
</html>
Controller
#Autowired
UserService service;
#RequestMapping(value="user/new", method = RequestMethod.GET)
public String newUser(Long id, Model md) {
Users user = service.findOne(id);
md.addAttribute("user", user);
return "new";
}
#RequestMapping(value = "/create", method = RequestMethod.POST)
public String create(#RequestParam("id") Long id, #RequestParam("name") String name, #RequestParam("age") int age,
#RequestParam("email") String email, Model md) {
md.addAttribute("users", service.addOrUpdate(new Users(id, name, age)));
return "redirect:/user";
}
Service class
#Autowired
JdbcTemplate template;
public Users findOne(Long id)
{
String sql = "select * from people where id=" +id;
return template.query(sql, new ResultSetExtractor<Users>() {
#Override
public Users extractData(ResultSet resultSet) throws SQLException, DataAccessException {
if (resultSet.next()) {
Users user = new Users(resultSet.getLong("id"),
resultSet.getString("name"),
resultSet.getInt("age"));
String email = resultSet.getString("email");
if (email != null) {
user.setEmail(email);
}
return user;
}
return null;
}
});
}
public int addOrUpdate(Users user){
if (user.getId() > 0) {
String sql = "UPDATE people SET name=?, age =?, email=? WHERE id=" +user.getId();
System.out.println(sql);
return template.update(sql, user.getName(), user.getAge(), user.getEmail());
} else {
String sql = "INSERT INTO people ( name, age, email) VALUES ( ?, ?, ?)";
System.out.println(sql);
return template.update(sql, user.getName(), user.getAge(), user.getEmail());
}
}
Users (Model)
package ro.database.jdbcTest.model;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
public class Users {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String name;
private int age;
private String email;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getEmail() {
return email;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public Users(Long id, String name, int age){
this.id=id;
this.name=name;
this.age=age;
}
public void setEmail(String email){
this.email=email;
}
}
Since your user object is null you are getting that error.
All you need to do is send a new User() object every time a request with a new user comes.
#RequestMapping(value="user/new", method = RequestMethod.GET)
public String newUser(Long id, Model md) {
Users user = null;
if(id > 0) { // Id is present, fetch from the database.
user = service.findOne(id);
} else { // Create a new user.
user = new User();
}
md.addAttribute("user", user);
return "new";
}
Using the above way you will never have a null user in new.html

Selecting the option passed from the controller

I'm having trouble with the selection of the right value in a 'select' when the options are String. I can't find the solution in the forums.
I pass 'kind' in the controller and I can see that the values are fine but only the Integer fields are selected properly in the 'select'. The ones with String always show the first value and not the one pass in 'kind'.
I added the code I thought it could help
Can anyone help?
My HTML code. The form contains many 'select' but I left two, the first one works but the second one always show the first option:
<form role="form" th:action="#{/kind/update}" th:object="${kind}" method="post">
<div class="form-group col-md-4">
<label for="replicates">No. of Replicates</label>
<select id="replicates" class="form-control" style="width: 70%;" th:field="${kind.replicates}">
<option th:each="rep: ${replicatesnumber}" th:value="${rep}" th:text="${rep}"> </option>
</select>
</div>
<div class="form-group col-md-3">
<label for="substrate">Substrate</label>
<select id="substrate" class="form-control" th:field="${kind.substrate}">
<option th:each="substrate: ${substrates}" th:value="${substrate}" th:text="${substrate}"> </option>
</select>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary">Save</button>
<a class="btn btn-primary" th:href="#{/division/edit/}+${kind.division.id}" role="button">Cancel</a>
</div>
</form>
The controller look like this:
#Controller
#RequestMapping("/kind")
public class KindController {
#Autowired
private KindService kindService;
#ModelAttribute("replicatesnumber")
public int[] getReplicates() {
int[] reps = new int[3];
reps[0] = 2;
reps[1] = 4;
reps[2] = 8;
return reps;
}
#ModelAttribute("substrates")
public List<String> getSubstrates() {
return Arrays.asList("BP", "PP", "TP", "OGM", "Sand");
}
#GetMapping(value= "/edit/{kindId}")
public String viewDivision(#PathVariable Integer kindId, Model model){
Kind kind= kindService.findById(kindId);
model.addAttribute("kind",kind);
return "kind_edit";
}
and the entity:
#Entity
#Table(name = "kind", schema = "ostscourses")
public class Kind implements java.io.Serializable {
private Integer id;
private Division division;
private String name;
private Integer germinationDays;
private Integer firstCount;
private Integer replicates;
private Boolean dark;
private Integer chill;
private String temperature;
private String substrate;
private Integer noSeeds;
private List<Sample> samples;
public Kind() {
}
public Kind(Integer id, Division division) {
this.id = id;
this.division = division;
}
public Kind(Integer id, Division division, String name, Integer germinationDays, Integer firstCount, Integer replicates, Boolean dark, Integer chill, String temperature, String substrate, Integer noSeeds, List<Sample> samples) {
this.id = id;
this.division = division;
this.name = name;
this.germinationDays = germinationDays;
this.firstCount = firstCount;
this.replicates = replicates;
this.dark = dark;
this.chill = chill;
this.temperature = temperature;
this.substrate = substrate;
this.noSeeds = noSeeds;
this.samples = samples;
}
#Id
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "division_id", nullable = false)
#JsonIgnore
public Division getDivision() {
return this.division;
}
public void setDivision(Division division) {
this.division = division;
}
#Column(name = "name", length = 25)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "germination_days")
public Integer getGerminationDays() {
return this.germinationDays;
}
public void setGerminationDays(Integer germinationDays) {
this.germinationDays = germinationDays;
}
#Column(name = "first_count")
public Integer getFirstCount() {
return this.firstCount;
}
public void setFirstCount(Integer firstCount) {
this.firstCount = firstCount;
}
#Column(name = "replicates")
public Integer getReplicates() {
return this.replicates;
}
public void setReplicates(Integer replicates) {
this.replicates = replicates;
}
#Column(name = "dark")
public Boolean getDark() {
return this.dark;
}
public void setDark(Boolean dark) {
this.dark = dark;
}
#Column(name = "chill")
public Integer getChill() {
return this.chill;
}
public void setChill(Integer chill) {
this.chill = chill;
}
#Column(name = "temperature", length = 10)
public String getTemperature() {
return this.temperature;
}
public void setTemperature(String temperature) {
this.temperature = temperature;
}
#Column(name = "substrate", length = 5)
public String getSubstrate() {
return this.substrate;
}
public void setSubstrate(String substrate) {
this.substrate = substrate;
}
#Column(name = "no_seeds")
public Integer getNoSeeds() {
return this.noSeeds;
}
public void setNoSeeds(Integer noSeeds) {
this.noSeeds = noSeeds;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "kind")
#JsonIgnore
public List<Sample> getSamples() {
return this.samples;
}
public void setSamples(List<Sample> samples) {
this.samples = samples;
}
#Override
public int hashCode() {
int hash = 3;
hash = 47 * hash + Objects.hashCode(this.id);
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Kind other = (Kind) obj;
if (!Objects.equals(this.id, other.id)) {
return false;
}
return true;
}
#Override
public String toString() {
return "Kind{" + "id=" + id + ", name=" + name + ", germinationDays=" + germinationDays + ", firstCount=" + firstCount + ", replicates=" + replicates + ", dark=" + dark + ", chill=" + chill + ", temperature=" + temperature + ", substrate=" + substrate + ", noSeeds=" + noSeeds + '}';
}
}
Well, I just found a solution creating enum with the values I need in the select
public enum SubstrateType{
BP,
PP,
TP,
OGM,
Sand;
}
In my controller:
#ModelAttribute("substrates")
public SubstrateType[] getSubstrates() {
return SubstrateType.values();
}
I know it should work without enum as I have seen this before. Anyway I think is a good practice having enum.

springboot + thymeelaf form handling with select and object

Hello there,
I'm facing a problem - for several days now- that is: I need to save a form with a select/option that contains a reference to another class...but when the controller tries to save it fails. The console shows me nothing...any tips?
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Dec 11 17:00:10 BRST 2016
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='consulta'. Error count: 1
The form cadastro.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
...
</head>
<body>
<div th:replace="includes/header :: menu"></div>
<div id="consu" class="container">
<form action="#" th:action="#{salvar}" th:object="${consulta}" method="POST">
<div class="form-inline">
<label for="select-medico-consulta" class="form-group">Medico</label>
<select id="select-medico-consulta" th:field="*{medico}">
<div>
<option th:each="medico : ${medicos}" th:value="${medico}"
th:text="${medico.nome}" ></option>
</div>
</select>
<div class="form-group">
<label id="paciente-label" for="select-paciente-consulta" > Paciente</label>
</div>
</div>
<div class="form-group">
<label for="comment">Consulta</label>
<textarea class="form-control" rows="5" id="comment"></textarea>
</div>
<div class="checkbox">
<label>
<input type="checkbox"/> Internado
</label>
</div>
<button type="submit" class="btn btn-default">Salvar</button>
</form>
</div>
<div th:fragment="footer">
<p class="rodape">
<img class="img-responsive" src="/img/logo.jpg"
th:src="#{/img/logo.jpg}" alt="error" />
</p>
</div>
</body>
</html>
ConsultaController
#Controller
#RequestMapping("/medclin")
public class ConsultaController {
#Autowired
private ConsultaDao consultadao;
#Autowired
private MedicoDao medicoDao;
#Autowired
private PacienteDao pacienteDao;
#RequestMapping("/consulta")
public ModelAndView Consulta() {
ModelAndView modelAndView = new ModelAndView("consulta/consulta");
ArrayList<Medico> medicos = (ArrayList<Medico>) medicoDao.findAll();
ArrayList<Paciente> pacientes = (ArrayList<Paciente>) pacienteDao.findAll();
modelAndView.addObject("medicos", medicos);
modelAndView.addObject("pacientes", pacientes);
modelAndView.addObject("consulta", new Consulta());
return modelAndView;
}
#RequestMapping(value = "/salvar", method = RequestMethod.POST)
public String salvar(#ModelAttribute Consulta consulta) {
consultadao.save(consulta);
return "redirect:medclin/home";
}
}
the Model, consulta.java
#Entity
public class Consulta {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#ManyToOne
private Medico medico;
#ManyToMany
#JoinTable(name = "CONSULTA_PACIENTES")
private List<Paciente> pacientes = new ArrayList<>();
#ManyToMany
#JoinTable(name = "CONSULTA_RECEITA")
private List<Receita> receita = new ArrayList<>();
public Consulta(Medico med, List<Paciente> paciente) {
this.medico = med;
this.pacientes = paciente;
}
public Consulta() {
}
public Consulta(Medico medico2) {
this.medico = medico2;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<Paciente> getPct() {
return pacientes;
}
public void setPct(List<Paciente> pct) {
this.pacientes = pct;
}
public Medico getMedico() {
return medico;
}
public void setMedico(Medico medico) {
this.medico = medico;
}
public List<Receita> getReceita() {
return receita;
}
public void setReceita(List<Receita> receita) {
this.receita = receita;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((medico == null) ? 0 : medico.hashCode());
result = prime * result + ((pacientes == null) ? 0 : pacientes.hashCode());
result = prime * result + ((receita == null) ? 0 : receita.hashCode());
return result;
}
//TODO corrigir esse erro
public boolean equals(Consulta cons) {
if (this.id == cons.getId())
return true;
else
return false;
}
#Override
public String toString() {
return "Consulta [id=" + id + ", medico=" + medico + ", pacientes=" + pacientes + ", receita=" + receita + "]";
}
}
Try
<select id="select-medico-consulta" th:field="*{medico.id}">
<option th:each="medicoEntry : ${medicos}" th:value="${medicoEntry.id}"
th:text="${medicoEntry.nome}" ></option>
</select>

Adding error message to Spring 3 DataBinder for custom object fields

I'm trying to manually add an individual email error message to my model but nothing is displaying in the view.
I think it may be how I'm creating or attached the ObjectError to the BindingResult.
I'm adding the error inside the catch.
Here is the contents of result.errors when I leave email field empty and JSR-303 annotations kick in (error displays in view):
[Field error in object 'user' on field 'email': rejected value []; codes [NotEmpty.user.email,NotEmpty.email,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.email,email]; arguments []; default message [email]]; default message [may not be empty]]
Here is the contents of of result.errors after I manually add the ErrorObject(email error does not display in view):
[Error in object 'email': codes []; arguments []; default message [An account already exists for this email.]]
Controller:
#RequestMapping(value = "/registration", method = RequestMethod.POST)
public ModelAndView post(#Valid User user, BindingResult result)
{
if (result.hasErrors())
{
ModelAndView modelAndView = new ModelAndView(
Consts.MODEL_RESISTER_PAGE);
modelAndView.addObject("user", user);
return modelAndView;
}
else
{
try
{
userService.addUser(user);
ModelAndView modelAndView = new ModelAndView(
Consts.MODEL_CARD_REPORTS_HOME_PAGE);
modelAndView.addObject("userRegisteredSuccess", Boolean.TRUE);
return modelAndView;
}
catch (DataIntegrityViolationException ex)
{
ObjectError error = new ObjectError("email","An account already exists for this email.");
result.addError(error);
ModelAndView modelAndView = new ModelAndView(
Consts.MODEL_RESISTER_PAGE);
modelAndView.addAllObjects(result.getModel());
modelAndView.addObject("user", user);
return modelAndView;
}
}
}
My Model:
#Entity
public class User implements Serializable
{
/**
*
*/
private static final long serialVersionUID = -5232533507244034448L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotEmpty
#Size(min=2, max=15)
private String firstname;
#NotEmpty
#Size(min=2, max=15)
private String surname;
#NotEmpty
#Email
private String email;
#NotEmpty
#Size(min=6, max=10)
private String password;
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 getSurname()
{
return surname;
}
public void setSurname(String surname)
{
this.surname = surname;
}
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;
}
}
File add.html
<form id="registrationForm" action="#" th:action="#{/registration}" th:object="${user}" method="post" class="clearfix">
<legend>Registration</legend>
<div class="control-group input" th:class="${#fields.hasErrors('firstname')}? 'control-group input error'">
<input type="text" th:field="*{firstname}" placeholder="Firstname" />
<span class="help-block" th:if="${#fields.hasErrors('firstname')}" th:errors="*{firstname}"></span>
</div>
<div class="control-group input" th:class="${#fields.hasErrors('surname')}? 'control-group input error'">
<input type="text" th:field="*{surname}" placeholder="Surname" />
<span class="help-block" th:if="${#fields.hasErrors('surname')}" th:errors="*{surname}"></span>
</div>
<div class="control-group input" th:class="${#fields.hasErrors('email')}? 'control-group input error'">
<input type="text" th:field="*{email}" placeholder="Email" />
<span class="help-block" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></span>
</div>
<div class="control-group input" th:class="${#fields.hasErrors('password')}? 'control-group input error'">
<input type="password" th:field="*{password}" placeholder="Password" />
<span class="help-block" th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></span>
</div>
<div class="clearfix">
<input type="submit" class="btn btn-success btn-large" value="Register" />
</div>
</form>
I usually call result.rejectValue("property", "error.object"); to add errors to BindingResult. If you want to add a global object error, you could use result.reject("error.object");.
So, in your code, instead of:
ObjectError error = new ObjectError("email","An account already exists for this email.");
result.addError(error);
try with:
result.rejectValue("email", "error.user", "An account already exists for this email.");
Check the reference here.
Hope this helps.

Resources