Spring MVC 3.0: Comment puis-je lier à un objet persistant
-
01-10-2019 - |
Question
Je travaille avec Spring MVC et je voudrais à lier un objet persistant de la base de données, mais je ne peux pas comprendre comment je peux mettre mon code pour faire un appel à la DB avant de se lier. Par exemple, je suis en train de mettre à jour cependant, un objet « BenefitType » à la base de données, je veux obtenir la base de données lesemployés objet, pas créer un nouveau, donc je n'ai pas de mettre à jour tous les champs.
@RequestMapping("/save")
public String save(@ModelAttribute("item") BenefitType benefitType, BindingResult result)
{
...check for errors
...save, etc.
}
La solution 2
Alors j'ai fini par résoudre ce annoter par une méthode avec un @ModelAttribute du même nom dans la classe. Spring construit le premier modèle avant d'exécuter la mise en correspondance de la demande:
@ModelAttribute("item")
BenefitType getBenefitType(@RequestParam("id") String id) {
// return benefit type
}
Autres conseils
Il y a plusieurs options:
-
Dans le cas où votre simpliest objet a seulement des propriétés simples que vous pouvez lier toutes ses propriétés aux champs de formulaire (
hidden
si nécessaire), et d'obtenir un objet entièrement lié après soumission. propriétés complexes peuvent également être liés aux champs de formulaire en utilisantPropertyEditor
s. -
Vous pouvez également utiliser la session pour stocker votre objet entre les demandes de
GET
etPOST
. Printemps 3 faciliates cette approche avec l'annotation@SessionAttributes
(de l'échantillon Petclinic ):@Controller @RequestMapping("/owners/*/pets/{petId}/edit") @SessionAttributes("pet") // Specify attributes to be stored in the session public class EditPetForm { ... @InitBinder public void setAllowedFields(WebDataBinder dataBinder) { // Disallow binding of sensitive fields - user can't override // values from the session dataBinder.setDisallowedFields("id"); } @RequestMapping(method = RequestMethod.GET) public String setupForm(@PathVariable("petId") int petId, Model model) { Pet pet = this.clinic.loadPet(petId); model.addAttribute("pet", pet); // Put attribute into session return "pets/form"; } @RequestMapping(method = { RequestMethod.PUT, RequestMethod.POST }) public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) { new PetValidator().validate(pet, result); if (result.hasErrors()) { return "pets/form"; } else { this.clinic.storePet(pet); // Clean the session attribute after successful submit status.setComplete(); return "redirect:/owners/" + pet.getOwner().getId(); } } }
Cependant, cette approche peut causer des problèmes si plusieurs instances de la forme sont ouverts simultanément dans la même session.
-
Ainsi, l'approche la plus fiable pour les cas complexes est de créer un objet distinct pour stocker des champs de formulaire et les changements de fusion de cet objet en objet persistant manuellement.
Il est possible que votre modèle de domaine est si simple que vous pouvez objets UI lier directement aux objets du modèle de données, il est plus probable que ce n'est pas, dans ce cas, je vous recommande vivement de concevoir une classe spécifique pour la forme liaison, puis de traduire entre elle et les objets de domaine dans votre contrôleur.
Je suis un peu confus. Je pense que vous parlez en fait un flux de travail de mise à jour?
Vous avez besoin de deux @RequestMappings, l'une pour GET et POST un pour:
@RequestMapping(value="/update/{id}", method=RequestMethod.GET)
public String getSave(ModelMap model, @PathVariable Long id)
{
model.putAttribute("item", benefitDao.findById(id));
return "view";
}
puis sur le POST réellement mettre à jour le champ.
Dans exemple ci-dessus vous, votre @ModelAttribute devrait déjà être rempli avec une méthode comme la méthode ci-dessus, et les propriétés lié en utilisant quelque chose comme tabglibs JSTL ou au printemps conjointement avec l'objet de support de forme.
Vous pouvez également regarder initBinder en fonction de votre cas d'utilisation.