Neither BindingResult nor plain target object for bean name 'user' available as request attribute error - spring

I am new on spring. I am just trying to create my own CRUD OneToMany project. I have user and course table in my database. Course table has user_id foreign key references user(id).
When user successfully logged into the page, homePage.jsp comes and user courses are listed. When we click "Add Course" button in homePage.jsp, course-form.jsp file comes and we should add course.
The problem is, when I try to add course, I lost my user modelAttribute because in this time another attribute is on process with spring mvc.
When addedCourse form action performed these error occurs,
Cannot invoke "com.veg.entity.User.addCourse(com.veg.entity.Course)" because "user" is null
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
My Controller,
#PostMapping("/showFormForAdd")
public String showFormForAdd(#ModelAttribute("user") User theUser, Model theModel) {
Course theCourse = new Course();
theCourse.setUser(theUser);
theModel.addAttribute("course", theCourse);
theModel.addAttribute("user", theUser);
return "course-form";
}
#PostMapping("addedCourse")
public String addedCourse(#ModelAttribute("course") Course theCourse, Model theModel) {
User user = theCourse.getUser();
userService.save(user, theCourse);
theModel.addAttribute("user", user);
return "homePage";
}
homePage.jsp
<p>Welcome ${user.username}</p>
<span>
<form:form action="showFormForAdd" modelAttribute="user" method="POST">
<form:hidden path="username"/>
<form:hidden path="password"/>
<input type="submit" value="Add Course" class="add-course"/>
</form:form>
</span>
<table>
<tbody>
<tr>
<th>Course id</th>
<th>Course title</th>
</tr>
<c:forEach var="temp" items="${user.courses}">
<tr>
<td> ${temp.id} </td>
<td> ${temp.title} </td>
</tr>
</c:forEach>
</tbody>
</table>
course-form.jsp
<p>Welcome ${user.username}</p>
<span>
<form:form action="loggedUser" modelAttribute="user" method="POST">
<form:hidden path="username"/>
<form:hidden path="password"/>
<input type="submit" value="Back to Course List" class="add-course"/>
</form:form>
</span>
<!-- In the below I lost my user modelAttribute because I should use course attribute -->
<form:form action="addedCourse" modelAttribute="course" method="POST">
<table>
<tbody>
<tr>
<td> Title </td>
<td> <form:input path="title"/> </td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Add Course" class="add-course"/>
</td>
</tr>
</tbody>
</table>
</form:form>
I have #Transactional in my service, #Repository in my DAO and there is no problem with sessionFactory.

Related

Thymeleaf binding a selected value from a table

I'm having a table with multiple elements that are generated from a List and every table element from that list has a button.By clicking that button there is a post submit request which should bind the values from that table data element to a #ModelAttribute object in spring boot.
The problem is that i'm able to map the whole list but I want to bind only the table element where the button was pressed.
<div class="table-responsive">
<form th:action="#{/saveAd}" th:object="${object}" method="POST">
<table class="table table-sm table-hover">
<thead class="thead-dark">
<tr>
<th>Image</th>
<th>Title</th>
<!-- <th style="width: 16.66%">Link</th> -->
<th>Price</th>
<th>City</th>
</tr>
</thead>
<tbody id="myTable">
<th:block th:each="element, itemStat: *{lista}">
<tr
th:onclick="'javascript:rowClicked(\'' + *{lista[__${itemStat.index}__].url} + '\');'">
<input type="hidden" readonly="readonly"
th:name="?"
th:value="${element.getUrl()}" />
<td>
<input type="hidden" readonly="readonly" th:name="img" th:value="${element.getImg()}" />
<img th:src="*{lista[__${itemStat.index}__].img}" class="size" name="img" />
</td>
<td>
<input type="hidden" readonly="readonly" th:name="?" th:value="${element.getTitle()}" />
<span th:text="*{lista[__${itemStat.index}__].title}"></span>
</td>
<td>
<input type="hidden" readonly="readonly" th:name="?" th:value="${element.getPrice()}" />
<span th:text="*{lista[__${itemStat.index}__].price}"></span>
</td>
<td>
<input type="hidden" readonly="readonly" th:name="?" th:value="${element.getCity()}" />
<span th:text="*{lista[__${itemStat.index}__].city}"></span>
</td>
<td><input class="btn btn-danger" type="submit"
value="Save"></td>
</tr>
</th:block>
</tbody>
</table>
</form>
</div>
The Controller:
#RequestMapping(path = "/saveAd", method = RequestMethod.POST)
public String saveAd(#ModelAttribute("Value") ListCreationAutovitDto listCreationAutovitDto) {
return "home";
}
I have a hidden input type for every td which should map the values but i've tried naming it in different ways but i can't make it work.Are there any ways to bind only the values where the button was pressed?
Idea 1: Make each td contain a form pointing to your controller method. Then bind the values you want to pass to the model by using hidden input fields in the form. Each button would then do a submit for the form it is in.
Idea 2: If you're mapping json to your java objects in your app, you can construct the json request body in JavaScript to contain only the stuff you want for that request

Pass id to the controller

Firstly, I am passing values from database to the table. In the first column I want to create a form that will pass the id to delete function in Controller.
<tr th:each="blg: ${all}" th:object="${blg}" >
<td>
<form th:action="#{/delete}" th:object= "${blg}" method="post">
<input type="text" th:field="${blg.id}"/>
<button type="submit">Delete</button>
</form>
</td>
<td th:text="*{title}"> title </td>
<td th:text="*{content}"> title </td>
<td th:text="*{category}"> title </td>
<td th:text="*{signature}"> title </td>
</tr>
Controller:
#GetMapping("/show")
public String show(Model model){
List<Blog> all = br.findAll();
model.addAttribute("all",all);
return "show";
}
#RequestMapping(value="/delete", method=RequestMethod.POST)
public String deletePost(#RequestParam Long id){
br.delete(id);
return "redirect:/show";
}
The thymeleaf engine doesn't map the object as this error occcurs:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'blg' available as request attribute.
What is the way to create a correct form in this case?
Update your html code as shown below:
<tr th:each="blg: ${all}" >
<td>
<form th:action="#{|/delete/${blg.id}|}" method="post">
<button type="submit">Delete</button>
</form>
</td>
<td th:text="${blg.title}"> title </td>
<td th:text="${blg.content}"> title </td>
<td th:text="${blg.category}"> title </td>
<td th:text="${blg.signature}"> title </td>
</tr>
Better to use HTTP method DELETE for delete operations.
The reason because th:object tried to look in your request attribute for the attribute blg. But blg is a result of an iteration.

Spring MVC - Submit Form 400 Error

I'm just begin writing an application using Spring MVC. I have 2 entities, District & City. A City has many districts, and each district belongs to a city.
In district.jsp I declare a form, allowing user input of the district name and a selection box to choose the City it belongs to.
The District entity looks like this:
<form:form action="${aAction}" commandName="district">
<table>
<c:if test="${!empty district.districtName}">
<tr>
<td>
<form:label path="id">
<spring:message text="ID"/>
</form:label>
</td>
<td>
<form:input path="id" readonly="true" size="8" disabled="true" />
<form:hidden path="id" />
</td>
</tr>
</c:if>
<tr>
<td>
<form:label path="districtName">
<spring:message text="District Name"/>
</form:label>
</td>
<td>
<form:input path="districtName" />
</td>
</tr>
<tr>
<td>
<form:label path="belongToCity">
<spring:message text="Belong to City"/>
</form:label>
</td>
<td>
<c:if test="${!empty listCities}">
<form:select path="belongToCity" items="${listCities}" itemLabel="cityName" itemValue="id"></form:select>
</c:if>
</td>
</tr>
<tr>
<td colspan="2">
<c:if test="${!empty district.districtName}">
<input type="submit"
value="<spring:message text="Edit District"/>" />
</c:if>
<c:if test="${empty district.districtName}">
<input type="submit"
value="<spring:message text="Add District"/>" />
</c:if>
</td>
</tr>
</table>
</form:form>
In my district controller I declare add action.
#RequestMapping(value = {"/district/add"}, method = RequestMethod.POST)
public String addDistrict(#ModelAttribute("district") District p,Model model, BindingResult result) {
if(result.hasErrors()) {
return "district";
}
this.districtService.addDistrict(p);
return "district";
}
When I run my project, however, it shows a 400 error and the error message: "The request sent by the client was syntactically incorrect."
I suspect my form is wrong somewhere, maybe it is not able to post to controller processing. Could someone help me identify the issue?
Your BindingResult parameter should be adjacent to modelAttribute. Below should be method signature.
#RequestMapping(value = {"/district/add"}, method = RequestMethod.POST)
public String addDistrict(#ModelAttribute("district") District p, BindingResult result, Model model) {
if(result.hasErrors()) {
return "district";
}
this.districtService.addDistrict(p);
return "district";
}

Neither BindingResult nor plain target object for bean name 'command'. Spring exception

i'm starting learning spring MVC3, and i would like to display a simple "search form" here my jsp file
<form:form method="post" action="addGeo.html" >
<table>
<tr>
<td>
<input type="submit" value="<spring:message code="label.addzone"/>"/>
</td>
</tr>
</table>
</form:form>
<form:form method="post" action="maingeo.html" >
<table>
<tr>
<td>
<form:label path="codeZone"><spring:message code="label.area"/></form:label>
</td>
<td>
<form:input path="codeZone" />
</td>
<td>
<form:label path="type"><spring:message code="label.type"/></form:label>
</td>
<td>
<form:input path="type" />
</td>
<td>
<form:label path="codePostal"><spring:message code="label.departement"/></form:label>
</td>
<td>
<form:input path="codePostal" />
</td>
<td>
<input type="submit" value="<spring:message code="label.searchArea"/>"/>
</td>
</tr>
</table>
</form:form>
and here my controller :
#Controller
public class RefGeoController {
#Autowired
private RefGeoService refgeoService;
#RequestMapping("/maingeo")
public String goSearchArea() {
return "maingeo";
}
}
when i go to this url page, i've got this exception : java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute . I think that i forgot something in my form or maybe in my controller but i dont know where. Moreover what should i put on my method parameter when i don't want to send specific model to my jsp view?
You need to write an Class, that contains the fields of your form - this kind of class is called Command-Object/Class.
Then in your Controller method, that is responsible for providing the form page, you need to create an instance of this Command-Object, put it in the Model and then let the view render it. The name that is used for the Command-Object in the Model, must match the "command" attribute name of the <form:form command="myCommand"> tag. If you don't have this attribute, than the default name is command.
#Controller public class RefGeoController {
#Autowired private RefGeoService refgeoService;
#RequestMapping("/maingeo")
public ModelAndView goSearchArea() {
return new ModelAndView("maingeo", "searchCommand", new SearchCommand());
}
//only to prevent your next question: How to recive the committed form
#RequestMapping("/maingeo.html", method = RequestMethod.POST)
public ModelAndView handleSearch(SearchCommand searchCommand) {
... implement the search stuff
}
}
<form:form method="post" action="maingeo.html" command="searchCommand">

How are Spring MVC Controllers being bound to JSP pages?

Hi I am new to spring and I am trying to develop a simple portlet that accepts users first and last name and saves it to db using hibernate.
Basically I cannot figure out how the jsps and controllers communicate; I am missing some chunk here.
This is my first controller that needs to be called (where do I mention so?)
package codes.controller;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value="SimpleUserController")
#RequestMapping(value = "VIEW")
public class SimpleUserController {
// -- auto-wiring of service dependency
#Autowired
#Qualifier("userService")
private UserService userService;
// --maps the incoming portlet request to this method
#RenderMapping
public String showUsers(RenderResponse response) {
return "home";
}
#ExceptionHandler({ Exception.class })
public String handleException() {
return "errorPage";
}
// -- #ModelAttribute here works as the referenceData method
#ModelAttribute(value="user")
public User getCommandObject() {
return new User();
}
}
Initially I am displaying a home.jsp that will display the form with two input boxes and a submit button.
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<form:form name="home" commandName="user" method="post"
action="${addUserActionUrl}">
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" value="SUBMIT" /></td>
</tr>
</table>
</table>
</form:form>
This JSP should call the action method in the AddUserController.java:
package codes.controller;
import javax.portlet.ActionResponse;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value = "AddUserController")
#RequestMapping(value = "VIEW")
public class AddUserController {
#Autowired
#Qualifier("userService")
private UserService userService;
#RenderMapping(params = "myaction=addUser")
public String showRegisterPage(Model model) {
model.addAttribute("user", new User());
model.addAttribute("users", getUsers());
return "addUser";
}
public List<User> getUsers() {
return userService.getAllUsers();
}
#ActionMapping(params = "myaction=addUser")
public void addBook(#ModelAttribute(value = "user") User user,
BindingResult bindingResult, ActionResponse response,
SessionStatus sessionStatus) {
if (!bindingResult.hasErrors()) {
userService.addUser(user);
response.setRenderParameter("myaction", "users");
sessionStatus.setComplete();
} else {
response.setRenderParameter("myaction", "addUser");
}
}
}
This time this firstname+last name should be saved in the db AND the screen should refresh to show a new form that will have a dropdown with the current users' names in the database and another first name and last name form fields. If you select a username from the dropdown the form fields are populated and you can edit these values and click on UPdate button to save the values in DB. Otherwise you can add a new user to the database using submit button.
addUser.jsp:
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<portlet:renderURL var="homeUrl">
<portlet:param name="myaction" value="Users" />
</portlet:renderURL>
<script type="text/javascript" src="js/userRelated.js"></script>
<form:form name="addUser" commandName="user" method="post"
action="${addUserActionUrl}">
<form:select path="model">
<form:option value="NONE" label="--- Select ---" id="userList" onchange="showHide()"/>
<form:options items="${users}" />
</form:select>
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" id="submit" value="SUBMIT" />SUBMIT</td>
</tr>
<tr>
<td> </td>
<td><input type="submit" id="update" value="SUBMIT" />UPDATE</td>
</tr>
</table>
</table>
</form:form>
I am hiding and unhiding the SUBMIT/UPDATE button using onchange of dropdown. How do I call different functions in the addUsercontroller depending on the button available?
by updating the action attribute of form element with javascript

Resources