I am trying to save an uploaded file as Blob in a MySql record. I am new to Spring. When I am about to save the record after uploading a file, then when my POST method updateCandidate() executes, I get this exception:
Field error in object 'candidateForm' on field 'cv': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile#59c09df6]; codes [typeMismatch.candidateForm.cv,typeMismatch.cv,typeMismatch.java.sql.Blob,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [candidateForm.cv,cv]; arguments []; default message [cv]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.sql.Blob' for property 'cv'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.sql.Blob' for property 'cv': no matching editors or conversion strategy found]
What is going wrong? How to fix?
My entity:
import java.sql.Blob;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
#Entity
public class Candidate {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(unique = true)
private String ssn;
private String name;
private String surname;
private String technology;
private String media;
#Lob
private Blob cv;
private boolean activeCV;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
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;
}
public String getTechnology() {
return technology;
}
public void setTechnology(String technology) {
this.technology = technology;
}
public String getMedia() {
return media;
}
public void setMedia(String media) {
this.media = media;
}
public Blob getCv() {
return cv;
}
public void setCv(Blob cv) {
this.cv = cv;
}
public boolean isActiveCV() {
return activeCV;
}
public void setActiveCV(boolean activeCV) {
this.activeCV = activeCV;
}
}
In my service:
#Autowired
private CandidateRepository repository;
...
public Optional<Candidate> getCandidate(Long id){
return repository.findById(id);
}
public void addOrUpdateCandidate(Candidate candidate) {
repository.save(candidate);
}
In my controller:
#Controller
#RequestMapping("/candidates")
public class CandidateController {
#Autowired
private EntityManagerFactory emf;
#Autowired
private CandidateService service;
...
#GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(#PathVariable("id") Long id, Model model) {
Candidate candidate = service.getCandidate(id).get();
model.addAttribute("candidateForm", candidate);
return "updateCandidateForm";
}
#PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(#ModelAttribute("candidateForm") Candidate candidate, #RequestParam("cv") MultipartFile file) throws IOException {
InputStream iStream = file.getInputStream();
long size = file.getSize();
Session session = emf.unwrap(Session.class);
Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);
candidate.setCv(cv);
service.addOrUpdateCandidate(candidate);
return "updateCandidateResult";
}
}
My updateCandidateForm.jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<body>
<form:form method="POST" action="updateCandidateResult" modelAttribute="candidateForm" enctype="multipart/form-data">
<form:hidden path="id"/>
<table>
<tr>
<td><form:label path="name">Name</form:label></td>
<td><form:input path="name"/></td>
</tr>
<tr>
<td><form:label path="surname">Surname</form:label></td>
<td><form:input path="surname"/></td>
</tr>
<tr>
<td><form:label path="ssn">SSN</form:label></td>
<td><form:input path="ssn"/></td>
</tr>
<tr>
<td><form:label path="technology">Known Technology</form:label></td>
<td><form:input path="technology"/></td>
</tr>
<tr>
<td><form:label path="media">Found us on</form:label></td>
<td><form:input path="media"/></td>
</tr>
<tr>
<td><form:label path="cv">Select a cv</form:label></td>
<td><input type="file" name="cv" /></td>
</tr>
<tr>
<td><form:label path="activeCV">Active CV</form:label></td>
<td><form:checkbox path="activeCV" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit"/></td>
</tr>
</table>
</form:form>
</body>
In my POM:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
EDIT 1 (question):
Would there be even a way of preventing Spring from trying to convert MultipartFile to Blob at "Submit-time", triggering this operation sooner, having the POST method already manage the Candidate (with Blob field already set) object?
EDIT 2:
as suggested by JB Nizet, I tried to use a support POJO, which has the field CV of the type MultipartFile, to store temporarily what I post via form (text fields + file field), and I don't get that exception anymore, because at "Submit-time" the populated object has the cv field of the type of the uploaded file:
import org.springframework.web.multipart.MultipartFile;
public class CandidatePOJO {
private Long id;
private String ssn;
private String name;
private String surname;
private String technology;
private String media;
private MultipartFile cv;
private boolean activeCV;
#Override
public String toString() {
return "CandidatePOJO [id=" + id + ", ssn=" + ssn + ", name=" + name + ", surname=" + surname + ", technology="
+ technology + ", media=" + media + ", cv=" + cv + ", activeCV=" + activeCV + "]";
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
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;
}
public String getTechnology() {
return technology;
}
public void setTechnology(String technology) {
this.technology = technology;
}
public String getMedia() {
return media;
}
public void setMedia(String media) {
this.media = media;
}
public MultipartFile getCv() {
return cv;
}
public void setCv(MultipartFile cv) {
this.cv = cv;
}
public boolean isActiveCV() {
return activeCV;
}
public void setActiveCV(boolean activeCV) {
this.activeCV = activeCV;
}
}
in controller, now my first concern is to see whether the pojo can be correctly instantiated, so my GET-POST pair is:
#GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(#PathVariable("id") Long id, Model model) {
CandidatePOJO candidatePOJO = new CandidatePOJO();
candidatePOJO.setId(id);
model.addAttribute("candidateForm", candidatePOJO);
return "updateCandidateForm";
}
#PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(#ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) {
System.out.println("CANDIDATE POJO");
System.out.println(candidatePOJO.toString()); // here I notice id = null
/* MultipartFile to Blob conversion */
// MultipartFile file = candidatePOJO.getCv();
// InputStream iStream = file.getInputStream();
// long size = file.getSize();
// Session session = emf.unwrap(Session.class);
// Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);
/* instantiating the entity object to be freezed in db */
// Candidate candidate = new Candidate();
// set all data from candidatePOJO..
// candidate.setCv(cv);
// service.addOrUpdateCandidate(candidate);
return "updateCandidateResult";
}
and I get a CandidatePOJO object with no id set. I don't manage to have the id pass from GET to POST. Does anyone know what is gong wrong?
EDIT 3:
after many days I opted for the solution with a support POJO, unbelievably I am noticing that the ID is passed from the GET method to the POST one (I haven't changed anything, I have just performed the classical Maven project cleaning as I did when I posted my issue). Unluckily I am facing now another exception (after restoring the code previously commented in the POST method, of course):
javax.persistence.PersistenceException: Hibernate cannot unwrap EntityManagerFactory as 'org.hibernate.Session'
How to fix that?
EDIT 4:
Exception just above solved replacing:
Session session = emf.unwrap(Session.class);
with:
EntityManager em = emf.createEntityManager();
Session session = (Session) em.getDelegate();
BY USING SUPPORT POJO, I finally solved. Indeed I had already solved earlier, by code. The code in the post is right (EDIT 2). When I often performed Maven project cleaning, this didn't discover the errors. I performed it in the last hours and unbelievably my code worked. I can't guess the magic :D I don't know what really happened. By code, I solved in two different ways. First:
#Autowired
private EntityManagerFactory emf;
// ........
#GetMapping("/updateCandidate/{id}")
public String showUpdateUserForm(#PathVariable("id") Long id, Model model) {
Candidate candidate = service.getCandidate(id).get();
CandidatePOJO candidatePOJO = new CandidatePOJO();
candidatePOJO.setId(id);
candidatePOJO.setName(candidate.getName());
candidatePOJO.setSurname(candidate.getSurname());
candidatePOJO.setSsn(candidate.getSsn());
candidatePOJO.setMedia(candidate.getMedia());
candidatePOJO.setTechnology(candidate.getTechnology());
candidatePOJO.setActiveCV(candidate.isActiveCV());
model.addAttribute("candidateForm", candidatePOJO);
return "updateCandidateForm";
}
#PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(#ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) throws IOException {
MultipartFile file = candidatePOJO.getCv();
InputStream iStream = file.getInputStream();
long size = file.getSize();
EntityManager em = emf.createEntityManager();
Session session = (Session) em.getDelegate();
Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);
Candidate candidate = new Candidate();
candidate.setId(candidatePOJO.getId());
candidate.setName(candidatePOJO.getName());
candidate.setSurname(candidatePOJO.getSurname());
candidate.setSsn(candidatePOJO.getSsn());
candidate.setMedia(candidatePOJO.getMedia());
candidate.setTechnology(candidatePOJO.getTechnology());
candidate.setActiveCV(candidatePOJO.isActiveCV());
candidate.setCv(cv);
service.addOrUpdateCandidate(candidate);
return "updateCandidateResult";
}
Second (with the same GET):
#PostMapping("/updateCandidate/updateCandidateResult")
public String updateCandidate(#ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) throws IOException, SerialException, SQLException {
MultipartFile file = candidatePOJO.getCv();
Blob cv = new SerialBlob(file.getBytes());
Candidate candidate = new Candidate();
candidate.setId(candidatePOJO.getId());
candidate.setName(candidatePOJO.getName());
candidate.setSurname(candidatePOJO.getSurname());
candidate.setSsn(candidatePOJO.getSsn());
candidate.setMedia(candidatePOJO.getMedia());
candidate.setTechnology(candidatePOJO.getTechnology());
candidate.setActiveCV(candidatePOJO.isActiveCV());
candidate.setCv(cv);
service.addOrUpdateCandidate(candidate);
return "updateCandidateResult";
}
Being new to Spring, I don't know the differences yet. I would appreciate a lot an explanation. Moreover, I want to modify, sooner or later, this code, in order to get rid of the support POJO and to work with just the entity objects: if anyone can solve my initial issue, I would be forever grateful!
Related
hope you can help with this simple noob problem. I creating a Multiple choice question using springboot and thymeleaf.I am getting this error and hope you can help me write the controller method.
Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (learning:23)
Neither BindingResult nor plain target object for bean name 'options[0]' available as request attribute
<form method="post" th:action="#{/list}" >
<table>
<tr th:each="option, rowStat : *{a}">
<td><input type="radio" th:field="*{options[__${rowStat.index}__].ansA}" th:value="A"/></td>
<td><input type="radio" th:field="*{options[__${rowStat.index}__].ansB}" th:value="B"/></td>
</tr>
</table>
<input type="submit" value="ok"/>
</form>
Model object
#Entity
public class LearningStyle {
private int Qid;
private String question;
private String ansA;
private String ansB;
public LearningStyle(int qid, String question, String ansA, String ansB) {
Qid = qid;
this.question = question;
this.ansA = ansA;
this.ansB = ansB;
}
public LearningStyle(){}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "Qid", nullable = false, updatable = false)
public int getQid() {
return Qid;
}
public void setQid(int qid) {
Qid = qid;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getAnsA() {
return ansA;
}
public void setAnsA(String ansA) {
this.ansA = ansA;
}
public String getAnsB() {
return ansB;
}
public void setAnsB(String ansB) {
this.ansB = ansB;
}
}
Controller
public class LearningStyleController {
#Autowired
LearningStyleService learningstyleservice;
#RequestMapping("/list")
public String learningstyle(Model model) {
List<LearningStyle> a= learningstyleservice.findAll();
model.addAttribute("a",a);
return "learning";
}
#RequestMapping(value = "/list", method = RequestMethod.POST)
public String learn(#ModelAttribute("a") LearningStyle learningStyle, Model model) {
//code to get list of object
return "home";
}
have a very simple question on JSTL tags.
I am using spring to fetch data from back-end and display in the JSP.
Have the following code. I am getting the items of the for each tag printed in the console. But the same items are not getting printed/displayed inside the table rows.
<table id="table_id" class="display">
<thead>
<tr>
<th>Movie Name</th>
<th>Movie Rating</th>
</tr>
</thead>
<tbody>
<c:forEach items="${model.movieslist}" var="movie">
<tr>
<td>${movie.name}</td>
<td>${movie.rating}</td>
</tr>
</c:forEach>
</tbody>
My spring controller class
public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// TODO Auto-generated method stub
logger.info("returning hello view");
List<Movie> moviesList = DbManager.getInstance().getMovies();
ModelMap modelMap = new ModelMap();
modelMap.addAttribute("movieslist", moviesList);
return new ModelAndView("hello.jsp",modelMap);
}
Movie domain class
package springapp.domain;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "movie")
public class Movie {
#Id
public String _id;
public String name;
public String getId() {
return _id;
}
public void setId(String _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getRating() {
return rating;
}
public void setRating(float rating) {
this.rating = rating;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public float rating;
public String date;
#Override
public String toString() {
// TODO Auto-generated method stub
return name;
}
}
First, your jsp should contain the following taglib
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Second, you don't need to get it using ${model.moviesList}, modify it as follows:
<c:forEach items="${movieslist}" var="movie">
I have written a program to display some details entered in one form in another.Like I have a UserRegisteration.jsp where I am entering few details and UserAccount.jsp which has to display some of the entered details.I have created a model object UserDetails which has all the details of a particular code.
When I am running the project I am getting the propertynotfound exception.I have checked everything and couldn't find the reason behind it.I have the getters and setters methods in my model class.And using auto-binding feature using #modelattribute.Kindly let me know if I missed any code.
UserDetails.java
package com.bindu.myBankcontroller;
import java.util.ArrayList;
public class UserDetails {
private String UserName;
private String FirstName;
private String LastName;
private String EmailId;
private ArrayList<String> AccountType;
private ArrayList<String> gender;
private Long AccountNo;
private int age;
private String password;
Address address;
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getEmailId() {
return EmailId;
}
public void setEmailId(String emailId) {
EmailId = emailId;
}
public ArrayList<String> getAccountType() {
return AccountType;
}
public void setAccountType(ArrayList<String> accountType) {
AccountType = accountType;
}
public ArrayList<String> getGender() {
return gender;
}
public void setGender(ArrayList<String> gender) {
this.gender = gender;
}
public Long getAccountNo() {
return AccountNo;
}
public void setAccountNo(Long accountNo) {
AccountNo = accountNo;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Controller class,UserAccountController.java
package com.bindu.myBankcontroller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.*;
import org.springframework.web.servlet.ModelAndView;
import com.bindu.myBankcontroller.UserDetails;
#Controller
public class UserAccountController {
#ModelAttribute
public void addingCommonObjects(Model model1) {
model1.addAttribute("headerMessage", "MyBank, India");
}
#RequestMapping(value="/LoginForm.html", method = RequestMethod.GET)
public ModelAndView getAdmissionForm() {
ModelAndView model1 = new ModelAndView("LoginForm");
return model1;
}
#RequestMapping(value="/userRegistration.html", method = RequestMethod.GET)
public ModelAndView submitRegistrationForm() {
ModelAndView model1 = new ModelAndView("UserRegistration");
return model1;
}
#RequestMapping(value="/UserAccount.html", method = RequestMethod.POST)
public ModelAndView userAccountForm(#ModelAttribute("user") UserDetails user) {
System.out.println("User name:"+user.getUserName());
ModelAndView model1 = new ModelAndView("UserAccount");
return model1;
}
}
UserAccount.jsp
<html>
<body>
<h1>${headerMessage}</h1>
<h3>Congratulations!! you have successfully registered</h3>
<h2>Details submitted by you:: </h2>
<table>
<tr>
<td>User Name :</td>
<td>${user.UserName}</td>
</tr>
<tr>
<td>First Name :</td>
<td>${user.FirstName}</td>
</tr>
<tr>
<td>Last Name :</td>
<td>${user.LastName}</td>
</tr>
</table>
</body>
</html>
None of the related posts helped me in resolving this issue, so I have posted this one.
The problem is cause by the way you are accessing your property in jsp,
${user.UserName}
should instead be
${user.userName}
Same for the other expressions, you should lower case the first letter.
Behind the scenes the UserDetails is introspected and a map of properties is created, but the keys are based on your getter/setter methods, so lowercased (userName, firstName, lastName). In your JSP EL you're passing the key, and it is not matching any property on account of case difference
Your instance variables do not respect the java naming principles. Java variables should start with lower letter and use camel case capitalization.
Ex: userName, firstName, lastName,
and the corresponding getters would be getUserName(), getFirstName(), getLastName().
If you have the instance variable defined like this the jsp accessors will be obtained by stripping the get (or is, if the method returns a boolean) suffix and lower the first letter of the remaining method name: ${user.userName}, ${user.firstName}, ${user.lastName}.
Since I've decided to use same JSP for adding and editing posts, I just pass an attribute "saveUrl" which defines the action for my form in the JSP. Adding a new post works fine, but when editing a post, the object returned to the controller is missing all attributes except for the description.
What am I missing or doing wrong here?
Thanks for help!
My controller:
#Controller
public class BlogController {
private static final Logger logger = LoggerFactory.getLogger(BlogController.class);
#Autowired
private BlogPostManager bpManager;
#Autowired
private UserManager usrManager;
.....
#RequestMapping(value = "addPost", method = RequestMethod.GET)
public String addPost(Locale locale, Model model, Principal principal) {
model.addAttribute("post", new BlogPostEntity());
/** some more code here **/
return "addEditPost";
}
#RequestMapping(value = "addPostProcess", method = RequestMethod.POST)
public String addPostProcess(Locale locale, Model model, Principal principal, #ModelAttribute("post") BlogPostEntity blogPost) {
blogPost.setDate(new Date());
blogPost.setAuthor(usrManager.getUser(principal.getName()));
bpManager.addBlogPost(blogPost);
return "redirect:/latest";
}
#RequestMapping(value = "editPost/{id}", method = RequestMethod.GET)
public String editPost(Locale locale, Model model, Principal principal, #PathVariable Integer id) {
model.addAttribute("post", bpManager.getBlogPost(id));
model.addAttribute("username", getUsername(principal));
model.addAttribute("saveUrl", "");
return "addEditPost";
}
#RequestMapping(value = "editPost/{id}", method = RequestMethod.POST)
public String editPostProcess(Locale locale, Model model, Principal principal, #ModelAttribute("post") BlogPostEntity blogPost) {
bpManager.updateBlogPost(blogPost);
return "redirect:/latest";
}
/** some private methods **/
}
addEditPost.jsp
NOTE: this jsp is acting as a body of Apache tiles.
<h2>Create new post:</h2>
<form:form modelAttribute="post" action="${saveUrl}" method='POST'>
<table>
<tr>
<td><form:label path="title">Title:</form:label></td>
<td><form:input path="title"></form:input></td>
</tr>
<tr>
<td><form:label path="description">Description:</form:label></td>
<td><form:input path="description"></form:input></td>
</tr>
<tr>
<td><form:label path="text">Text:</form:label></td>
<td><form:input path="text"></form:input></td>
</tr>
<tr>
<td><input value="Save" type="submit"></td>
<td></td>
</tr>
</table>
</form:form>
The mapped BlogPost class:
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name = "BLOGPOST")
public class BlogPostEntity {
#Id
#GeneratedValue
#Column(name = "ID")
private int id;
#Column(name = "TITLE", nullable = false, length = 100)
private String title;
#Column(name = "DESCRIPTION", length = 500)
private String description;
#Column(name = "TEXT", length = 5000)
private String text;
#Column(name = "DATE")
private Date date;
#ManyToOne(targetEntity = UserEntity.class)
#JoinColumn(name = "authorid", referencedColumnName = "id")
private UserEntity author;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public int getId() {
return id;
}
public void setAuthor(UserEntity author) {
this.author = author;
}
public UserEntity getAuthor() {
return author;
}
}
DAO for blogpost:
import java.util.ArrayList;
import java.util.List;
import org.danizmax.simpleblog.entity.BlogPostEntity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
#Repository("blogpostdao")
public class BlogPostDaoImpl implements BlogPostDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public void addBlogPost(BlogPostEntity blogPost) {
getSession().persist(blogPost);
}
#Override
public void removeBlogPost(int id) {
BlogPostEntity entity = (BlogPostEntity) sessionFactory.getCurrentSession().load(BlogPostEntity.class, id);
if (entity != null) {
getSession().delete(entity);
}
}
#Override
#SuppressWarnings("unchecked")
public List<BlogPostEntity> latest() {
List<BlogPostEntity> result = new ArrayList<BlogPostEntity>();
try {
result = getSession().createQuery("FROM BlogPostEntity ORDER BY 'id' desc LIMIT 5;").list();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
#Override
#SuppressWarnings("unchecked")
public List<BlogPostEntity> listPosts(int userId) {
List<BlogPostEntity> result = new ArrayList<BlogPostEntity>();
try {
result = getSession().createQuery("FROM UserEntity").list();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
#Override
public void updateBlogPost(BlogPostEntity blogPost) {
blogPost = getBlogPost(blogPost.getId());
getSession().update(blogPost);
}
#Override
public BlogPostEntity getBlogPost(int id) {
return (BlogPostEntity) getSession().get(BlogPostEntity.class, id);
}
private Session getSession() {
return sessionFactory.getCurrentSession();
}
}
UPDATE: I've been experimenting a bit and tried method from HERE, but the object returned to the controler was still empty.
Then I changed the saveURL in JSP to (I read it might be important HERE):
<c:url var="addUrl" value="/secure/postProcess"/>
<form:form modelAttribute="post" action="${addUrl}" method='POST'>
and now the object is filled, only the id is still empty. So there is something probably wrong with the JSP.
I am newbie to Spring MVC.
I was stuck by an error while running my project
Error-The request sent by the client was syntactically incorrect.
I have an entity class PatientInfo.
My jsp page is demo1.
My controller is Patient Controller.
The functionality i want to implement is Inserting values into database.
But i am not able to call my function(add-update2) in controller.
demo1.jsp
<%#taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>Registration Form</title>
</head>
<body>
<h2 align="center">Full Registration Form</h2>
<hr />
<table align="center" cellpadding="5" cellspacing="5">
<form:form modelAttribute="patientInfo" method="POST" action="add-update2">
<tr>
<td> First Name</td>
<td><form:input path="firstName"/></td>
</tr>
<tr>
<td>Middle Name</td>
<td><form:input path="middleName" /></td>
</tr>
<tr>
<td>Last Name</td>
<td><form:input path="lastName"/>
</td>
</tr>
<tr>
<td>Age</td>
<td><form:input path="age" /></td>
</tr>
<tr>
<td>Gender</td>
<td><form:select path="gender">
<form:option value="" label="Select Gender" />
<form:options items="${genderList}" itemLabel="gender" itemValue="gender" />
</form:select></td>
</tr>
<tr>
<td>Marital Status</td>
<td><form:select path="maritalStatus">
<form:option value="" label="Select Marital Status" />
<form:options items="${maritalList}" itemLabel="maritalstatus" itemValue="maritalstatus" />
</form:select></td>
</tr>
<tr>
<td>Nationality</td>
<td><form:select path="nationality">
<form:option value="" label="Select Nationality" />
<form:options items="${nationalityList}" itemLabel="country" itemValue="country" />
</form:select></td>
</tr>
<tr name="tstest">
<td>Date Of Birth</td>
<td><form:input path="dateOfBirth" name="timestamp" value=""/>
<img src="../images/cal.gif" width="16" height="16" border="0" alt="Click Here to Pick up the timestamp">
</td>
</tr>
<tr>
<td>E-mail</td>
<td><form:input path="email"/></td>
</tr>
<tr>
<td>Blood Group</td>
<td><form:select path="bloodGroup">
<form:option value="" label="Select Blood Group" />
<form:options items="${bloodList}" itemLabel="bloodgroupname" itemValue="bloodgroupname" />
</form:select></td>
</tr>
<tr>
<td><input type="submit" value="submit"/></td>
</tr>
</form:form>
</table>
</body>
</html>
Controller-PatientController.java
package com.app.ehr.api;
import com.app.ehr.domain.Bloodgroup;
import com.app.ehr.domain.Gendertype;
import com.app.ehr.entities.Patientinfo;
import com.app.ehr.domain.Maritalstatus;
import com.app.ehr.domain.Nationality;
import com.app.ehr.model.Patient;
import com.app.ehr.service.PatientService;
import org.springframework.stereotype.Controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class PatientController {
public PatientService patientService;
#Autowired
public PatientController(PatientService patientService){
this.patientService = patientService;
}
#RequestMapping(value="/", method= RequestMethod.GET)
public String index(ModelMap map) {
return "index";
}
#RequestMapping(value="/full-reg", method= RequestMethod.GET)
public String fullreg(ModelMap map,Patientinfo patientInfo) {
List<Bloodgroup> bloodList = new ArrayList<Bloodgroup>();
List<Gendertype> genderList = new ArrayList<Gendertype>();
List<Nationality> nationalityList = new ArrayList<Nationality>();
List<Maritalstatus> maritalList = new ArrayList<Maritalstatus>();
bloodList=patientService.getAllBloodgroup();
genderList= patientService.getAllGendertype();
nationalityList=patientService.getAllNationality();
maritalList=patientService.getAllMaritalstatus();
for(int i=0;i<bloodList.size();i++)
{
System.out.println("---------------------Controller"+bloodList.get(i));
}
// map.addAttribute("hello", "Hello Spring from Netbeans!!");
map.addAttribute("patientInfo", patientInfo);
map.addAttribute("bloodList", patientService.getAllBloodgroup());
map.addAttribute("genderList", patientService.getAllGendertype());
map.addAttribute("maritalList", patientService.getAllMaritalstatus());
map.addAttribute("nationalityList", patientService.getAllNationality());
return "demo1";
}
#RequestMapping(value="/add-update2", method= RequestMethod.POST)
public String addUpdate(#ModelAttribute("patientInfo") Patientinfo patientInfo) {
System.out.println("----------------------------------------- From Controller------------------------------------------------");
//patientService.addPatient(patientInfo);
return "redirect:/full-reg";
}
}
Entity Class- PatientInfo.java
package com.app.ehr.entities;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
*
* #author HP LAPTOP
*/
#Entity
#Table(name = "patientinfo")
#NamedQueries({
#NamedQuery(name = "Patientinfo.findAll", query = "SELECT p FROM Patientinfo p")})
public class Patientinfo implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#Column(name = "PatientKey")
private Long patientKey;
#Column(name = "PatientMRNumber")
private String patientMRNumber;
#Column(name = "IntPrimaryPhysicianKey")
private BigInteger intPrimaryPhysicianKey;
#Column(name = "FirstName")
private String firstName;
#Column(name = "MiddleName")
private String middleName;
#Column(name = "LastName")
private String lastName;
#Column(name = "Age")
private Short age;
#Column(name = "Gender")
private String gender;
#Column(name = "Nationality")
private String nationality;
#Column(name = "DateOfBirth")
#Temporal(TemporalType.TIMESTAMP)
private Date dateOfBirth;
#Column(name = "MaritalStatus")
private String maritalStatus;
#Column(name = "Occupation")
private String occupation;
#Column(name = "AnnualIncome")
private String annualIncome;
#Column(name = "BloodGroup")
private String bloodGroup;
#Column(name = "Email")
private String email;
#Column(name = "ModeOfPayment")
private String modeOfPayment;
#Column(name = "ModeOfPaymentAlt")
private String modeOfPaymentAlt;
#Column(name = "ExtPrimaryPhysicianName")
private String extPrimaryPhysicianName;
#Column(name = "ExtPrimaryPhysicianPhoneNumber")
private String extPrimaryPhysicianPhoneNumber;
#Column(name = "IsDeleted")
private Boolean isDeleted;
#Column(name = "Meta_CreatedByUser")
private String metaCreatedByUser;
#Column(name = "Meta_UpdatedDT")
#Temporal(TemporalType.TIMESTAMP)
private Date metaUpdatedDT;
#Column(name = "Meta_CreatedDT")
#Temporal(TemporalType.TIMESTAMP)
private Date metaCreatedDT;
public Patientinfo() {
}
public Patientinfo(Long patientKey) {
this.patientKey = patientKey;
}
public Long getPatientKey() {
return patientKey;
}
public void setPatientKey(Long patientKey) {
this.patientKey = patientKey;
}
public String getPatientMRNumber() {
return patientMRNumber;
}
public void setPatientMRNumber(String patientMRNumber) {
this.patientMRNumber = patientMRNumber;
}
public BigInteger getIntPrimaryPhysicianKey() {
return intPrimaryPhysicianKey;
}
public void setIntPrimaryPhysicianKey(BigInteger intPrimaryPhysicianKey) {
this.intPrimaryPhysicianKey = intPrimaryPhysicianKey;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Short getAge() {
return age;
}
public void setAge(Short age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getMaritalStatus() {
return maritalStatus;
}
public void setMaritalStatus(String maritalStatus) {
this.maritalStatus = maritalStatus;
}
public String getOccupation() {
return occupation;
}
public void setOccupation(String occupation) {
this.occupation = occupation;
}
public String getAnnualIncome() {
return annualIncome;
}
public void setAnnualIncome(String annualIncome) {
this.annualIncome = annualIncome;
}
public String getBloodGroup() {
return bloodGroup;
}
public void setBloodGroup(String bloodGroup) {
this.bloodGroup = bloodGroup;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getModeOfPayment() {
return modeOfPayment;
}
public void setModeOfPayment(String modeOfPayment) {
this.modeOfPayment = modeOfPayment;
}
public String getModeOfPaymentAlt() {
return modeOfPaymentAlt;
}
public void setModeOfPaymentAlt(String modeOfPaymentAlt) {
this.modeOfPaymentAlt = modeOfPaymentAlt;
}
public String getExtPrimaryPhysicianName() {
return extPrimaryPhysicianName;
}
public void setExtPrimaryPhysicianName(String extPrimaryPhysicianName) {
this.extPrimaryPhysicianName = extPrimaryPhysicianName;
}
public String getExtPrimaryPhysicianPhoneNumber() {
return extPrimaryPhysicianPhoneNumber;
}
public void setExtPrimaryPhysicianPhoneNumber(String extPrimaryPhysicianPhoneNumber) {
this.extPrimaryPhysicianPhoneNumber = extPrimaryPhysicianPhoneNumber;
}
public Boolean getIsDeleted() {
return isDeleted;
}
public void setIsDeleted(Boolean isDeleted) {
this.isDeleted = isDeleted;
}
public String getMetaCreatedByUser() {
return metaCreatedByUser;
}
public void setMetaCreatedByUser(String metaCreatedByUser) {
this.metaCreatedByUser = metaCreatedByUser;
}
public Date getMetaUpdatedDT() {
return metaUpdatedDT;
}
public void setMetaUpdatedDT(Date metaUpdatedDT) {
this.metaUpdatedDT = metaUpdatedDT;
}
public Date getMetaCreatedDT() {
return metaCreatedDT;
}
public void setMetaCreatedDT(Date metaCreatedDT) {
this.metaCreatedDT = metaCreatedDT;
}
#Override
public int hashCode() {
int hash = 0;
hash += (patientKey != null ? patientKey.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Patientinfo)) {
return false;
}
Patientinfo other = (Patientinfo) object;
if ((this.patientKey == null && other.patientKey != null) || (this.patientKey != null && !this.patientKey.equals(other.patientKey))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.app.ehr.entities.Patientinfo[ patientKey=" + patientKey + " ]";
}
}
I think the issue is that Spring doesn't know how to deserialize the date your browser client sends when submitting the following input field in
<tr name="tstest">
<td>Date Of Birth</td>
<td><form:input path="dateOfBirth" name="timestamp" value=""/>
<img src="../images/cal.gif" width="16" height="16" border="0" alt="Click Here to Pick up the timestamp">
</td>
</tr>
Spring doesn't know how to take the value that you enter into that field and convert it into a Date object. You need to register a PropertyEditor for that. For example, add the following to your #Controller class
#InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
sdf.setLenient(true);
binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
}
Obviously, change the SimpleDateFormat to whatever your client is sending.
On a related note, you're sending a 302 response by sending a redirect
return "redirect:/full-reg";
Remember that request and model attributes only live for the duration of one request. So when your client send the request to full-reg, none of the form input parameters you sent originally exist any more. You should re-think how you do this.
I came across the same error this morning. The problem with my code was that I had declared a variable as an integer in my form binding object but on the actual form I was capturing text. Changing the variable to the correct type worked out for me
This happens when the defined binding does not match to what the user is sending. The most common issues are:
Missing PathVariable declaration
Incomplete PathVariable declaration (for example missing value="variableName")
Wrong data type, such as Sotirios Delimanolis answer above. If the Class of an input parameter cannot be serialized the request is not processable
So, in general, be sure that:
Each PathVariable is declared
A value is assigned that corresponds to value to be match in the path - #PathVariable(value="myVariableName", String myVariable) where the path defines #RequestMapping(value = "/userInfo/myVariableName", method = RequestMethod.GET)
Each class declared for a PathVariable must be serializable.
try with this (with /add-update2 instead of just add-update2) and replace modelAttribute by commandName
<form:form commandName="patientInfo" method="POST" action="/add-update2">
In my case, I try to create an object that has ID and NAME as attributes.
ID is int, NAME is String.
But my js set values like this
ID = '', NAME = 'brabrabra...'
After set ID = 0, problem is fixed.
I had a similar issue recently and solved it by annotating my Date field with the #DateTimeFormat. In your case, you would edit your PatientInfo.java file to:
import org.spring.framework.annotation.DateTimeFormat;
#Column(name = "DateOfBirth")
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern = ${pattern})
private Date dateOfBirth;
Make sure to replace ${pattern} with a string representing the format that will be received (e.g. "yyyy-MM-dd").