I have been wrestling with how to implement a form that creates many-to-many relations in a web application I am building with Spring 3 and Hibernate 4. I am trying to build a simple blog tool with a tagging system. I have created a model BlogPost that has a many-to-many relationship with the model Tags. When I create a new BlogPost object, the web form input for tags is a single-lined text input. I'd like to be able to split this text string by whitespace and use it to create Tag objects. Alternatively, when editing an existing BlogPost, I'd like to be able to take the Set of Tag objects associated with the BlogPost and convert it to a String that is used as the value of the input element. My problem is in converting between the text input and the referenced set of Tag objects using my form.
What is the best practice for binding/fetching/updating many-to-many relationships with web forms? Is there an easy way to do this that I am unaware of?
UPDATE
I decided, as suggested in the answer below, to manually handle the object conversion between the String tag values in the form and the Set<Tag> object required for the object model. Here is the final working code:
editBlogPost.jsp
...
<div class="form-group">
<label class="control-label col-lg-2" for="tagInput">Tags</label>
<div class="col-lg-7">
<input id="tagInput" name="tagString" type="text" class="form-control" maxlength="100" value="${tagString}" />
</div>
<form:errors path="tags" cssClass="help-inline spring-form-error" element="span" />
</div>
....
BlogController.java
#Controller
#SessionAttributes("blogPost")
public class BlogController {
#Autowired
private BlogService blogService;
#Autowired
private TagService tagService;
#ModelAttribute("blogPost")
public BlogPost getBlogPost(){
return new BlogPost();
}
//List Blog Posts
#RequestMapping(value="/admin/blog", method=RequestMethod.GET)
public String blogAdmin(ModelMap map, SessionStatus status){
status.setComplete();
List<BlogPost> postList = blogService.getAllBlogPosts();
map.addAttribute("postList", postList);
return "admin/blogPostList";
}
//Add new blog post
#RequestMapping(value="/admin/blog/new", method=RequestMethod.GET)
public String newPost(ModelMap map){
BlogPost blogPost = new BlogPost();
map.addAttribute("blogPost", blogPost);
return "admin/editBlogPost";
}
//Save new post
#RequestMapping(value="/admin/blog/new", method=RequestMethod.POST)
public String addPost(#Valid #ModelAttribute BlogPost blogPost,
BindingResult result,
#RequestParam("tagString") String tagString,
Model model,
SessionStatus status)
{
if (result.hasErrors()){
return "admin/editBlogPost";
}
else {
Set<Tag> tagSet = new HashSet();
for (String tag: tagString.split(" ")){
if (tag.equals("") || tag == null){
//pass
}
else {
//Check to see if the tag exists
Tag tagObj = tagService.getTagByName(tag);
//If not, add it
if (tagObj == null){
tagObj = new Tag();
tagObj.setTagName(tag);
tagService.saveTag(tagObj);
}
tagSet.add(tagObj);
}
}
blogPost.setPostDate(Calendar.getInstance());
blogPost.setTags(tagSet);
blogService.saveBlogPost(blogPost);
status.setComplete();
return "redirect:/admin/blog";
}
}
//Edit existing blog post
#Transactional
#RequestMapping(value="/admin/blog/{id}", method=RequestMethod.GET)
public String editPost(ModelMap map, #PathVariable("id") Integer postId){
BlogPost blogPost = blogService.getBlogPostById(postId);
map.addAttribute("blogPost", blogPost);
Hibernate.initialize(blogPost.getTags());
Set<Tag> tags = blogPost.getTags();
String tagString = "";
for (Tag tag: tags){
tagString = tagString + " " + tag.getTagName();
}
tagString = tagString.trim();
map.addAttribute("tagString", tagString);
return "admin/editBlogPost";
}
//Update post
#RequestMapping(value="/admin/blog/{id}", method=RequestMethod.POST)
public String savePostChanges(#Valid #ModelAttribute BlogPost blogPost, BindingResult result, #RequestParam("tagString") String tagString, Model model, SessionStatus status){
if (result.hasErrors()){
return "admin/editBlogPost";
}
else {
Set<Tag> tagSet = new HashSet();
for (String tag: tagString.split(" ")){
if (tag.equals("") || tag == null){
//pass
}
else {
//Check to see if the tag exists
Tag tagObj = tagService.getTagByName(tag);
//If not, add it
if (tagObj == null){
tagObj = new Tag();
tagObj.setTagName(tag);
tagService.saveTag(tagObj);
}
tagSet.add(tagObj);
}
}
blogPost.setTags(tagSet);
blogPost.setPostDate(Calendar.getInstance());
blogService.updateBlogPost(blogPost);
status.setComplete();
return "redirect:/admin/blog";
}
}
//Delete blog post
#RequestMapping(value="/admin/delete/blog/{id}", method=RequestMethod.POST)
public #ResponseBody String deleteBlogPost(#PathVariable("id") Integer id, SessionStatus status){
blogService.deleteBlogPost(id);
status.setComplete();
return "The item was deleted succesfully";
}
#RequestMapping(value="/admin/blog/cancel", method=RequestMethod.GET)
public String cancelBlogEdit(SessionStatus status){
status.setComplete();
return "redirect:/admin/blog";
}
}
BlogPost.java
#Entity
#Table(name="BLOG_POST")
public class BlogPost implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="POST_ID")
private Integer postId;
#NotNull
#NotEmpty
#Size(min=1, max=200)
#Column(name="TITLE")
private String title;
...
#ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
#JoinTable(name="BLOG_POST_TAGS",
joinColumns={#JoinColumn(name="POST_ID")},
inverseJoinColumns={#JoinColumn(name="TAG_ID")})
private Set<Tag> tags = new HashSet<Tag>();
...
public Set<Tag> getTags() {
return tags;
}
public void setTags(Set<Tag> tags) {
this.tags = tags;
}
}
Tag.java
#Entity
#Table(name="TAG")
public class Tag implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="TAG_ID")
private Integer tagId;
#NotNull
#NotEmpty
#Size(min=1, max=20)
#Column(name="TAG_NAME")
private String tagName;
#ManyToMany(fetch = FetchType.LAZY, mappedBy="tags")
private Set<BlogPost> blogPosts = new HashSet<BlogPost>();
public Integer getTagId() {
return tagId;
}
public void setTagId(Integer tagId) {
this.tagId = tagId;
}
public String getTagName() {
return tagName;
}
public void setTagName(String tag) {
this.tagName = tag;
}
public Set<BlogPost> getBlogPosts() {
return blogPosts;
}
public void setBlogPosts(Set<BlogPost> blogPosts) {
this.blogPosts = blogPosts;
}
}
If you choose to encode your Tags in a String as the transfer data model between client and server you might make your life a little harder if you want to improve your UX later on.
I would consider having Set<Tag> as its own model element and I would do the transformation directly in the front-end using JavaScript on a JSON model.
Since I would like to have auto completion for my tagging, I would pass all existing Tags as part of the /admin/blog/new model with the ability to mark which tags belong to the blog post (e.g. as a Map<Tag, Boolean> or two Sets) - most likely with a JSON mapping. I would modify this model using JavaScript in the frontend (perhaps utilizing some jquery plugins that provides some nice autocomplete features) and rely on default JSON Mapping (Jackson) for the back conversion.
So my model would have at least two elements: the blog post and all the tags (some who are marked as "assigned to this BlogPost". I would use a TagService to ensure existence of all relevant tags, query them with where name in (<all assigned tag names>) and set my BlogPost.setTags(assignedTags).
In addition I would want to have some cleanup function to remove unused Tags from the DB. If I would want to make it easier for the server, I would have another model element with the removed removed tags (so I can check whether this was the last BlogPost that used this Tag).
This should work in your form:
<div class="form-check">
<input class="form-check-input" type="checkbox" value="1"
name="categories"> <label class="form-check-label"
for="categories"> Cat 1 </label>
<input class="form-check-input"
type="checkbox" value="2" name="categories"> <label
class="form-check-label" for="categories"> Cat 2 </label>
</div>
Related
Recently we fixed the struts2's 'S2-045' problem.I updated all the struts2 related jar files including freemarker, ognl, xWork,etc. I use tomcat8 to deploy my dynamic web project. There were not any Exceptions while starting the tomcat-server. But some problems seemed occur: some values(got from db) should be displayed on the jsp pages dose not show up any more. There is no Exceptions thrown. I also can watch that I have already got the very Objects correctly in the Action Classes.
the following is some examples
// index.jsp ----- here is the list I want to show on the page.
// the list is the type of List<News> (Class News is my bussiness Class).
// I want to get the 'fTitle' and 'fCreatetime_s' from 'News' but they
// do not show up! (This used to be working very well.)
<s:bean name="org.ulibrary.web.Getarclist">
<s:iterator value="list">
<li>
<span class="listTitle">
<a target="_blank" href="ViewArc.action? uuid=${UUID}">${fTitle}</a>
</span>
<span class="listDate">${fCreatetime_s}</span>
</li>
</s:iterator>
</s:bean>
//=================================================================
Following is the ralated fields id News.java
// News.java (**just some ralated fields**)
class News{
#Id
#GeneratedValue(generator = "system-uuid")
#GenericGenerator(name = "system-uuid", strategy = "uuid")
#Column(name = "f_uuid", length = 32, unique = true)
private String UUID;
#Column(name = "f_title", length = 200)
private String fTitle;
#Transient
private String fCreatetime_s;
public String getUUID() {
return UUID;
}
public void setUUID(String uuid) {
UUID = uuid;
}
public String getFTitle() {
return fTitle;
}
public void setFTitle(String title) {
fTitle = title;
}
public String getFCreatetime_s() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
return formatter.format(Long.valueOf(fCreatetime));
}
public void setFCreatetime_s(String createtime_s) {
fCreatetime_s = createtime_s;
}
}
and then the GetarcList.java
//GetarcList.java (just include some related fields)
class GetarcList{
private List list;
public void setList(List list) {
this.list = list;
}
//!!!!!!$$$$$$$$--- Attention -----$$$$$$$$$!!!!!!!!!!!
// this method returns a List<News> , I can successfully get every value of 'News' in the list
public List getList() throws AuctionException{
String orderby_str = (String) OrderByMap.get(String.valueOf(orderby));
list = webTagManager.getArcList(row, typeid, titlelen, infolen, orderby_str + " " + orderway);
return list;
}
}
I think this maybe caused by the OGNL or JSP related jar-files. I didn't find any problems in my index.jsp or java-files.
You need to use getters/setters in the following format. Properties with only one starting lowercase letter are not uppercased.
public String getfTitle() {
return fTitle;
}
public void setfTitle(String title) {
fTitle = title;
}
I have two entities with relation as
#Entity
public class Foo {
#Id
#GeneratedValue
private Integer id;
private String name;
#OneToMany(mappedBy = "foo")
private List<Bar> bars;
// *******************\\
}
and
#Entity
public class Bar{
#Id
#GeneratedValue
private Integer id;
private String title;
#ManyToOne
#JoinColumn(name = "foo_id")
private Foo foo;
// *******************\\
}
I get list of bars to show in form for adding new foo
#RequestMapping(value = "/add-foo", method = RequestMethod.GET)
public String fooForm(Model model) {
model.addAttribute("bars", barService.findAll());
return "add-foo";
}
and form is
<form:form commandName="foo">
<form:input path="name"/><br>
<form:select path="bars" multiple="multiple">
<c:forEach items="${bars}" var="bar">
<form:option value="${bar.id}">${bar.title}</form:option>
</c:forEach>
</form:select><br>
<input type="submit" value="Add Foo with selected Bars">
</form:form>
Here I see all bars present using
<c:forEach items="${bars}" var="bar">
<form:option value="${bar.id}">${bar.title}</form:option>
</c:forEach>
but when I submit the form, using the method in controller
#RequestMapping(value = "/add-foo", method = RequestMethod.POST)
public String addFoo(#ModelAttribute("foo") Foo foo) {
List<Bar> bars = foo.getBars();
for (Bar bar : bars ) {
logger.info("DEBUG Foo object", bar);
}
return "redirect:/foos-list";
}
it seems not to send data to server and say an error The request sent by the client was syntactically incorrect.
Your binding input form fields with your Business Domain model Object, Make sure that Databinding is correctly performed or not. So use BindingResult after `#ModelAttribute. So you can easily identify your whether the form fields is bind your business object or not.
#RequestMapping(value = "/add-foo", method = RequestMethod.POST)
public String addFoo(#ModelAttribute("foo") Foo foo, BindingResult result) {
if (!result.hasErrors()){
List<Bar> bars = foo.getBars();
for (Bar bar : bars ) {
logger.info("DEBUG Foo object", bar);
}
} else
System.out.println("Binding result error");
return "redirect:/foos-list";
}
And your redirect to "/foos-list" into your Controller again. There is no such RequestMapping in your post. So redirect to appropriate RequestMapping like this,
#RequestMapping(value = "/foos-list", method = RequestMethod.GET)
public String fooForm(Model model) {
model.addAttribute("bars", barService.findAll());
return "add-foo";
}
I am new to spring + hibernate. When I add a customer and its destinations (one to many relationship), everything is fine. But when I update the customer's destination, all previous destinations remain in the database with a null customer foreign key.
Suppose I insert 4 destinations a, b, c, d. After updating the customer, I insert x, y. Then it stores total 6 destinations: a, b, c, d with null references and x, y with customer references.
Here is my code:
1). Customer Entity
Has one-to-many relationship with destination and relationship is unidirectional.
#Entity
#Table(name="customers")
#Proxy(lazy=false)
public class CustomerEntity {
#Id
#Column(name="id")
#GeneratedValue
private Integer id;
private String description;
private String panNo;
private String cstNo;
private String vatNo;
#OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
#JoinColumn(name = "customer_id", referencedColumnName = "id")
public List<DestinationsEntity> destination = new AutoPopulatingList<DestinationsEntity>(DestinationsEntity.class);
//getter and setters
}
2). Destination Entity
#Entity
#Table(name = "destinations")
#Proxy(lazy = false)
public class DestinationsEntity {
#Id
#Column(name = "id")
#GeneratedValue
private Integer id;
#Column(name="destination")
private String destination;
// getter and setter
}
1). AddCustomer.jsp
This code for adding more destinations in Autopopulate list
<div id="destination_container">
<div><textarea row="3" col="5" class="destination_address" name= "destination[${0}].destination" placeholder="Please enter address"></textarea></div>
</div>
<script type="text/javascript">
$(document).ready(function(){
var index = 1;
/*
* Add more destination
*/
$('#add_more_destination').click(function(){
$('#destination_container').append('<div><textarea row="3" col="5" class="destination_address" name= "destination[${"'+index+'"}].destination" placeholder="Please enter address"></textarea><span class="remove_dest">*</span></div>');
index++;
});
});
</script>
2). updateCustomer.jsp
All destinations added by customer is show here and he/she can be change destinations(like before inserted pune, mumbai , banglore) now updating destinations( delhi, punjab)
<c:set var="index" scope="page" value="${fn:length(destinationss)}"/>
<c:forEach items="${destinationss}" var="dest" varStatus="i">
<div>
<textarea class="destination_address" name= "destination[${i.index}].destination" placeholder="Please enter address">${dest.destination}</textarea><span class="remove_dest">*</span>
</div>
</c:forEach>
<button type ="button" id="add_more_destination">Add More Destinations</button>
<script type="text/javascript">
$(document).ready(function(){
/*
* Add a destination
*/
var index = ${index};
$('#add_more_destination').click(function(){
$('#destination_container').append('<div><textarea row="3" col="5" class="destination_address" name=destination["'+index+'"].destination placeholder="Please enter address"></textarea><span class="remove_dest">*</span></div>');
alert(index);
index++;
});
</script>
Controller
#RequestMapping(value = "/addCustomerForm", method = RequestMethod.GET)
public String addCustomerForm(ModelMap map) {
return "master/addCustomer";
}
#RequestMapping(value = "/addCustomer", method = RequestMethod.POST)
public String addCustomer(#ModelAttribute(value = "customer") CustomerEntity customer,BindingResult result, HttpServletRequest request) {
customerService.addCustomer(customer);
return "redirect:/customer";
}
Update Customer
This is new thing I tried last night. Problem is solved partially.
#ModelAttribute
public void updateOperation(HttpServletRequest request, ModelMap map) {
if(null !=request.getParameter("id"))
map.addAttribute("customer1", customerService.findOne(Integer.parseInt(request.getParameter("id"))));
}
#RequestMapping(value = "/updateCustomerForm/{customerId}", method = RequestMethod.GET)
public String updateCustomerForm(#PathVariable("customerId") Integer customerId, ModelMap map, HttpServletRequest request) {
CustomerEntity customerEntity = customerService.findOne(customerId);
map.addAttribute("customer", customerEntity);
map.addAttribute("destinationss",customerEntity.getDestination());
}
#RequestMapping(value = "/updateCustomer", method = RequestMethod.POST)
public String updateCustomer(#ModelAttribute(value = "customer1")CustomerEntity customer1,BindingResult result, HttpServletRequest request,HttpServletResponse response) {
customerService.updateCustomer(customer1);
return "redirect:/customer";
}
}
1). CustomerServiceImpl
public class CustomerServiceImpl implements CustomerService{
#Autowired
private CustomerDao customerDao;
#Override
#Transactional
public void addCustomer(CustomerEntity customer) {
customerDao.addCustomer(customer);
}
#Override
#Transactional
public CustomerEntity findOne(Integer id){
return customerDao.findOne(id);
}
#Override
#Transactional
public void updateCustomer(CustomerEntity customerEntity){
if (null != customerEntity) {
customerDao.updateCustomer(customerEntity);
}
}
}
2).CustomerDaoImpl
public class CustomerDaoImpl implements CustomerDao{
#Autowired
private SessionFactory sessionFactory;
#Override
#Transactional
public void addCustomer(CustomerEntity customer){
this.sessionFactory.getCurrentSession().save(customer);
}
#Override
public CustomerEntity findOne(Integer id){
return (CustomerEntity) sessionFactory.getCurrentSession().load(CustomerEntity.class, id);
}
#Override
#Transactional
public void updateCustomer(CustomerEntity customerEntity){
if (null != customerEntity) {
this.sessionFactory.getCurrentSession().update(customerEntity);
}
}
}
The issue is Spring will give you new Customer entity, so I guess the Destination entities in this Customer is empty initially. So in your update operation you are just adding some new Destination entities and then adding them to customer as per your code.
So in this case, the customer entity is having only the new Destination objects where as the already existing Destination entities which were mapped earlier are not present in your Customer entity.
To fix the issue, first get the Customer entity from database, then this entity will have the set of Destination objects. Now to this Customer you can add new Destination objects and also update the existing Destination objects if needed then ask Hibernate to do the update operation. In this case Hibernate can see your earlier destination objects and also the new destination objects and based on that it will run the insert & update queries.
The code looks something like this:
// First get the customer object from database:
Customer customer = (Customer) this.sessionFactory.getCurrentSession().get(Customer.class, customerId);
// Now add your destination objects, if you want you can update the existing destination entires here.
for (int i = 0; i < destinationAddrs.length; i++) {
DestinationsEntity destination = new DestinationsEntity();
destination.setDestination(destinationAddrs[i]);
customer.getDestinationEntity().add(destination);
}
// Then do the update operation
this.sessionFactory.getCurrentSession().update(customer);
I have a simple model class Product which exhibits a many to one relationship with ProductCategory:
Product class:
#Entity
#Table(name="product")
public class Product {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Long id;
#Column(name="name")
private String name;
#Column(name="description")
private String description;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="category_id")
private ProductCategory category;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPdfUrl() {
return pdfUrl;
}
public void setPdfUrl(String pdfUrl) {
this.pdfUrl = pdfUrl;
}
public ProductCategory getCategory() {
return category;
}
public void setCategoryId(ProductCategory category) {
this.category = category;
}
}
ProductCategory class
#Entity
#Table(name="product_category",uniqueConstraints={#UniqueConstraint(columnNames="name")})
public class ProductCategory {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Long id;
#Column(name="name")
private String name;
#OneToMany(fetch=FetchType.LAZY, mappedBy="category")
private Set<Product> products = new HashSet<Product>(0);
// getters() & setters()
}
I am using Spring boot with Thymeleaf to create the necessary forms for the usual CRUD operations.
Here is the essential portion of my html page which I use to add a new Product object into the database.
<form action="#" th:action="/product/save" th:object="${newProduct}" method="POST">
<input type="text" th:field="*{name}" />
<input type="text" th:field="*{description}" />
<select th:field="*{category}">
<option th:each="category: ${productCategories}" th:value="${category}" th:text="${category.name}" />
</select>
<button type="submit">Submit</button>
</form>
The problem is, when I try and insert the resulting Product object from the controller (I know I haven't shown it here, mostly because I don't think that is actually the cause of the problem), there is a
MySQLIntegrityConstraintViolationException: Column 'category_id' cannot be null
I have tried changing the value of the option to ${category.id}, but even that doesn't fix it.
In a nutshell
How do I actually pass a complex object as a POST parameter into a controller using Thymeleaf?
Update
Contrary to my first thoughts, this might actually be related to my Controller, so here is my ProductController:
#RequestMapping(value="/product/save", method=RequestMethod.POST)
public String saveProduct(#Valid #ModelAttribute("newProduct") Product product, ModelMap model) {
productRepo.save(product);
model.addAttribute("productCategories", productCategoryRepo.findAll());
return "admin-home";
}
#RequestMapping(value="/product/save")
public String addProduct(ModelMap model) {
model.addAttribute("newProduct", new Product());
model.addAttribute("productCategories", productCategoryRepo.findAll());
return "add-product";
}
Note that I have changed the form method to POST.
From thymeleafs perspective I can assure the below code should work.
<form method="POST" th:action="#{/product/save}" th:object="${newProduct}">
....
<select th:field="*{category}" class="form-control">
<option th:each="category: ${productCategories}" th:value="${category.id}" th:text="${category.name}"></option>
</select>
Provided that your controller looks like this.
#RequestMapping(value = "/product/save")
public String create(Model model) {
model.addAttribute("productCategories", productCategoryService.findAll());
model.addAttribute("newproduct", new Product()); //or try to fetch an existing object
return '<your view path>';
}
#RequestMapping(value = "/product/save", method = RequestMethod.POST)
public String create(Model model, #Valid #ModelAttribute("newProduct") Product newProduct, BindingResult result) {
if(result.hasErrors()){
//error handling
....
}else {
//or calling the repository to save the newProduct
productService.save(newProduct);
....
}
}
Update
Your models should have proper getters and setters with the correct names. For example, for the property category You should have,
public ProductCategory getCategory(){
return category;
}
public void setCategory(productCategory category){
this.category = category;
}
NOTE - I have not compiled this code, I got it extracted from my current working project and replace the names with your class names
I've two classes
public class User {
private int id;
priavte List<Hobby> hobbies;
//setter getter
}
public class Hobby {
private int id;
private String hobbyName;
//setter getter
}
now i want to create form for User.java
my form.jsp is
<form:form method="POST" action="saveEmployee.html" commandName="user" name="register-form" id="register-form" cssClass="smart-green">
<form:select path="hobbies" multiple="true" size="3">
<form:option value="1">Cricket</form:option>
<form:option value="2">Computer Games</form:option>
<form:option value="3">Tennis</form:option>
<form:option value="4">Music</form:option>
</form:select>
</form:form>
myController.java
#RequestMapping(value = "/saveEmployee.html", method = RequestMethod.POST)
public ModelAndView addEmployee(
#ModelAttribute("user") User user BindingResult result) {
System.out.println(user.getChoice()); // giving null
// usrDao.saveUser(user);
return new ModelAndView("redirect:add.html", model);
}
How could i get the value for List from my form so that i could get the value?
The Solution to Bind your multi select value to the POJO Object list is done under CustomCollectionEditor class. This is important when binding complex data types such as in your case.
Add this below code in your controller class myController.java :
#InitBinder
protected void initBinder(WebDataBinder binder)
{
binder.registerCustomEditor(List.class, "hobbies", new CustomCollectionEditor(List.class)
{
#Override
protected Object convertElement(Object element)
{
Long id = null;
String name = null;
if(element instanceof String && !((String)element).equals(""))
{
//From the JSP 'element' will be a String
try{
id = Long.parseLong((String) element);
}
catch (NumberFormatException e) {
e.printStackTrace();
}
}
else if(element instanceof Long)
{
//From the database 'element' will be a Long
id = (Long) element;
}
// Here you can get Hobby object from database based on the id you have got.
//You any other way you can get hobbyName and set in hobby object and return it
Hobby h = new Hobby();
h.setId(Integer.parseInt(String.valueOf(id)));
h.setHobbyName(name);
return h;
}
});
}
Reference Link for more details :
SpringMVC bind Multi Select with object in Form submit
Multiple Select in Spring 3.0 MVC.