Home > front end >  Thymleaf throws an exception when I add a new variable to the model class
Thymleaf throws an exception when I add a new variable to the model class

Time:07-20

I'm new to Thymleaf and Spring so I'm assuming I've made a simple mistake but I can't work it out after 2 days.

I have started a simple spring/h2/thymleaf app that was displaying the html correctly. The class initially had only 3 attributes (id, activity, description) just so I could make sure all the plumbing was correct. Now when I add a 4th attribute to the model/html I get :

2022-07-19 18:15:57.347 ERROR 22372 --- [nio-8080-exec-1] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-1] Exception processing template "TaskView": Exception evaluating SpringEL expression: "task.plan_number" (template: "TaskView" - line 73, col 9)

other messages removed

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'plan_number' cannot be found on object of type 'com.apa.app.task.Task' - maybe not public or not valid?

If I return to the original 3 attributes in the html it still works fine. Also leaving the additional attribute in the java code works fine, it is only when I add the th:utext line for the additional attribute(s) to the html that the error is generated. I have included a println in the controller code just to confirm the data is being read correctly from H2 (which it is). Any help would be greatly appreciated. Thanks

Code:

Model

@Entity
@Table(name="tasks")
public class Task {

    @Id
    @GeneratedValue
    private long id;
    private String type;            // Type of task 
    private int plan_number;        // The task number as appears in the plan view
    private String activity;        // Short description that is seen in task view
    private String description;     // Detailed free form text of steps
    private String x;
    
    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;
    }
    public long getplan_number() {
        return plan_number;
    }
    public void setplan_number(int plan_number) {
        this.plan_number = plan_number;
    }
    public String getActivity() {
        return activity;
    }
    public void setActivity(String activity) {
        this.activity = activity;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public String getx() {
        return x;
    }
    public void setx(String x) {
        this.x = x;
    }

    public Task( ) {
    }
    
    public Task(long id, String type, int plan_number, String activity, String description, String x) {
        super();
        this.id = id;
        this.type = type;
        this.plan_number = plan_number;
        this.activity = activity;
        this.description = description;
        this.x = x;
    }
    
    @Override
    public String toString() {
        return "Task [id="   id   ", type="   type   ", plan_number="   plan_number   ", activity="   activity
                  ", description="   description   ", x="   x   "]";
    }
    
}

Controller

    @Controller
public class TaskController {

    @Autowired
    private TaskService taskService;

    @GetMapping({"/TaskList"})
    public String taskview(Model model) {
        model.addAttribute("tasks", taskService.getTasks());
        return "TaskView";
    }   
    
    @PostConstruct
    private void postInit() {
        System.out.println("All data :"   taskService.getTasks());
    }
}

Snippet of html

<div th:each ="task : ${tasks}">
    <span th:switch="${task.type}">
        <p th:case = "'action'">
        <tr >
            <td class='priority'>1</td>
            <td th:utext=${task.activity}></td>
            <td th:utext=${task.description}></td>
            <td th:utext=${task.plan_number}></td>
        </tr>
        </p>

CodePudding user response:

My guess is that your getter and setter for plan_number are incorrect. Replace:

public long getplan_number() {
        return plan_number;
    }
    public void setplan_number(int plan_number) {
        this.plan_number = plan_number;
    }

with:

public long getPlan_number() {
    return plan_number;
}
public void setPlan_number(int plan_number) {
    this.plan_number = plan_number;
}

Notice the capital P after set or get.

Even better would be to follow Java naming conventions and use planNumber for the field and getPlanNumber and setPlanNumber.

  • Related