Duplicate similar objects to contain different data?

0

Context

I have a somewhat complex structure of classes that resemble a tree in this way.

  • Quotation
    • Processes
      • Activities
        • Machines
          • Expenses

So I can have something like this:

Cotizacion1
    Proceso1
        RelacionProcesoActividad1(Actividad1)
             RelacionActividadMaquina1(Maquina1) - segundos int
                 RelacionMaquinaGasto1 (Gasto1)
             RelacionActividadMaquina2
                 RelacionMaquinaGasto1
                 RelacionMaquinaGasto2
         RelacionProcesoActividad2
             RelacionActividadMaquina2
                 RelacionMaquinaGasto1
                 RelacionMaquinaGasto2
     Proceso2
        RelacionProcesoActividad1
             RelacionActividadMaquina1
                 RelacionMaquinaGasto1
             RelacionActividadMaquina2
                 RelacionMaquinaGasto1
                 RelacionMaquinaGasto2
     Proceso3
        RelacionProcesoActividad1
             RelacionActividadMaquina1
                 RelacionMaquinaGasto1
             RelacionActividadMaquina2
                 RelacionMaquinaGasto1
                 RelacionMaquinaGasto2
         RelacionProcesoActividad2
             RelacionActividadMaquina2
                 RelacionMaquinaGasto1
                 RelacionMaquinaGasto2

The object RelacionMaquinaGasto1 for obvious reasons has exactly the same data in all parts except the seconds and an id of a class with which it is related. That class with which it is related allows me to store the data independently (in relation to the seconds and machines) and this is its structure:

RelacionCotizacionMacro

  • id (int) This is the id that we store in RelacionMaquinaGasto1
  • Cotizacion
  • Proceso
  • Actividad
  • Maquina
  • segundos (int) These are the seconds that we store.

This class is stored directly in the database with this same structure, the difference is that the classes are replaced by the id that exist.

What can I do?

  • I create my structure as at the beginning and can save it and consult it.
  • I can access the data that is repeated.
  • I can save the seconds in the table RelacionCotizacionMacro
  • I can save this information in the database with this code without any problem:

                //CONVERTIMOS EL MANEJO DE PROCESOS A MAQUINAS.
                for (Proceso proceso : manejoDeProcesos.getProcesos()) {
                    for (RelacionProcesoActividad relacionProcesoActividad
                            : proceso.getRelacionProcesoActividad()) {
                        for (RelacionActividadMaquinaModelo relacionActividadMaquinaModelo
                                : relacionProcesoActividad.getActividad().getRelacionActividadMaquinaModelo()) {
    
                            cotizacion.addrelacionCotizacionMacro()
                                    .setProceso(proceso)
                                    .setCotizacion(cotizacion)
                                    .setActividad(relacionProcesoActividad.getActividad())
                                    .setMaquinaModelo(relacionActividadMaquinaModelo.getMaquinaModelo())
                                    .setSegundos(relacionActividadMaquinaModelo.getSegundos());
                        }
                     }
                  }
    

Once I save the data in RelacionCotizacionMacro I try to modify them. For this I have to follow this procedure.

  • Consult all the data that you save in RelacionCotizacionMacro and that match the quote that I want to modify. I get a arrayList as a result of type RelacionCotizacionMacro .

  • Filter the duplicate processes and I get a new arraylist of type Proceso without duplicates. Automatically the structure that has the tree that I described at the beginning was generated because spring consulted the already existing processes and with it all the relations that had already been defined were brought. (The activities that are related to the process, the machines related to the activities and finally the expenses associated with the machines, all within their relationships)

  • The problem

    When I save the data I do it from the html and spring understands that they are different data (I do not know why it does so), but if I try to traverse the tree from java and assign data (the seconds to the relation of the machine) these are overwritten because I am modifying the same instance.

    This is what I have tried.

     for (RelacionCotizacionMacro rcm : manejoDeProcesos.getCotizacion().getRelacionCotizacionMacro()) {
                for (Proceso proceso : procesosNew) {
                    for (RelacionProcesoActividad rpa : proceso.getRelacionProcesoActividad()) {
                        for (RelacionActividadMaquinaModelo ramm : rpa.getActividad().getRelacionActividadMaquinaModelo()) {
    
    
                            boolean x = rcm.getProceso().getId() == proceso.getId();
                            boolean y = rcm.getActividad().getId() == rpa.getActividad().getId();
                            boolean z = rcm.getMaquinaModelo().getId() == ramm.getMaquinaModelo().getId();
                            boolean a = !ramm.isAsignado();
    
                            if (x && y && z && a) {
                                //Ponemos el flag asignado a la máquina puesto
                                //que puede haber muchas máquinas iguales. 
                                ramm.setAsignado(true);
                                //Copiamos los segundos. 
                                ramm.setSegundos(rcm.getSegundos());
                                //Este dato lo ocupo copiar para despues actualizar en la BD
                                ramm.setIdRelacionCotizacionMacro(rcm.getId());
                            }
                        }
                    }
                }
    

    Try to create new objects this way:

    //CREAMOS LA NUEVA LISTA DE PROCESOS QUE CONTENDRA MANEJO DE PROCESOS
            List<Proceso> procesosNew = new ArrayList<>();
    
            //CARGAMOS TODOS LOS PROCESOS QUE SE GUARDARON EN LA COTIZACIÓN Y LOS 
            // FILTRAMOS PARA QUITAR LOS REPETIDOS. 
            List<Proceso> procesosParaCargar = manejoDeProcesos.getCotizacion().getRelacionCotizacionMacro()
                    .stream()
                    //AGRUPAMOS POR PROCESOS.
                    .collect(Collectors.groupingBy(a -> a.getProceso() ))
                    .entrySet()
                    .stream()
                    .filter(e -> e.getValue().size() > 1)
                    .map(e -> e.getKey())
                    .collect(Collectors.toList());
            //ITINERAMOS SOBRE LOS PROCESOS QUE NO ESTAN REPETIDOS PARA COPIARLOS.
    
            procesosParaCargar.forEach(p->{
                //CREAMOS UNA NUEVA INSTANCIA DE PROCESO Y LA COPIAMOS. 
                Proceso procesoNew = new Proceso();
    
                //COPIAMOS TODOS LOS DATOS DEL PROCESO. 
                procesoNew
                        .setChecked(p.isChecked())
                        .setCostoTotalDeProceso(p.getCostoTotalDeProceso())
                        .setDepartamento(p.getDepartamento())
                        .setDescripcion(p.getDescripcion())
                        .setId(p.getId())
                        .setMateriaPrima(p.isMateriaPrima())
                        .setNombre(p.getNombre());
    
                procesosNew.add(p);
    
                //COPIAMOS LAS RELACIONES
                p.getRelacionProcesoActividad().forEach(rpa->{
    
                    Actividad actividadRPA = rpa.getActividad();
    
                    //CREAMOS UNA NUEVA ACTIVIDAD Y LA COPIAMOS
                    Actividad actividadNew = new Actividad();
                    actividadNew
                            .setDescripcion(actividadRPA.getDescripcion())
                            .setId(actividadRPA.getId())
                            .setNombre(actividadRPA.getNombre())
                            .setTotalGastos(actividadRPA.getTotalGastos());
    
    
                    //AGREGAMOS LOS GASTOS
                    actividadRPA.getRelacionActividadGasto().forEach(relGasto->{
                        //CREAMOS LA NUEVA COPIA DE GASTO
                        Gasto gastoRelGasto = relGasto.getGasto();
    
                        Gasto gastoNew = 
                                new Gasto()
                                .setCostoPorUnidad(gastoRelGasto.getCostoPorUnidad())
                                .setId(gastoRelGasto.getId())
                                .setNombreGasto(gastoRelGasto.getNombreGasto())
                                .setSegundos(gastoRelGasto.getSegundos())
                                .setUnidad(gastoRelGasto.getUnidad())
                                ;
    
    
                        //CREAMOS UNA NUEVA RELACION DE GASTO
                        RelacionActividadGasto relGastoNew = 
                                new RelacionActividadGasto()
                                .setActividad(actividadNew)
                                .setAsignado(relGasto.isAsignado())
                                .setGasto(gastoNew)
                                .setId(relGasto.getId())
                                .setIdRelacionCotizacionMacroGasto(relGasto.getIdRelacionCotizacionMacroGasto())
                                .setOrdenDeOperacion(relGasto.getOrdenDeOperacion())
                                .setSegundos(relGasto.getSegundos())
                                .setTotalGasto(relGasto.getTotalGasto())
                                ;
                        //ASIGANMOS LA NUEVA RELACION A LOS GASTOS DE LA ACTIVIDAD
                        actividadNew.getRelacionActividadGasto().add(relGastoNew);
                    });
    
                    //AGREGAMOS LAS MÁQUINAS.
                    actividadRPA.getRelacionActividadMaquinaModelo().forEach(relMaquina->{
                        //OBTENEMOS LA MAQUINA DE LA RELACION
                        MaquinaModelo maquinaModeloRel = relMaquina.getMaquinaModelo();
    
    
                        //CREAMOS LA NUEVA MÁQUINA
                        MaquinaModelo maquinaModeloNew = 
                                new MaquinaModelo()
                                .setAnio(maquinaModeloRel.getAnio())
                                .setCosto(maquinaModeloRel.getCosto())
                                .setCostoDepreciacionSegundo(maquinaModeloRel.getCostoDepreciacionSegundo())
                                .setCostoDepreciacionTotal(maquinaModeloRel.getCostoDepreciacionTotal())
                                .setDepreciacion(maquinaModeloRel.getDepreciacion())
                                .setId(maquinaModeloRel.getId())
                                .setModelo(maquinaModeloRel.getModelo());
    
                        //AGREGAMOS LOS GASTOS DE LA MAQUINA 
    
                        maquinaModeloRel.getRelacionMaquinaModeloGasto().forEach(relGasto->{
    
                            //OBTENEMOS EL GASTO DE LA RELACIÓN
                            Gasto gastoRel = relGasto.getGasto();
    
                            //CREAMOS EL NUEVO GASTO
                            Gasto gastoNew = 
                                    new Gasto()
                                    .setCostoPorUnidad(gastoRel.getCostoPorUnidad())
                                    .setId(gastoRel.getId())
                                    .setNombreGasto(gastoRel.getNombreGasto())
                                    .setSegundos(gastoRel.getSegundos())
                                    .setUnidad(gastoRel.getUnidad());
    
                            //CREAMOS LA RELACION
                            RelacionMaquinaModeloGasto relGastoNew = 
                                    new RelacionMaquinaModeloGasto()
                                    .setConsumoHora(relGasto.getConsumoHora())
                                    .setCostoPorSegundo(relGasto.getCostoPorSegundo())
                                    .setCostoTotal(relGasto.getCostoTotal())
                                    .setGasto(gastoNew)
                                    .setId(relGasto.getId())
                                    .setMaquinaModelo(maquinaModeloNew);
    
                            maquinaModeloNew.getRelacionMaquinaModeloGasto().add(relGastoNew);
                        });
    
    
                        //CREAMOS LA NUEVA RELACION
                        RelacionActividadMaquinaModelo relMaquinaNew = 
                                new RelacionActividadMaquinaModelo()
                                .setActividad(actividadNew)
                                .setAsignado(relMaquina.isAsignado())
                                .setCostoTotalMaquina(relMaquina.getCostoTotalMaquina())
                                .setId(relMaquina.getId())
                                .setIdRelacionCotizacionMacro(relMaquina.getIdRelacionCotizacionMacro())
                                .setMaquinaModelo(maquinaModeloNew)
                                .setOrdenDeOperacion(relMaquina.getOrdenDeOperacion())
                                .setSegundos(relMaquina.getSegundos());
    
                        actividadNew.getRelacionActividadMaquinaModelo().add(relMaquinaNew);
    
                    });
    
                    //CREAMOS UNA NUEVA RELACIÓN Y LA COPIAMOS.                 
                    RelacionProcesoActividad relProAct = new RelacionProcesoActividad();
                    relProAct
                            .setActividad(actividadRPA)
                            .setAsignada(rpa.isAsignada())
                            .setCostoTotalDeActividad(rpa.getCostoTotalDeActividad())
                            .setId(rpa.getId())
                            .setOrdenDeProceso(rpa.getOrdenDeProceso())
                            .setProceso(p)
                            .setTotalGastos(rpa.getTotalGastos());
    
                    procesoNew.getRelacionProcesoActividad().add(relProAct);
                });
            });
    

    But I do not get good results. When the objects are repeated, I ignore the flag of the machine.

    What can not I do?

    Load the seconds of the machine saved in RelacionCotizacionMacro roaming on List<Proceso> to find the matches and display them in the html with their corresponding pair.

        
    asked by Angel 11.05.2018 в 20:07
    source

    1 answer

    1

    Let's see if I understood.

    You need, that the object RelacionMaquinaGasto1 has the same Id (PK) to relate it in the DB with the parent objects ... BUT the object changes its idPadree and number of seconds ... nevertheless spring at the time of doing the mapping identifies each object RelacionMaquinaGasto1 (child) as a different one in each parent object (that is, it is not the same as it changes its PK).

    That I understand.

    What I see, is that you are trying to make a many-to-many relationship (Many RelacionProcesoActivity can have many RelacionMaquinaGasto1 and vice versa)

    The most logical thing to do would be to normalize, that is, create an identity called RelacionProcesoActivityRelacionMaquinaGasto1 that has the following:

    A unique id, and an object of type RelacionProcesoActivity, an object of type RelacionMaquinaGasto1 and the time in seconds in which it differs

    That is, it eliminates the seconds of the object RelacionMaquinaGasto1 and adds them to the new object RelacionProcesoActividadRelacionMaquinaGasto1, in this way the structure of the object RelacionMaquinaGasto1 does not change and spring will not generate new objects trying to satisfy the needs of the injection of dependencies.

        
    answered by 13.05.2018 в 03:21