2

This webapp is made with spring boot connected to MariaDB .I would like to view the items in each category, I can see the category attributes and can see the item in the view as such [Item [id=1, title=test, description=11, status=Used, zipcode=1231, price=111.0, category=Category [id=3, type=Services]]]

heres my controller

    @RequestMapping(value="/item-by-category/{id}",method= RequestMethod.GET)
public String itemByCategory(@PathVariable("id") Long categoryid, Model model){
    //model.addAttribute("items",irepository.findByCategory(categoryid));
    model.addAttribute("categorys",crepository.findOne(categoryid));
    //model.addAttribute("item",irepository.findByCategory(categoryid));
    return "/item-by-category";

}

Im using CRUD repositories so I tried to use the itemRepository method to filter the items by category but I get an error on the type of attribute passed even if its of type Long as stated in the class initiation.

Repositories:

public interface ItemRepository extends CrudRepository<Item, Long> {
    List<Item> findByTitle(String title);

    List<Item> findByCategory(Long categoryid);

}

public interface CategoryRepository extends CrudRepository<Category, Long> {
    //find by cat type
    List<Category> findByType(String type);

    //List<Category>findByItem(String item);
    //Item findByCategory(String type);
    //show the items in the categories
    //List<Item>items(String type);
    //List<Category>findByItem(String item);
}   

classes :

    @Entity
@Table(name="category")
public class Category {
    //@id creates an ID column for the table
    @Id
    //Generates automatically a unique PK for every new entity object
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="categoryid")
    private Long id;
    @Column(name="type")
    private String type;


    // 1 Category can have * Items
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "category")
    private List<Item> item;


    //constructor
    public Category() {}

    public Category(String type) {
        super();
        this.type = type;
    }



    //getters n setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    //getters n setters for relationship

    public List<Item> getItems() {
        return item;
    }

    public void setItems(List<Item> item) {
        this.item = item;
    }



    @Override
    public String toString() {
        return "Category [id=" + id + ", type=" + type + "]";
    }

}


@Entity
@Table(name="item")
public class Item {
    //generated ID column 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="itemid")
    private Long id;


    @Column(name="title")
    private String title;

    @Column(name="description")
    private String description;

    @Column(name="status")
    private String status;


    @Column(name="zipcode",length=5)
    private Integer zipcode;

    @Column(name="price")
    private Double price;

    //create relationship or * to 1 between items to user
    /*
    @ManyToOne
    @JsonIgnore
    @JoinColumn(name = "userid")
    private User user;
    */

    //Many items can have 1 category * to 1
    @ManyToOne
    /*entity relationship will
    cause endless loop (First item is serialized and it contains
    category which is then serialized which contains students which
    are then serialized
    */
    @JsonIgnore
    @JoinColumn(name = "categoryid")
private Category category;

    //working ^^
    //JPA constructor
    public Item(){

    }

    public Item(Long id, String title, String description, String status, Integer zipcode, Double price,
            Category category) {
        super();
        this.id = id;
        this.title = title;
        this.description = description;
        this.status = status;
        this.zipcode = zipcode;
        this.price = price;
        this.category = category;
    }

    public Long getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Integer getZipcode() {
        return zipcode;
    }

    public void setZipcode(Integer zipcode) {
        this.zipcode = zipcode;
    }

    public Double getPrice() {
        return price;
    }

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

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    @Override
    public String toString() {
        return "Item [id=" + id + ", title=" + title + ", description=" + description + ", status=" + status
                + ", zipcode=" + zipcode + ", price=" + price + ", category=" + category + "]";
    }


}

so tried taking the category and got it working so far like this:

<table  class="table table-striped">


            <tr th:each ="category : ${categorys}">
                <td th:text="${category.id}" ></td>
                <td th:text="${category.items}" ></td>
                 //shows the size of the array 
                <td th:text="${category.items.size()}" ></td>               
            </tr>

            <!-- this is what I want as the result, I would like to know how to loop with the TH attribute 
            <tr>

                <td th:text="${category.items[0].title}"></td>
                <td th:text="${category.items[0].category.type}"></td>
                <td th:text="${category.items[0].description}"></td>
                <td th:text="${category.items[0].status}"></td>
                <td th:text="${category.items[0].zipcode}"></td>
                <td th:text="${category.items[0].price}"></td>
            </tr>
             -->

This is my first web app using Spring mvc, at this point I am a bit stuck and would appreciate it if someone pointed me towards the right path thank you :D

2 Answers 2

2

To achieve a nested loop in Thymeleaf, simply do the following:

<th:block th:each="category : ${categorys}">    
    <tr th:each="item : ${category.items}">
        <td th:text="${category.item.title}"></td>
        <td th:text="${category.item.category.type}"></td>
        <td th:text="${category.item.description}"></td>
        <td th:text="${category.item.status}"></td>
        <td th:text="${category.item.zipcode}"></td>
        <td th:text="${category.item.price}"></td>            
    </tr>
</th:block>  
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the quick response, I tried your suggestion but during run time there is an error There was an unexpected error (type=Internal Server Error, status=500). Exception evaluating SpringEL expression: "category.items.price" (/item-by-category:19)
in the console I get ` : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "category.items.title" (/item-by-category:19)] with root cause org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'title' cannot be found on object of type 'org.hibernate.collection.internal.PersistentBag' - maybe not public?`
I think you made a typo. It is supposed to be category.item.price, not category.items.price.
1

I was able to achieve the result asked without the nested loops. by changing the parameter type to Category which is the attribute type in the entity class.

Repository:

List<Item> findByCategory(Category categoryid); 

Controller :

    @RequestMapping(value="/item-by-category/{id}",method= RequestMethod.GET)
public String itemByCategory(@PathVariable("id") Category categoryid, Model model){
    model.addAttribute("items",irepository.findByCategory(categoryid));
    return "/itemlist";     
}

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.