0

I try to get an string from a java object with thymeleaf and using java Spring as framework but I get a error , the error is:

org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method getSrc() cannot be found on type java.lang.String

The html code is :

<div th:each="product: ${products}">
    <div class="col-1">
        <div class="gallery">
            <div th:each="imgg :${product.id}+img">
                <p th:text="${imgg.getSrc()}"></p>
            </div>
            <div class="desc">
                <p th:text="${product.name}"></p>
            </div>
        </div>
    </div>
</div>

And the controller is:

@GetMapping("/")
public String dashboard(ModelMap model) {
  List < CpuProduct > CpuProducts = cpurepo.findAll();

  model.put("products", CpuProducts);

  CpuProducts.forEach(prod ->{

    model.put(prod.getId() + "img", prod.getPhotos());
  });

  return "index";
}

The CpuProduct class is :

    package com.deiutz.BuildIT.User.products;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderColumn;

@Entity
public class CpuProduct {

    private long id;
    private double price;
    private String description;
    private String model;
    private String name;
    private Set<Image> photos;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        // TODO Auto-generated method stub
        return id;
    }

    public void setId(long id) {
        this.id = id;

    }

    public double getPrice() {
        // TODO Auto-generated method stub
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }


    public String getDescrpiton() {

        return description;
    }


    public void setDescrpiton(String description) {
        this.description = description;

    }


    public String getModel() {

        return model;
    }


    public void setModel(String model) {
        this.model = model;

    }


    public String getName() {

        return name;
    }


    public void setName(String name) {
        this.name = name;

    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "product")
    @OrderColumn
    public Set<Image> getPhotos() {
        return this.photos;
    }


    public void setPhotos(Set<Image> photos) {
        this.photos = photos;

    }


}

The Image class is :

    package com.deiutz.BuildIT.User.products;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity

public class Image {

    private long id;
    private byte[] foto;
    private CpuProduct product;
    private String src = "img/" + id;


    public byte[] getFoto() {
        return foto;
    }

    public void setFoto(byte[] foto) {
        this.foto = foto;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }


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

    @ManyToOne()
    public CpuProduct getProduct() {
        return product;
    }

    public void setProduct(CpuProduct product) {
        this.product = product;
    }

    public String getSrc() {
        return src;
    }

    public void setSrc(String src) {
        this.src = src;
    }

}
1
  • How is your CpuProduct object? Does the class have all getters and setters? Also your other object "images" I guess, has getters and setters? Commented Nov 25, 2020 at 22:19

1 Answer 1

1

I'm not sure what is causing your problem. Probably you can't access variables in the model map by adding two strings in the template, it will only concat it to string.

On other hand, I can offer you a solution (a cleaner one). In short, let's put in one model a map of photos mapped by product id rather than put 'n' models by product id that contains photos.

model.put("products", cpuProducts);

Map<Integer, List<Photo>> photosByProduct = cpuProducts.stream()
            .collect(Collectors.toMap(CpuProduct::getId, CpuProduct::getPhotos));

//          Or using forEach
//
//          Map<Integer, List<Photo>> photosByProduct = new HashMap<>();
//          cpuProducts.forEach(cpuProduct -> {
//              photosByProduct.put(cpuProduct.getId(), cpuProduct.getPhotos())
//          });

model.put("photos", photosByProduct);

<div th:each="product: ${products}">
    <div class="col-1">
        <div class="gallery">
            <div th:each="photo: ${photos.get(product.id)}">
                <p th:text="${photo.src}"></p>
            </div>
            <div class="desc">
                <p th:text="${product.name}"></p>
            </div>
        </div>
    </div>
</div>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.