ERROR
java.lang.NullPointerException
at com.javalabs.web.dao.UserPropertyEditor.setAsText(UserPropertyEditor.java:20)
...
I can not bind the parameter from the form property userResponsible where I get the id of a user to bind to the object Task. But I'm getting the parameter userResponsible = 1, which is a user from database. Any idea from what can be?
form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<h1>Create task</h1>
<form:form method="GET" class="form-horizontal"
action="${pageContext.request.contextPath}/docreatetask"
commandName="task">
...
<div class="form-group">
<label for="userresponsible" class="col-sm-2 control-label">User
responsible</label>
<div class="col-sm-10">
<form:select path="userResponsible" name="userResponsible" class="form-control">
<form:option value="0" label="Select" />
<form:options items="${users}" itemValue="idUser"
itemLabel="username" />
</form:select>
<div id="state.error">
<span class="text-danger"><form:errors path="userResponsible" /></span>
</div>
</div>
</div>
...
Task.java
@Entity
@Table(name = "t_task")
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "idTask")
private long idTask;
...
@ManyToOne
@JoinColumn(name = "idUser_responsible", nullable = true)
private User userResponsible;
...
UserPropertyEditor.java
public class UserPropertyEditor extends PropertyEditorSupport {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
line 20: super.setValue(userService.get(Long.parseLong(text)));
//text variable is null when this function is called
}
}
TaskController.java
...
@InitBinder
public void initBinder(WebDataBinder binder, HttpServletRequest req) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
binder.registerCustomEditor(State.class, new StatePropertyEditor());
binder.registerCustomEditor(Category.class, new CategoryPropertyEditor());
binder.registerCustomEditor(Priority.class, new PriorityPropertyEditor());
binder.registerCustomEditor(User.class, "userResponsible", new UserPropertyEditor());
//binder.registerCustomEditor(User.class, new UserPropertyEditor());
}
...
What am I missing?
In your initBinder
method you are constructing the UserPropertyEditor
yourself, as this makes this a non spring managed bean the @Autowired
doesn't do a thing.
Either you have to call the setUserService
yourself or you have to ask the application context to wire the instance for you.
@Controller
public class TaskController {
@Autowired
private UserService userService;
@InitBinder
public void initBinder(WebDataBinder binder, HttpServletRequest req) {
UserPropertyEditor upe = new UserPropertyEditor();
upe.setUserService(userService);
binder.registerCustomEditor(User.class, "userResponsible", upe);
}
}
When you call the setter yourself you have to inject the UserService
into your controller so that you have access to it. Now construct a UserPropertyEditor
and call the setUserService
method on it.
@Controller
public class TaskController {
@Autowired
private ApplicationContext context;
@InitBinder
public void initBinder(WebDataBinder binder, HttpServletRequest req) {
UserPropertyEditor upe = new UserPropertyEditor();
context.getAutowireCapableBeanFactory().autowireBean(upe);
binder.registerCustomEditor(User.class, "userResponsible", upe);
}
}
When using the ApplicationContexct
you have to inject that into your controller, get a AutowireCapableBeanFactory
and call the autowireBean
method on the freshly constructed instance of the bean. Now Spring will do any injection and callbacks for your object.