0

I have been working with thymeleaf and spring boot. I can send data with a form in POST and a simple class. (without Objects lists). I tried to modify (in my form) a "object" that contains a list of objects but in my controller I get the object with the correct data, but the list is null.

I have this class which contains a list of objects:

@Entity
@Table(name = "maquina_modelo")
public class MaquinaModelo implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 30)
    @Column(name = "modelo")
    private String modelo;
    @Basic(optional = false)
    @NotNull
    @Column(name = "anio")
    private int anio;
    
    
    @NotNull
    @Column(name = "costo")
    private BigDecimal costo;
    
    @NotNull
    @Column(name = "depreciacion")
    private BigDecimal depreciacion;
    
    //HACE REFERENCIA AL ATRIBUTO. El CAMPO DE LA CLASE, NO EL DE LA BD.
    @OneToMany(mappedBy = "maquinaModelo")
    @NotFound(action = NotFoundAction.IGNORE)
    private List<RelacionMaquinaModeloGastoIndirecto> relacionMaquinaModeloGastoIndirectoCollection;
    
    public MaquinaModelo() {
       
    }

    public MaquinaModelo(Integer id) {
        this.id = id;
    }

    public MaquinaModelo(Integer id, String modelo, int anio) {
        this.id = id;
        this.modelo = modelo;
        this.anio = anio;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }



    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.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 MaquinaModelo)) {
            return false;
        }
        MaquinaModelo other = (MaquinaModelo) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "MaquinaModelo{" + "id=" + id + ", modelo=" + modelo + ", anio=" + anio + ", costo=" + costo + ", depreciacion=" + depreciacion + ", relacionMaquinaModeloGastoIndirectoCollection="  + '}';
    }

    

    public String getModelo() {
        return modelo;
    }

    public void setModelo(String modelo) {
        this.modelo = modelo;
    }

    public int getAnio() {
        return anio;
    }

    public void setAnio(int anio) {
        this.anio = anio;
    }

    public List<RelacionMaquinaModeloGastoIndirecto> getRelacionMaquinaModeloGastoIndirectoCollection() {
        return relacionMaquinaModeloGastoIndirectoCollection;
    }

    public void setRelacionMaquinaModeloGastoIndirectoCollection(List<RelacionMaquinaModeloGastoIndirecto> relacionMaquinaModeloGastoIndirectoCollection) {
        this.relacionMaquinaModeloGastoIndirectoCollection = relacionMaquinaModeloGastoIndirectoCollection;
    }

    public BigDecimal getCosto() {
        return costo;
    }

    public void setCosto(BigDecimal costo) {
        this.costo = costo;
    }

    public BigDecimal getDepreciacion() {
        return depreciacion;
    }

    public void setDepreciacion(BigDecimal depreciacion) {
        this.depreciacion = depreciacion;
    }
             
    
}

I can do CRUD operations in MaquinaModelo and show the data from List<RelacionMaquinaModeloGastoIndirecto> in this form:

<form th:action="${maquinaModelo.id>0}? @{/costos/admin/maquinaModelo/modificar}:@{/costos/admin/maquinaModelo}" method="post" >
                
            <div class="form-group">
                <input type="hidden"    name="id";
                th:value="${maquinaModelo.id}">

                <div class="input-group">
                    <span class="input-group-addon">Modelo</span>
                    <input th:type="text"
                    th:value="${maquinaModelo.modelo}"
                    name="modelo"
                    class="form-control input-lg mayusculas">
                    <div th:if="${#fields.hasErrors('maquinaModelo.modelo')}" th:errors="${maquinaModelo.modelo}" class="alert alert-danger"></div>
                </div>
            </div>
            <div class="form-group">
                <div class="input-group">
                    <span class="input-group-addon">Año</span>
                    <input th:type="text"
                    th:value="${maquinaModelo.anio}"
                    name="anio"
                    class="form-control input-lg mayusculas">
                    <div th:if="${#fields.hasErrors('maquinaModelo.anio')}" th:errors="${maquinaModelo.anio}" class="alert alert-danger"></div>
                </div>
            </div>
            <div class="form-group">
                <div class="input-group">
                    <span class="input-group-addon">Costo</span>
                    <input th:type="text"
                    th:value="${maquinaModelo.costo}"
                    name="costo"
                    class="form-control input-lg mayusculas">
                    <div th:if="${#fields.hasErrors('maquinaModelo.costo')}" th:errors="${maquinaModelo.costo}" class="alert alert-danger"></div>
                </div>
            </div>
            <div class="form-group">
                <div class="input-group">
                    <span class="input-group-addon">Depreciación</span>
                    <input th:type="text"
                    th:value="${maquinaModelo.depreciacion}"
                    name="depreciacion"
                    class="form-control input-lg mayusculas">
                    <div th:if="${#fields.hasErrors('maquinaModelo.depreciacion')}" th:errors="${maquinaModelo.depreciacion}" class="alert alert-danger"></div>
                </div>
            </div>

            <div class="row">
                <div class="col-xs-12 text-right">
                    <a type="button" class="btn btn-danger BOTON_LIMPIAR" href="/index"> <span class="  glyphicon glyphicon-remove"></span> Cancelar</a>
                    <button type="submit" class="btn btn-success"> <span class="glyphicon glyphicon-floppy-save"></span> <span th:text="${maquinaModelo.id>0}? @{Modificar}:@{Guardar}"></span></button>
                </div>
            </div>
        


            <div class="form-group col-xs-12  ">
                <div class="input-group">
                    <span class="input-group-addon">Gastos indirectos</span>
                    <select class="form-control input-lg lista-articulos" >
                        <option th:each="gasto:${gastosIndirectos}"
                                th:value="${gasto.idGastoIndirecto}"
                                th:text="${gasto.nombreGasto}"> </option>
                    </select>
                </div>
                <a class="btn btn-success btn-cargar-articulo"> + Añadir gasto</a>
            </div>


            <hr>
            <h1>Elementos de gasto indirecto</h1>

            
            <div th:each="costo, i:${maquinaModelo.relacionMaquinaModeloGastoIndirectoCollection}" >
                <div class="form-group">
                <div class="input-group">
                    <span class="input-group-addon" th:text="${costo.gastoIndirecto.nombreGasto}" ></span>
                    <input th:type="text"
                    th:value="${maquinaModelo.relacionMaquinaModeloGastoIndirectoCollection[__${i.index}__].consumoHora}"
                    th:name="${maquinaModelo.relacionMaquinaModeloGastoIndirectoCollection[__${i.index}__]}"
                    class="form-control input-lg mayusculas">
                    <!-- <div th:if="${#fields.hasErrors('maquinaModelo.depreciacion')}" th:errors="${maquinaModelo.depreciacion}" class="alert alert-danger"></div> -->
                </div>
            </div>
            </div>
        </form>

But, when I submit the form the list is empty. How can I get this to work?


UPDATE

@Controller
@RequestMapping(value ="/costos/**")
public class CostosController {

//....



@RequestMapping(value = "admin/maquinaModelo/modificar/{id}", method = RequestMethod.GET)
public ModelAndView maquinaModeloModificar(@PathVariable("id") int id){
    ModelAndView mav = new ModelAndView();
    
    if (maquinaModeloService.exist(id)) {
        MaquinaModelo maquina = maquinaModeloService.find(id);
        mav.addObject("maquinaModelo", maquina);
    } else {
        mav.addObject("error", "El modelo no existe: "+id);
        mav.addObject("maquinaModelo", new MaquinaModelo());
    }
    

    mav.addAllObjects(gds.costos_MaquinaModelo(gds.getUser()));
    mav.setViewName("costos/maquinaModelo");
    return mav;
}

@RequestMapping(value = "admin/maquinaModelo/modificar", method = RequestMethod.POST)
public ModelAndView maquinaModeloModificar(
        MaquinaModelo maquinaModelo,
        BindingResult br
){
    ModelAndView mav = new ModelAndView();
     if (br.hasErrors()) {
        mav.setViewName("costos/maquinaModelo");
        mav.addObject("maquinaModelo", maquinaModelo);
    } else {
        if (maquinaModeloService.update(maquinaModelo)) {
            mav.addObject("success", "El modelo se ha modificado con exito.");
            mav.addObject("maquinaModelo", new MaquinaModelo());
        } else {
            mav.addObject("error", "Algo paso y no se pudo guardar el modelo.");
            mav.addObject("maquinaModelo", maquinaModelo);
        }
    }

    mav.addAllObjects(gds.costos_MaquinaModelo(gds.getUser()));
    mav.setViewName("costos/maquinaModelo");
    return mav;
}

}
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Legna
  • 460
  • 6
  • 19
  • Can you please provide the code for the controller – W.K.S Mar 05 '18 at 22:22
  • could you also select from maquina_modelo and where ever RelacionMaquinaModeloGastoIndirecto maps to and post results here. How do you know the data is not missing in your database? – Andrew Butenko Mar 05 '18 at 22:22
  • I'd just like to clarify; You have a controller that forwards a model (`Maquina`) to a view. This `Maquina` model contains a list. In the view, there is a form which when posted, should submit a new `Maquina` model containing the original list. Is my understanding correct – W.K.S Mar 05 '18 at 22:28
  • @W.K.S. Yes, and modify too. – Legna Mar 05 '18 at 22:58
  • @AndrewButenko (If I understand ) I know it's because I have test data in the BD. Then, I can load in the form (visual confirmation?), but i can't submit the list again to the controller. (POST) Null appears. – Legna Mar 05 '18 at 23:02
  • @Angel did you check this: https://stackoverflow.com/questions/36500731/how-to-bind-an-object-list-with-thymeleaf. They did something similar – Cata Mar 06 '18 at 01:07
  • in your jsp you define set inputs of ${maquinaModelo.relacionMaquinaModeloGastoIndirectoCollection[__${i.index}__].consumoHora as name="${maquinaModelo.relacionMaquinaModeloGastoIndirectoCollection[__${i.index}__]}" but according to https://www.w3.org/TR/html-json-forms/ your naming is incorrect. consider their "EXAMPLE 3: Deeper Structure" there. Plus, I guess you have more than one field "consumoHora" in your RelacionMaquinaModeloGastoIndirecto. – Andrew Butenko Mar 06 '18 at 02:05
  • @Cata. Thank you. The link helped me find the answer. – Legna Mar 06 '18 at 14:34
  • @AndrewButenko That's I looking for. Now is working. Thank you. – Legna Mar 06 '18 at 14:37

0 Answers0