org.springframework.beans.NotReadablePropertyException: недопустимое свойство класса компонента. Thymeleaf + SpringBoot - PullRequest
0 голосов
/ 03 мая 2018

Сведения об ошибке

Страница работает нормально, но когда я введу неверный промежуток времени в два входа startStatusDate и endStatusDate. Произошла ошибка при проверке правильности в классе DriverHistoryValidator.

Я вижу в отладчике, что исключение генерируется после присваивания

errors.rejectValue("startStatusDate", 
"co.driverHistoryStatusPeriod.notpermitted")

в методе

validate(Object o, Errors errors)

Смотри ниже, пожалуйста

Что я делаю не так?

2018-05-03 11:03:54.364 ERROR 6234 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.beans.NotReadablePropertyException: Invalid property 'startStatusDate' of bean class [kg.nurtelecom.dictionaries.entity.carordering.Driver]: Bean property 'startStatusDate' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?] with root cause

org.springframework.beans.NotReadablePropertyException: Invalid property 'startStatusDate' of bean class [kg.nurtelecom.dictionaries.entity.carordering.Driver]: Bean property 'startStatusDate' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

Передняя часть

В Thymeleaf реализован интерфейс:

<form id="statusSheduleForm" class="form-horizontal" th:action="@{/driver/saveStatusSchedule}"
                  th:method="POST"
                  th:object="${driverHistory}">
                <div class="form-group col-md-7">
                    <div class="input-group date">
                        <label class="validation-message" for="statusdatetimepicker1"
                               th:if="${#fields.hasErrors('startStatusDate')}"
                               th:errors="*{startStatusDate}"></label>
                        <input type="text" placeholder="Время начала" th:field="*{startStatusDate}"
                               id="statusdatetimepicker1"/>
                        <input type="text" placeholder="Время окончания" th:field="*{endStatusDate}"
                               id="statusdatetimepicker2"/>
                        <select id="status-select" required="required" th:field="*{driverStatus}">
                            <option th:each="item:${statuses}"
                                    th:value="${item.id}"
                                    th:text="${item.name}"></option>
                        </select>
                    </div>
                </div>

                <div class="form-group">
                    <button type="submit" class="btn btn-primary">Сохранить</button>
                    <a th:href="@{/driver/index}" class="btn btn-default">Закрыть</a>
                </div>

            </form>

BackEnd:

Контроллер

@RequestMapping(value = "/saveStatusSchedule", method = RequestMethod.POST)
    public ModelAndView saveStatusSchedule(@ModelAttribute DriverHistory driverHistory, Driver driver,
                                           BindingResult bindingResult) {
        ModelAndView modelAndView = getModelsViews();
        Driver sessionDriver = (Driver) modelAndView.getModel().get("driver");
        if (sessionDriver != null) {
            sessionDriver.setMenu1Act();
            driverHistory.setDriver(sessionDriver);
            driverHistoryValidator.validate(driverHistory, bindingResult);
            if (bindingResult.hasErrors()) {
                return getModelsViews();
            }
            if (driverHistory.getDriverShift() != null) {
                sessionDriver.setMenu2Act();
            }
            driverHistory.setDriver(sessionDriver);
            driverHistoryService.save(driverHistory);
            return getModelsViews();
        } else {
            driver.setMenu0Act();
            modelAndView.addObject("failMessage", "Водитель не создан");
            modelAndView.addObject("driver", driver);
            return modelAndView;
        }
    }

Validator:

@Component
public class DriverHistoryValidator implements Validator {

    @Autowired
    DriverHistoryService driverHistoryService;

    @Override
    public boolean supports(Class<?> aClass) {
        return DriverHistory.class.equals(aClass);
    }

    @Override
    public void validate(Object o, Errors errors) {
        DriverHistory driverHistory = (DriverHistory) o;
        if (driverHistoryService.isExistDriverStatusInPeriodOf(driverHistory)) {
            errors.rejectValue("startStatusDate", "co.driverHistoryStatusPeriod.notpermitted");
        }
    }
}

Организация:

@Entity
@Table(name = "CO_DRIVER_HISTORY")
public class DriverHistory extends BaseEntity {

    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm")
    @Column(name = "startStatusDate")
    private Date startStatusDate;

    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm")
    @Column(name = "endStatusDate")
    private Date endStatusDate;

    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm")
    @Column(name = "startShiftDate")
    private Date startShiftDate;

    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm")
    @Column(name = "endShiftDate")
    private Date endShiftDate;

    @ManyToOne
    @JoinColumn(name = "DriverId")
    private Driver driver;

    @ManyToOne
    @JoinColumn(name = "DriverStatusId")
    private DriverStatus driverStatus;

    @ManyToOne
    @JoinColumn(name = "DriverShiftId")
    private DriverShift driverShift;

    public DriverHistory() {
    }

    public Date getStartStatusDate() {
        return startStatusDate;
    }

    public void setStartStatusDate(Date startStatusDate) {
        this.startStatusDate = startStatusDate;
    }

    public Date getEndStatusDate() {
        return endStatusDate;
    }

    public void setEndStatusDate(Date endStatusDate) {
        this.endStatusDate = endStatusDate;
    }

    public Date getStartShiftDate() {
        return startShiftDate;
    }

    public void setStartShiftDate(Date startShiftDate) {
        this.startShiftDate = startShiftDate;
    }

    public Date getEndShiftDate() {
        return endShiftDate;
    }

    public void setEndShiftDate(Date endShiftDate) {
        this.endShiftDate = endShiftDate;
    }

    public Driver getDriver() {
        return driver;
    }

    public void setDriver(Driver driver) {
        this.driver = driver;
    }

    public DriverStatus getDriverStatus() {
        return driverStatus;
    }

    public void setDriverStatus(DriverStatus driverStatus) {
        this.driverStatus = driverStatus;
    }

    public DriverShift getDriverShift() {
        return driverShift;
    }

    public void setDriverShift(DriverShift driverShift) {
        this.driverShift = driverShift;
    }

}

1 Ответ

0 голосов
/ 04 мая 2018

Я выяснил причину проблемы. Позвольте мне ответить на вопрос.

В моем случае org.springframework.beans.NotReadablePropertyException, сгенерированное, поскольку свойство startStatusDate в действительности не существует в классе [kg.nurtelecom.dictionaries.entity.carordering.Driver]. Позвольте мне объяснить, почему это произошло. Дело в том, что параметры метода Контроллера, упомянутые ниже, имеют неправильную последовательность.

@RequestMapping(value = "/saveStatusSchedule", method = RequestMethod.POST)
    public ModelAndView saveStatusSchedule(@ModelAttribute 
                                                   DriverHistory driverHistory, 
                                                   Driver driver,
                                                   BindingResult bindingResult)

BindingResult объект, объявленный в параметре, получает предыдущий объявленный параметр как целевой объект . См. Отладку на снимке экрана . В моем валидаторе class DriverHistoryValidator я установил значение ошибки в поле класса, который не является целевым объектом. Проблема исправлена ​​после того, как я просто изменил порядок параметров в методе выше, как:

@RequestMapping(value = "/saveStatusSchedule", method = RequestMethod.POST)
public ModelAndView saveStatusSchedule(DriverHistory driverHistory,
                                       BindingResult bindingResult,
                                       Driver driver)

После изменения порядка параметра класс DriverHistory получается как целевой объект в BindinResult объекте, и проверка правильности работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...