I'm working on a Spring MVC controller and views to implement CRUD operations for a simple object named Partner. The update operation troubles me. It seems like I need to write several lines of code manually that I expected Spring MVC would take care of automatically. Is there a best practice that I'm missing here?
Here's my view:
<%@ include file="include.jsp"%>
<form:form commandName="partner">
<input type="hidden" name="_method" value="PUT" />
<table>
<tr>
<td>Id:</td>
<td><form:input path="id" disabled="true" /></td>
</tr>
<tr>
<td>Name:</td>
<td><form:input path="name" /></td>
</tr>
<tr>
<td>Logo:</td>
<td><form:input path="logo" /></td>
</tr>
<tr>
<td>On-screen text:</td>
<td><form:textarea path="onScreenText" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Save Changes" /></td>
</tr>
</table>
</form:form>
And here's my controller method for the update operation:
@RequestMapping(value="/partner/{partnerId}", method=RequestMethod.PUT)
public ModelAndView updatePartner(@ModelAttribute Partner partner, @PathVariable int partnerId) {
EntityManager entityManager = DatabaseHelper.getEntityManager();
try {
Partner partnerToUpdate = entityManager.find(Partner.class, partnerId);
entityManager.getTransaction().begin();
partnerToUpdate.setId(partnerId);
partnerToUpdate.setName(partner.getName());
partnerToUpdate.setLogo(partner.getLogo());
partnerToUpdate.setOnScreenText(partner.getOnScreenText());
entityManager.persist(partnerToUpdate);
entityManager.getTransaction().commit();
}
finally {
entityManager.close();
}
return new ModelAndView("redirect:/partner");
}
The lines of code that trouble me are:
Partner partnerToUpdate = entityManager.find(Partner.class, partnerId);
partnerToUpdate.setId(partnerId);
partnerToUpdate.setName(partner.getName());
partnerToUpdate.setLogo(partner.getLogo());
partnerToUpdate.setOnScreenText(partner.getOnScreenText());
Do I really need to look up the existing Partner in the database and explicitly update each field of that object? I already have a Partner object with all the right values. Is there no way to store that object directly to the database?
I've already looked at Spring MVC CRUD controller best pactice, but that didn't quite answer my question.
You can use merge to update the desired values, something like:
@RequestMapping(value="/partner/{partnerId}", method=RequestMethod.PUT)
public ModelAndView updatePartner(@ModelAttribute Partner partner, @PathVariable int partnerId) {
EntityManager entityManager = DatabaseHelper.getEntityManager();
try {
entityManager.getTransaction().begin();
partner.setId(partnerId);
entityManager.merge(partner);
entityManager.getTransaction().commit();
}
finally {
entityManager.close();
}
return new ModelAndView("redirect:/partner");
}
Also, I recommend You to use the DAO Pattern and Spring Transaction Support with @Transactional
and @Repository