I know questions on this matter have been asked already, but none of the answers I found solved my problem.
I have a many-to-many relantionship on my database. I'm using JPA and Hibernate to create and alter my tables. Here are my model classes:
Book.java
@Entity
@Table(name="tb_books")
public class Book implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false, nullable = false, insertable = false)
private Integer id;
@Column(name = "title", nullable = false, length = 255)
private String title;
@Column(name = "author", nullable = false, length = 255)
private String author;
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
@JoinTable(name = "book_tag",
joinColumns = { @JoinColumn(name = "fk_book") },
inverseJoinColumns = { @JoinColumn(name = "fk_tag") })
private List<Tag> tags;
//getters, setters, equals and hash methods...
}
Tag.java
@Entity
@Table(name="tb_tags")
public class Tag implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false, nullable = false)
private Integer id;
@Column(name = "description", nullable = false, length = 255)
private String description;
//getters, setters, equals and hash methods...
}
I'm trying to make insertions and updates on my book_tag table with the data comming from a JSP using Spring MVC. Here is my controller and insertion page:
BookController.java
@Controller
@RequestMapping(value = "/book")
public class BookController {
@Autowired
private BookService bookService;
/*
Controller method that gets us to the adding book page.
*/
@RequestMapping(value = "/add", method = RequestMethod.GET)
public ModelAndView addBookPage() {
List<Tag> tags = tagService.getTags(); //all tags from the database
ModelAndView modelAndView = new ModelAndView("form-book");
modelAndView.addObject("book", new Book());
modelAndView.addObject("tags", tags);
return modelAndView;
}
@RequestMapping(value = "/add", method = RequestMethod.POST)
public ModelAndView addBookProcess(@ModelAttribute Book book) {
bookService.addBook(book);
return new ModelAndView("redirect:/book/add");
}
//...
}
form-book.jsp
<form:form method="POST" modelAttribute="book" action="${pageContext.request.contextPath}/book/add.html">
<table>
<tbody>
<tr>
<td>Title:</td>
<td><form:input path="title" autocomplete="off" /></td>
</tr>
<tr>
<td>Author:</td>
<td><form:input path="author" autocomplete="off" /></td>
</tr>
<tr>
<td colspan="2">
<form:checkboxes path="tags"
items="${tags}"
itemLabel="description"
itemValue="id"/>
</td>
</tr>
<tr>
<td><input type="submit" value="Add" /></td>
<td><input type="button" onclick="location.href = '${pageContext.request.contextPath}/index'" value="Cancel"/></td>
</tr>
</tbody>
</table>
</form:form>
Everything is working fine, except when I try to update or insert books with one or more checkboxes selected. When I try to do so, I just get a "Bad Request" page, I imagine because of something wrong I'm doing concerning databinding.
Is this the way I'm supposed to handle this situation? Is there a better way? What am I doing wrong?