entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

1voto

JPA @ManyToMany Tabla intermedia con más valores que FKs

¡Saludos!

Estoy haciendo un Backend (Spring Boot, JPA) y mi problema es el siguiente:

Tablas

  • Empleado
  • Equipo_Empleado
  • Equipo

Como se pueden dar cuenta hay una relación en Empleado - Equipo de Muchos a Muchos (Necesito llevar un historial) y mi tabla Equipo_Empleado quiero utilizarla para tener no sólo los FK, sino tengo datos extras, FechaAlta, FechaBaja, Comentario_Alta, Comentario_Baja.

Pongo mis Modelos:

Empleado:

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@Table(name = "Empleado")
public class Empleado {

    @Column(name = "PK_Empleado", insertable = false, updatable = false)
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer idEmpleado;

    @OneToOne
    @JoinColumn(name = "FK01_Unidad", nullable = false)
    private Caracteristica red;

    @Column(name = "Nombre", nullable = false, length = 100, insertable = true, updatable = true)
    private String nombre;

    @Column(name = "Apellido_Paterno", nullable = false, length = 100, insertable = true, updatable = true)
    private String apellidoPaterno;

    @Column(name = "Apellido_Materno", nullable = true, length = 100, insertable = true, updatable = true)
    private String apellidoMaterno;

    @Column(name = "Usuario", nullable = false, length = 50, insertable = true, updatable = true)
    private String usuario;

    @Column(name = "Num_Empleado", nullable = false, length = 50, insertable = true, updatable = true)
    private String numEmpleado;

    @Column(name = "Fecha_Sistema", nullable = false, insertable = false, updatable = false)
    @JsonFormat(pattern="MM/dd/YYYY")
    private Date fechaSistema;

    @Column(name = "Fecha_Alta", nullable = false, insertable = true, updatable = true)
    @JsonDeserialize(using = DateAndTime.class)
    @JsonFormat(pattern="MM/dd/YYYY")
    private Date fechaAlta;

    @Column(name = "Fecha_Baja", nullable = true, insertable = true, updatable = true)
    @JsonDeserialize(using = DateAndTime.class)
    @JsonFormat(pattern="MM/dd/YYYY")
    private Date fechaBaja;

    @Column(name = "Habilitado", nullable = false, length = 1, insertable = true, updatable = true)
    private Integer habilitado;

    @ManyToMany(cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
    })
    @JoinTable(
        name = "Equipo_Empleado",
        joinColumns = @JoinColumn(name = "FK01_Equipo", nullable = false),
        inverseJoinColumns = @JoinColumn(name = "FK02_Empleado", nullable = false) )
    private Set<Equipo> lstEquipos = new HashSet<>();

    public void addEquipo(Equipo equipo) {
        if (this.lstEquipos == null) {
            this.lstEquipos = new HashSet<>();
        }
        this.lstEquipos.add(equipo);
    }

    public void removeEquipo(Equipo equipo) {
        lstEquipos.remove(equipo);
        equipo.getLstEmpleado().remove(this);
    }
        /* SETTERS AND GETTERS*/
}

Equipo:

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@Table(name = "Equipo")
public class Equipo {

    @Column(name = "PK_Equipo", insertable = false, updatable = false)
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer idEquipo;

    @OneToOne
    @JoinColumn(name = "FK01_Propietario", nullable = false)
    private Caracteristica contrato;

    @OneToOne
    @JoinColumn(name = "FK02_Unidad", nullable = false)
    private Caracteristica red;

    @OneToOne
    @JoinColumn(name = "FK03_Zona", nullable = false)
    private Caracteristica zona;

    @OneToOne
    @JoinColumn(name = "FK04_Subzona", nullable = true)
    private Caracteristica subzona;

    @OneToOne
    @JoinColumn(name = "FK05_Area", nullable = true)
    private Caracteristica area;

    @OneToOne
    @JoinColumn(name = "FK06_Marca", nullable = true)
    private Caracteristica marca;

    @OneToOne
    @JoinColumn(name = "FK07_Estado", nullable = false)
    private Caracteristica estado;

    @OneToOne
    @JoinColumn(name = "FK08_Tipo", nullable = false)
    private Caracteristica tipo;

    @Column(name = "Fecha_Sistema", nullable = false, insertable = false, updatable = false)
    @JsonFormat(pattern="MM/dd/YYYY")
    private Date fechaSistema;

    @Column(name = "Fecha_Alta", nullable = false, insertable = true, updatable = true)
    @JsonDeserialize(using = DateAndTime.class)
    @JsonFormat(pattern="MM/dd/YYYY")
    private Date fechaAlta;

    @Column(name = "Fecha_Baja", nullable = true, insertable = true, updatable = true)
    @JsonDeserialize(using = DateAndTime.class)
    @JsonFormat(pattern="MM/dd/YYYY")
    private Date fechaBaja;

    @Column(name = "Modelo", nullable = false, length = 100, insertable = true, updatable = true)
    private String modelo;

    @Column(name = "Serie", nullable = false, length = 100, insertable = true, updatable = true)
    private String serie;

    @Column(name = "ID", nullable = false, insertable = true, updatable = true)
    private Integer id;

    @Column(name = "Folio", nullable = false, length = 100, insertable = true, updatable = true)
    private String folio;

    @Column(name = "Costo", scale = 8, nullable = false, length = 100, insertable = true, updatable = true)
    private double costo;

    @Column(name = "Descripcion", nullable = false, length = 300, insertable = true, updatable = true)
    private String descripcion;

    @Column(name = "Arrendada", nullable = false, length = 1, insertable = true, updatable = true)
    private Integer arrendada;

    @Column(name = "Activo", nullable = false, length = 1, insertable = true, updatable = true)
    private Integer activo;

    @Column(name = "Habilitado", nullable = false, length = 1, insertable = true, updatable = true)
    private Integer habilitado;

    @ManyToMany(mappedBy = "lstEquipos")
    private Set<Empleado> lstEmpleado = new HashSet<>();

       /* SETTERS AND GETTERS*/
}

Recurso

@RestController
@RequestMapping("/empleado")
public class EmpleadoRecurso {

    @Autowired
    private EmpleadoService empleadoService;

    @RequestMapping(
            value = "/guardarEmpleado",
            method = RequestMethod.POST,
            consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    public Empleado guardarEmpleado(@RequestBody Empleado empleado) {
        return empleadoService.guardarEmpleado(empleado);
    }
}

Servicio:


@Service
public class EmpleadoService {

    @Autowired
    private EmpleadoDAO empleadoDAO;

    public Empleado guardarEmpleado(Empleado empleado) {
        try {
            empleado = empleadoDAO.save(empleado);
            return empleado;
        } catch (Exception e) {
            e.printStackTrace();
            return new Empleado();
        }
    }
}

Persistencia:

public interface EmpleadoDAO extends JpaRepository<Empleado, Integer> {
}

Funciona cuando a mi tabla Equipo_Empleado tiene que acepta NULL los los campos de fechas y comentarios, porque obviamente no van en la inserción que hace JPA, pero no sé como incluirlos, claro, podría hacer que actualice los campos después de crearlos, pero he estado buscando una forma de hacerlo en un solo paso.
Ya busqué mucha documentación de JPA y @ManyToMany, pero nada, lo único que indican es insertar FKs, o ¿está mal cómo lo he pensado? Es una mala práctica?

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta