org.springframework.beans.NotReadablePropertyException:-下拉表单

时间:2018-11-09 16:06:51

标签: java spring thymeleaf

我已经查看了与此错误相关的其他线程,但无法弄清楚为什么我仍然遇到此问题。我相信问题出在我的HTML模板上。我正在尝试创建一个简单的下拉框,以选择要删除的“锻炼”列表。

HTML表单:

    <form action="#" th:action="@{/workout/deleteWorkout}" th:object="${workout}" method="post">
        <select th:field="*{workout}" name="workout" class="selectForm">
            <option th:each="workout : ${workouts}"
                    th:value="${workout.workoutID}"
                    th:text="${workout.workoutName}">
            </option>
        </select>
        <input type="submit" class="input-box">
    </form>

页面的控制器方法:

    @GetMapping("/workout/deleteWorkout")
public String deleteWorkoutForm(Model model,
                                HttpServletRequest request) {
    Account account = (Account) request.getSession().getAttribute("loggedInUser");
    model.addAttribute("workouts", workoutService.getWorkouts(account));
    return "deleteWorkout";
}

@PostMapping("/workout/deleteWorkout")
public String deleteWorkout(@ModelAttribute Workout workout){
    workoutService.deleteWorkout(workout);
    return "workoutDeleted";
}

错误:

org.springframework.beans.NotReadablePropertyException: Invalid property 'workout' of bean class [depaul.tables.Workout]: Bean property 'workout' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

感谢您的帮助。我特别困惑,因为在另一种方法中,我没有问题可以使用下拉框选择锻炼功能。谢谢!

编辑: 锻炼:

@Entity
 public class Workout implements Serializable, IWorkout {

public Workout(){
}

public Workout(String accountName, String workoutName, String description, String workoutDate){
    this.accountName = accountName;
    this.workoutName = workoutName;
    this.description = description;
    this.workoutDate = workoutDate;
}

private String accountName;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long workoutID;

@NotNull
private String workoutName;

private String description;

private String workoutDate;

@OneToMany(cascade = CascadeType.ALL,
        fetch = FetchType.EAGER,
        mappedBy = "workout")
@Nullable
private Collection<Exercise> exercises = new ArrayList<Exercise>();

public String getAccountName() {
    return accountName;
}

public void setAccountName(String accountName) {
    this.accountName = accountName;
}

@Override
public Long getWorkoutID() {
    return workoutID;
}

@Override
public void setWorkoutID(Long workoutID) {
    this.workoutID = workoutID;
}

@Override
public String getWorkoutName() {
    return this.workoutName;
}

@Override
public void setWorkoutName(String workoutName) {
    this.workoutName = workoutName;
}

@Override
public String getDescription() {
    return description;
}

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

@Override
public String getWorkoutDate() {
   return this.workoutDate;
}

@Override
public void setWorkoutDate(String workoutDate) {
    this.workoutDate = workoutDate;
}

@Override
public Collection<Exercise> getExercises() {
    return exercises;
}

@Override
public void setExercises(Collection<Exercise> exercises) {
    this.exercises = exercises;
}

1 个答案:

答案 0 :(得分:1)

我认为正在发生的事情是,百里香正试图将名为“锻炼”的select th:field="*{workout}" name="workout" class="selectForm">的选择绑定到不属于该类的public class Workout的属性。

由于您要设置的实际值为workoutID,因此我将其命名为字段

<select th:field="*{workoutID}" name="workout" class="selectForm">

因此,百里香将参数绑定到setWorkoutID()。而不是查找不存在的属性的setWorkout()

希望这会有所帮助!

编辑1:

由于在控制器中期望有一个@ModelAttribute称为'workout'且类型为Workout.class,因此在页面呈现时,servlet引擎正在寻找该对象以将其绑定到Request。因此,您需要将此行添加到deleteWorkoutForm()方法中:

model.addAttribute("workout", new Workout());

这将初始化对象并将其绑定到RequestContext中的模型。