Hola, estoy empezando con Spring Boot en un sistema RESTful. Tengo dos tablas "usuarios" y "permisos" las cuales tienen una relación de muchos a muchos con una tabla intermedia "usuario_permiso" que solo tiene las llaves foraneas de id_usuario y id_permiso.
Ya he conseguido hacer que me muestre que permisos tiene el usuario desde un GET a "usuarios/{id}/permisos", pero aun no se como hacer para agregar una relación con un POST o borrarla con un DELETE. He probado hacerlo con Querys nativas pero he visto que no se puede hacer INSERT en JPA. ¿Alguna sugerencia de como implementarlo?
Esta es mi entidad Usuario:
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Entity
@Table(name = "usuario")
@NamedQueries({
@NamedQuery(name = "Usuario.findAll", query = "SELECT u FROM Usuario u")})
public class Usuario implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id_usuario")
private Integer idUsuario;
@Size(max = 75)
@Column(name = "nombre")
private String nombre;
@Basic(optional = false)
@NotNull
@Column(name = "status")
private int status;
@ManyToMany
@JoinTable(name = "usuario_permiso", joinColumns = {
@JoinColumn(name = "id_usuario", referencedColumnName = "id_usuario")}, inverseJoinColumns = {
@JoinColumn(name = "id_permiso", referencedColumnName = "id_permiso")})
private Collection<Permiso> permisoCollection;
public Usuario() {
}
public Usuario(Integer idUsuario) {
this.idUsuario = idUsuario;
}
public Usuario(Integer idUsuario, int status) {
this.idUsuario = idUsuario;
this.status = status;
}
public Integer getIdUsuario() {
return idUsuario;
}
public void setIdUsuario(Integer idUsuario) {
this.idUsuario = idUsuario;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public Collection<Permiso> getPermisoCollection() {
return permisoCollection;
}
public void setPermisoCollection(Collection<Permiso> permisoCollection) {
this.permisoCollection = permisoCollection;
}
@Override
public int hashCode() {
int hash = 0;
hash += (idUsuario != null ? idUsuario.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Usuario)) {
return false;
}
Usuario other = (Usuario) object;
if ((this.idUsuario == null && other.idUsuario != null) || (this.idUsuario != null && !this.idUsuario.equals(other.idUsuario))) {
return false;
}
return true;
}
@Override
public String toString() {
return "mx.lania.mca.entidades.Usuario[ idUsuario=" + idUsuario + " ]";
}
}
Esta es mi entidad Permiso
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name = "permiso")
@NamedQueries({
@NamedQuery(name = "Permiso.findAll", query = "SELECT p FROM Permiso p")})
public class Permiso implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id_permiso")
private Integer idPermiso;
@Size(max = 75)
@Column(name = "nombre")
private String nombre;
@JsonIgnore
@ManyToMany(mappedBy = "permisoCollection")
private Collection<Usuario> usuarioCollection;
@JoinColumn(name = "id_modulo", referencedColumnName = "id_modulo")
@ManyToOne(optional = false)
private Modulo idModulo;
public Permiso() {
}
public Permiso(Integer idPermiso) {
this.idPermiso = idPermiso;
}
public Integer getIdPermiso() {
return idPermiso;
}
public void setIdPermiso(Integer idPermiso) {
this.idPermiso = idPermiso;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Collection<Usuario> getUsuarioCollection() {
return usuarioCollection;
}
public void setUsuarioCollection(Collection<Usuario> usuarioCollection) {
this.usuarioCollection = usuarioCollection;
}
public Modulo getIdModulo() {
return idModulo;
}
public void setIdModulo(Modulo idModulo) {
this.idModulo = idModulo;
}
@Override
public int hashCode() {
int hash = 0;
hash += (idPermiso != null ? idPermiso.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Permiso)) {
return false;
}
Permiso other = (Permiso) object;
if ((this.idPermiso == null && other.idPermiso != null) || (this.idPermiso != null && !this.idPermiso.equals(other.idPermiso))) {
return false;
}
return true;
}
@Override
public String toString() {
return "mx.lania.mca.entidades.Permiso[ idPermiso=" + idPermiso + " ]";
}
}
Ambas las he mapeado con el NetBeans.
Este es mi controlador del Usuario:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.lania.permisos.model.Usuario;
import com.lania.permisos.model.Permiso;
import com.lania.permisos.repository.UsuarioRepository;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
@RestController
@RequestMapping("/permisos-api")
public class UsuarioController {
@Autowired
UsuarioRepository userRepository;
@GetMapping("/usuarios")
public List<Usuario> getAllUsuarios() {
return userRepository.findAll();
}
@GetMapping("/usuarios/{id}")
public ResponseEntity<Usuario> getUsuarioById(@PathVariable(value = "id") Integer userId) {
Usuario user = userRepository.findOne(userId);
if(user == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok().body(user);
}
@PostMapping("/usuarios")
public Usuario createUsuario(@Valid @RequestBody Usuario user) {
return userRepository.save(user);
}
@PutMapping("/usuarios/{id}")
public ResponseEntity<Usuario> updateUsuario(@PathVariable(value = "id") Integer userId,
@Valid @RequestBody Usuario userDetails) {
Usuario user = userRepository.findOne(userId);
if(user == null) {
return ResponseEntity.notFound().build();
}
user.setNombre(userDetails.getNombre());
user.setStatus(userDetails.getStatus());
Usuario updatedUser = userRepository.save(user);
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/usuarios/{id}")
public ResponseEntity<Usuario> deleteUusario(@PathVariable(value = "id") Integer userId) {
Usuario user = userRepository.findOne(userId);
if(user == null) {
return ResponseEntity.notFound().build();
}
userRepository.delete(user);
return ResponseEntity.ok().build();
}
@GetMapping("/usuarios/{id}/permisos")
public ResponseEntity<Collection<Permiso>> getPermisosOfUsuario(@PathVariable(value = "id") Integer userId) {
Usuario user = userRepository.findOne(userId);
if(user == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok().body(user.getPermisoCollection());
}
}
}
Script de la base de datos:
CREATE TABLE usuario (
id_usuario serial NOT NULL,
nombre varchar(75) NULL,
status integer NOT NULL
)
;
CREATE TABLE permiso (
id_permiso serial NOT NULL,
nombre varchar(75) NULL,
id_modulo integer NOT NULL,
)
;
CREATE TABLE modulo (
id_modulo serial NOT NULL,
nombre varchar(75) NULL,
ubicacion varchar(45) NULL,
servidor varchar(45) NULL,
version varchar(10) NULL
)
;
CREATE TABLE usuario_permiso (
id_usuario integer NOT NULL,
id_permiso integer NULL
)
;
ALTER TABLE usuario ADD CONSTRAINT PK_usuario
PRIMARY KEY (id_usuario)
;
ALTER TABLE permiso ADD CONSTRAINT PK_permiso
PRIMARY KEY (id_permiso)
;
ALTER TABLE modulo ADD CONSTRAINT PK_modulo
PRIMARY KEY (id_modulo)
;
ALTER TABLE usuario_permiso ADD CONSTRAINT FK_usuario_permiso_1
FOREIGN KEY (id_usuario) REFERENCES usuario (id_usuario)
;
ALTER TABLE usuario_permiso ADD CONSTRAINT FK_usuario_permiso_2
FOREIGN KEY (id_permiso) REFERENCES permiso (id_permiso)
;
ALTER TABLE permiso ADD CONSTRAINT FK_modulo_permiso
FOREIGN KEY (id_modulo) REFERENCES modulo (id_modulo)
;
Gracias de antemano. Saludos.