Los valores de @PathVariable y @ModelAttribute se superponen
Yo tengo unUser
objeto almacenado en la sesión con@SessionAttributes
. Y un método sencillo decorado con@ModelAttribute
para inicializarlo siempre que el valor de la sesión sea nulo.
Clase de usuario
@Entity
@Table( name="USER")
public class User implements java.io.Serializable {
private Long id;
private String username;
private String password;
....
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name ="ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
...
Controlador:
@RequestMapping("/item")
@Controller
@SessionAttributes({"user"})
public class MyController {
Método @ModelAttribute:
@ModelAttribute("user")
public User createUser(Principal principal) {
return userService.findByUsername(principal.getName());
}
Todo parece funcionar como se espera, excepto en este método particular:
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String showItem(@PathVariable("id") Long id, @ModelAttribute("user") User user,
Model uiModel) {
...
}
El problema es eseUser.id
está siendo configurado con@PathVariable("id")
. Creo que me encontré con esto con@RequestParam
también. Supongo que eso se debe a que ambos tienen el mismo nombre y tipo. Despues de leerDocumentación de primavera (ver más abajo) Supongo que este es el comportamiento esperado:
El siguiente paso es el enlace de datos. La clase WebDataBinder coincide con los nombres de los parámetros de solicitud, incluidos los parámetros de cadena de consulta y los campos de formulario, para modelar los campos de atributos por nombre. Los campos coincidentes se completan después de que se haya aplicado la conversión de tipo (desde Cadena al tipo de campo de destino) donde sea necesario.
Sin embargo, creo que este escenario es bastante común, ¿cómo lo manejan otras personas? Si mis conclusiones son correctas y este es el comportamiento esperado (o error), parece ser muy propenso a errores.
Soluciones posibles:
Cambio@PathVariable("id")
a@PathVariable("somethingElse")
. Funciona pero no es tan sencillo con @RequestParam (por ejemplo, no sé cómo cambiar la identificación del parámetro de solicitud de jqgrid a otra cosa, pero este es otro problema).Cambio@PathVariable("id")
tipo de largo a int. Esto haráUser.id
yid
Los tipos difieren, pero el elenco de Long se ve feo :)No usar@ModelAttribute
Aquí y consulta el DB paraUser
otra vez. No es consistente con otros métodos e involucra llamadas redundantes de base de datos.¿Alguna sugerencia?