I'm very new to Spring and I'm encountering the following problem.
I've got the following Controller, in which the @Autowired works perfectly (tried debugging and it works fine).
@Controller
@RequestMapping(value = "/registration")
@SessionAttributes("rf")
public class RegistrationController
{
@Autowired
UserJpaDao userDao;
@RequestMapping(method = RequestMethod.GET)
@Transactional
public String setupForm(Model model) throws Exception
{
model.addAttribute("rf", new RegistrationForm());
return "registration";
}
@RequestMapping(method = RequestMethod.POST)
@Transactional
public String submitForm(@ModelAttribute("rf") RegistrationForm rf, Model model) throws Exception
{
// ...
User user = rf.getUser();
userDao.save(user);
// ...
return "registration";
}
}
But when I submit my form, the @Autowired field in my RegistrationForm remains null.
RegistrationForm.java:
@Component
public class RegistrationForm
{
@Autowired
CountryJpaDao countryDao;
// ... fields...
public RegistrationForm()
{
}
@Transactional
public User getUser() throws InvalidUserDataException
{
//...
Country c = countryDao.findByCode("GB"); // Throws java.lang.NullPointerException
// ...
}
// ... getters/setters...
}
Here is the form's HTML/JSTL:
<form:form method="POST" modelAttribute="rf">
...
</form:form>
Can anyone help me?
Thank you.
(inspired by this post on SpringSource forums)
You're mixing up your concepts here. You use the likes of
@Component
and@Autowired
for Spring-managed beans, and@ModelAttribute
for transient, throwaway objects that are used to bind form data. The two should not be mixed. Your@Component
and@Autowired
annotations onRegistrationForm
will be ignored by Spring, because they're not appropriate in that context.Classes like
RegistrationForm
should represent the form data, and nothing else. Typically, the controller would askRegistrationForm
for the user ID, and would then look at the actualUser
object from the DAO itself. If you wantRegistrationForm
to look up theUser
itself, then your controller needs to manually supply the DAO toRegistrationForm
when it asks for theUser
object.As far as that post on the Spring forum is concerned, you'll notice that it never received an answer. It's not a good source to take inspiration from.
Note that I'm not saying that desiring to autowire beans into a form back object is a bad idea, I'm just saying that Spring doesn't do that.
It would work if you use the @Configurable annotation on your model, and this aspectJ configuration on your gradle file:
In this way aspectJ will generate code that does the auto wiring.