-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
Henry Lai opened SPR-3045 and commented
inside the org.springframework.samples.petclinic.webAddOwnerForm.onSubmit method
the owner.getId() is always null!
protected ModelAndView onSubmit(Object command) throws ServletException {
Owner owner = (Owner) command;
// delegate the insert to the Business layer
getClinic().storeOwner(owner);
return new ModelAndView(getSuccessView(), "ownerId", owner.getId());
}
in org.springframework.samples.petclinic.jpa.EntityManagerClinic
public void storeOwner(Owner owner) throws DataAccessException {
em.merge(owner);
}
when the owner object is unmanaged, invoking entityManager.merge( owner) return a different manage instance of owner, the id is assigned to the manage instance not the unmanage instance.
changed to
public void storeOwner(Owner owner) throws DataAccessException {
if ( owner.getId() == null ){
em.persist(owner);
} else {
em.merge(owner);
}
ClinicController
public ModelAndView ownerHandler(HttpServletRequest request, HttpServletResponse response) {
Owner owner = this.clinic.loadOwner(ServletRequestUtils.getIntParameter(request, "ownerId", 0));
if (owner == null) {
return new ModelAndView("findOwnersRedirect");
}
return new ModelAndView().addObject(owner);
}
the clinic.loadOwner method only loads the owner, does not load the owner.pets and pet.visits
therefore when the view owner.jsp reference owner.pets, and pet.visits, they are not shown, even though they exist in the DB, but did not get lazy load exception.
after configuring the OpenEntityManagerInViewFilter in web.xml the problem was resolved. This should be documented in the petclinic jpa docs.
AddPetForm
protected Object formBackingObject(HttpServletRequest request) throws ServletException {
Owner owner = getClinic().loadOwner(ServletRequestUtils.getRequiredIntParameter(request, "ownerId"));
Pet pet = new Pet();
owner.addPet(pet);
return pet;
}
the formBackingObject method adds a new pet to the owner object, which cause the pet object to be inserted to the DB, the next time the persistence context is flush, at this point most of the fields in the pet object is null, the flush result in null contraint exception.
The flush was occur inside referenceData method, in getClinic().getPetTypes() resulting in null contraint exception.
changed the code as follows
protected Object formBackingObject(HttpServletRequest request) throws ServletException {
Owner owner = getClinic().loadOwner(ServletRequestUtils.getRequiredIntParameter(request, "ownerId"));
Pet pet = new Pet();
pet.setOwner( owner );
return pet;
}
Affects: 2.0.1