Как передать значение из выпадающего списка - PullRequest
0 голосов
/ 08 апреля 2019

Я работаю с проектом Spring MVC + Thymeleaf, и у меня проблема с передачей значения поля объекту. Существуют сущности malt и country. В форме malt есть раскрывающийся список, который заполняется из БД - только названия стран - ничего необычного. Я могу заполнить список, но когда я нажимаю кнопку «отправить», появляются некоторые ошибки. Код ниже (только соответствующие части):

Солодовая сущность:

@Setter
@Getter
@NoArgsConstructor
@Entity
@ToString
@Table(name="malt")
public class Malt extends BaseEntity {

    @Column(name="malt_name")
    private String maltName;

    @ManyToOne(fetch=FetchType.EAGER,
            cascade= {CascadeType.PERSIST, CascadeType.MERGE,
                    CascadeType.DETACH, CascadeType.REFRESH})
    @JoinColumn(name="producer_id")
    private Producer producer;

    @Column(name="malt_filling")
    private int maltFilling;

    @Column(name="malt_ebc")
    private int maltEbc;

    @Column(name="malt_usage")
    private String maltUsage;

    @ManyToOne(fetch=FetchType.EAGER,
            cascade= {CascadeType.PERSIST, CascadeType.MERGE,
                    CascadeType.DETACH, CascadeType.REFRESH})
    @JoinColumn(name="country_id")
    private Country country;

    @ManyToMany(mappedBy="malts")
    private Set<Batch> batches;

Контроллер солода:

@Controller
@RequestMapping("/malt")
public class MaltController {

@ModelAttribute("countries")
public Collection<Country> populateCountries() {
    return countryService.findAll();
}

@RequestMapping("{id}/update")
public String updateMalt(@PathVariable String id, Model model) {
    model.addAttribute("malt", maltService.findById(Long.valueOf(id)));
    return "malt-form";
}

@PostMapping
public String saveOrUpdate(@ModelAttribute Malt malt) {
    Malt savedMalt = maltService.save(malt);
    return "redirect:/malt/" + savedMalt.getId() + "/malt-show";
}

Форма солода:

<div class="form-field-input">
    <select class="form-control" th:field="*{id}">
        <option value="0">Select country</option>
        <option
            th:each="country : ${countries}"
            th:value="${country.id}"
            th:text="${country?.countryName}">
        </option>
    </select>
</div>
<div class="form-field-submit">
    <button class="submit-button" type="submit">Submit</button>
</div>

Шаблон солода:

<div class="wrapper">
            <div class="main">
                <div class="page-title">
                    <p th:text="${malt.maltName}">Malt name</p>
                </div>
                <div class="show">
                    <div class="form-row">
                        <div class="form-field-name">
                            <label>Producer:</label>
                        </div>
                        <div class="form-field-input">
                            <p th:text="${malt.producer.producerName}">Producer name</p>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-field-name">
                            <label>Country:</label>
                        </div>
                        <div class="form-field-input">
                            <p th:text="${malt.country.countryName}">Country</p>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-field-name">
                            <label>Malt filling:</label>
                        </div>
                        <div class="form-field-input">
                            <p th:text="${malt.maltFilling}">Malt filling</p>                       
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-field-name">
                            <label>Malt usage:</label>
                        </div>
                        <div class="form-field-input">
                            <p th:text="${malt.maltUsage}">Malt usage</p>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-field-name">
                            <label>Malt EBC:</label>
                        </div>
                        <div class="form-field-input">
                            <p th:text="${malt.maltEbc}">Malt EBC</p>
                        </div>
                    </div>

                </div>
            </div>
        </div>

Завершить полученную ошибку:

An error happened during template parsing (template: "class path resource [templates/malt-show.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/malt-show.html]")
.
.
.
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "malt.country.countryName" (template: "malt-show" - line 44, col 11)
    at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
    at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
    at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
    ... 52 more
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "malt.country.countryName" (template: "malt-show" - line 44, col 11)
    at org.thymeleaf.spring5.expression.SPELVariableExpressionEvaluator.evaluate(SPELVariableExpressionEvaluator.java:290)
.
.
.
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'countryName' cannot be found on null    

Ссылка на репо: https://github.com/fangirsan/maruszka-new/tree/malt-form-problem

Я пробовал много разных подходов, но безрезультатно.

1 Ответ

1 голос
/ 09 апреля 2019

Как уже говорилось в исключении, проблема ${malt.country.countryName} в вашей malt-show форме. В последней строке трассировки стека исключений я вижу Property or field 'countryName' cannot be found on null. Это означает, что вы пытаетесь получить свойство связанной модели, равное нулю . Возможно, столбец country_id в вашей таблице malt равен нулю. Другими словами, country_id не сохраняется с другими полями. С этими допущениями вы найдете проблему в форме malt-form, где вы сохраняете солод. Я проверил эту форму, вероятно, проблема <select class="form-control" th:field="*{id}">. Я думаю, что это должно быть изменено на <select class="form-control" th:field="*{country.id}">.

Важное примечание:

Некоторые из связанных моделей могут быть нулевыми, например, предположим, что country в вашей malt модели может быть нулевым (это зависит от бизнес-логики приложения). В случае обнуляемых отношений доступ к полям отношения модели в шаблоне ${model.relation.field} может привести к ошибке выше. Так что в этих случаях вы должны использовать проверка нуля внутри вашего шаблона с тимьяном.

...