Spring MVC - Hibernate mapped object partially filled when using POST request method
-
14-10-2022 - |
Question
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.
No correct solution