Проблема с передачей измененного подобъекта в приложении SPRING через шаблон Thymeleaf - PullRequest
0 голосов
/ 20 октября 2018

Я новичок в SPING и веб-разработке.

Разрабатываю тестовое задание - цитата (без авторизации).У меня есть две сущности: Цитата и Автор.Есть код:

@Entity
@Table(name="authors")
public class Author {
    @Id
    @SequenceGenerator(name="author_id_seq", sequenceName="author_id_seq", allocationSize=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "author_id_seq")
    @Column(name = "id")
    private long id;

    @Column(name = "nick_name")
    private String nickName;

    public Author() {
    }

    public Author(long id, String nickName) {
        this.id = id;
        nickName = nickName;
    }
/*
Getters and Setters
*/
}

Цитата:

@Entity
@Table(name = "quotes")
public class Quote {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "quotes_id_seq")
    @SequenceGenerator(name="quotes_id_seq", sequenceName="quotes_id_seq", allocationSize=1)
    @Column(name = "id")
    private long id;
    @Column(name = "content")
    private String content;
   // @Temporal(TemporalType.DATE)
    @Column(name = "date")
    private LocalDate date;
    @ManyToOne
    @JoinColumn(name = "author")
    private Author author;

    public Quote() {
    }

    public Quote(long id, String content, LocalDate date, Author author) {
        this.id = id;
        this.content = content;
        this.date = date;
        this.author = author;
    }
/*
Getters and Setters
*/
}

Шаблон My Thymeleaf содержит форму с двумя полями ввода (для quote.content и quote.author.nickName) и выберите с помощьюсуществующие авторы.Я хочу увидеть поведение, когда я заполняю ввод для автора, содержимого, и если автора нет в таблице авторов, мое приложение добавляет строку в этой таблице с указанным значением из входного nickName и сгенерированного идентификатора.Но проблема заключается в в получении неожиданного для меня результата из шаблона Thymeleaf.Шаблон передается контроллеру Объект Quote с автором, у которого псевдоним пустое вместо значения из моего ввода. Есть код шаблона тимелина моей формы:

 <form action="#" th:action="@{/newQuote}" th:object="${quote}" method="post">
                <div class="form-row">
                    <div class="form-group col-md-3">
                        <label class="sr-only" for="inputNick">Nick Name</label>
                        <!--/*@thymesVar id="author" type="hello.entity.Author"*/-->
                        <input type="text" class="form-control" id="inputNick" th:field="*{author.nickName}"
                               placeholder="enter Nick Name">
                    </div>
                    <div class="form-group col-md-6">
                        <select id="nickNames">
                            <th:block th:each="author : ${allAuthors}">
                                <option th:text="${author.nickName}">Nick Name</option>
                            </th:block>
                        </select>
                    </div>
                    <div class="form-group col-md-12">
                        <label for="postContent">Your Quote:</label>
                        <input type="text" class="form-control" id="postContent" th:field="*{content}"
                               placeholder="quote text">
                    </div>
                </div>

                    <div class="form-group col-md-2">
                        <input type="submit" value="Add Quote"/>
                    </div>
                    <div class="form-group col-md-2">
                        <input type="reset" value="Reset"/>
                    </div>

            </form>

Методы контроллера:

@GetMapping("/newQuote")
    public String showAuthors(Model model){
        model.addAttribute("allAuthors",authorService.findAll());
        model.addAttribute("quote", new Quote());
        return "newQuote";
    }

    @PostMapping("/newQuote")
    public String addQuote (@ModelAttribute Quote quote) {
        quote.setDate(LocalDate.now());
        quoteRepository.save(quote);
        return "redirect:/";

Я пытался:

  1. добавить объект Author в GetMapping, передать его в шаблон newQuote, перейти от него к PostMapping - безрезультатно.Null в никнейме
  2. для создания и вставки объекта автора в объект цитаты, перехода к шаблону, перехода к постмаппингу.без эффекта

Я знаю, что могу создать класс DTO с псевдонимом поля вместо поля автора и преобразовать его в мой класс сущности в методе postmapping контроллера.Но я думаю, что это «плохая практика».Я думаю, что я сделал неправильные шаги, может быть, когда попытался изменить объект автора и передать его из тимелина в контроллер.А также я полагаю, что в этой ситуации нет способа реализовать эту логику.Я не знаю, где правда.Пожалуйста, помогите мне найти его.

PS: извините за мой плохой английский

1 Ответ

0 голосов
/ 20 октября 2018

Итак, ответ спрашивает, как добавить цитату и ее автора одновременно.При избранном подходе это невозможно, поскольку нашего автора не существует.И простой способ добиться этого - изменить сущность цитаты и добавить @Cascade(CascadeType.PERSIST) в поле автора в цитате.Это автоматически сохранит автора с вашей цитатой.

Это будут изменения в вашем коде, которые вам потребуются для этого.

Обновление

Поскольку последнее решение не работало, мы попытаемся отправить дополнительный параметр нашему контроллеру, чтобы избежать получения нулевого значения вместо псевдонима автора.

Контроллер

@PostMapping("/newQuote")
public String addQuote (@ModelAttribute Quote quote,
                        @RequestParam("nickName") String nickName) {
    // This will automatically persist your quote and it's author.
    quote.setDate(LocalDate.now());
    Author author = new Author();
    author.setNickName(nickName);
    quoteRepository.save(quote);
}

ЦитатаСущность

@Entity
@Table(name = "quotes")
public class Quote {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "quotes_id_seq")
    @SequenceGenerator(name="quotes_id_seq", sequenceName="quotes_id_seq", allocationSize=1)
    @Column(name = "id")
    private long id;

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

    @Column(name = "date")
    private LocalDate date;

    @ManyToOne
    @Cascade(CascadeType.PERSIST)
    @JoinColumn(name = "author")
    private Author author;

    // Getters and Setters
}

Важно , обратите внимание, что мы добавляем новую аннотацию @Cascade(CascadeType.PERSIST) в поле нашего автора.

HTML

Здесь мы просто удалим ненужный выбор.

<form action="#" th:action="@{/newQuote}" th:object="${quote}" method="post">
    <div class="form-row">
        <div class="form-group col-md-3">
            <label class="sr-only" for="inputNick">Nick Name</label>
            <!--/*@thymesVar id="author" type="hello.entity.Author"*/-->
            <input type="text" name="nickName" class="form-control" id="inputNick" placeholder="enter Nick Name"/>
        </div>
        <div class="form-group col-md-12">
            <label for="postContent">Your Quote:</label>
            <input type="text" class="form-control" id="postContent" th:field="*{content}" placeholder="quote text"/>
        </div>
   </div>
   <div class="form-group col-md-2">
       <input type="submit" value="Add Quote"/>
   </div>
   <div class="form-group col-md-2">
      <input type="reset" value="Reset"/>
   </div>
</form>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...