

こちらのページを参考にformの表示、データベースの保存を試しています  
<https://qiita.com/nokiyo8774/items/214aa24d60764f0f55f6>  
<https://github.com/nokiyo8774/springboot-dev-docker-template>

formを作成してDBに保存するまでは問題がなく動作しました。  
そのコードを元にitemというテーブルを作るDBに作成して、view,controller,repositoryを作成したのですが、フォームの表示でエラーになってしまいます。  
thymeleaf において「nameがない」となってしまいます

[code]

    Whitelabel Error Page
    This application has no explicit mapping for /error, so you are seeing this as a fallback.
    
    Tue Jun 28 16:29:04 JST 2022
    There was an unexpected error (type=Internal Server Error, status=500).
    An error happened during template parsing (template: "class path resource [templates/root/item/create.html]")
    org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/root/item/create.html]")
        at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241)
        at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
        at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
        at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
        at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362)
        at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189)
        at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1373)
        at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1118)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.base/java.lang.Thread.run(Thread.java:829)
    Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "root/item/create" - line 74, col 10)
        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)
        ... 48 more
    Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "root/item/create" - line 74, col 10)
        at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117)
        at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
        at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
        at org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918)
        at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleStandaloneElementEnd(TemplateHandlerAdapterMarkupHandler.java:260)
        at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:256)
        at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleStandaloneElementEnd(OutputExpressionInlinePreProcessorHandler.java:169)
        at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:104)
        at org.attoparser.HtmlVoidElement.handleOpenElementEnd(HtmlVoidElement.java:92)
        at org.attoparser.HtmlMarkupHandler.handleOpenElementEnd(HtmlMarkupHandler.java:297)
        at org.attoparser.MarkupEventProcessorHandler.handleOpenElementEnd(MarkupEventProcessorHandler.java:402)
        at org.attoparser.ParsingElementMarkupUtil.parseOpenElement(ParsingElementMarkupUtil.java:159)
        at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:710)
        at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)
        ... 50 more
    Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'itemForm' available as request attribute
        at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153)
        at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903)
        at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227)
        at org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:306)
        at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:253)
        at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:227)
        at org.thymeleaf.spring5.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:174)
        at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
        ... 63 more
    
[/code]

不思議な現象として、このエラーが発生すると、それまで問題なかったformの表示までエラーが発生するようになりdockerをdownして再度upするまで継続してしまいます。

２つの問題「item form エラーの原因」「一度エラーになると他のformもエラーになる」が起きています。  
この原因が究明できずにいます。理由あるいは解決のためのヒントになりそうなことがありましたら、教えてください。

よろしくお願いします。

※form表示ができない状態なのでpost時のRepositoryは動作（DB操作）していない状態ですが、添付いたします

**コントローラー（一部）**

[code]

    import com.example.demo.models.InquiryForm;
    import com.example.demo.models.Item;
    import com.example.demo.repositries.InquiryRepository;
    import com.example.demo.repositries.ItemRepository;
    
    @Controller
    @RequestMapping("/")
    public class RootController {
    
        @Autowired
        InquiryRepository repository;
        @Autowired
        ItemRepository itemRepository;
    
    /***** 略 *****/
    /***** ↓追記↓ *****/
    
        @GetMapping("/form")
        public String form(InquiryForm inquiryForm) {
            return "root/form";
        }
    
    /***** 略 *****/
    
        @GetMapping("/item/create")
        public String itemCreate(Item itemForm) {
            return "root/item/create";
        }
    
        @PostMapping("/item/create")
        public String itemCreate(@Validated Item itemForm, BindingResult bindingResult, Model model) {
            if (bindingResult.hasErrors()) {
                return "root/item/create";
            }
    
            // RDBと連携できることを確認しておきます。
            itemRepository.saveAndFlush(itemForm);
            itemForm.clear();
            model.addAttribute("message", "アイテムを登録しました。");
            return "root/item/create";
        }
    
[/code]

**form html**

[code]

    <!doctype html>
    <html xmlns:th="http://www.thymeleaf.org" lang="ja">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>ポートフォリオサイト</title>
    <link rel="stylesheet" media="all" th:href="@{/css/ress.min.css}" />
    <link rel="stylesheet" media="all" th:href="@{/css/style.css}" />
    <script th:src="@{/js/jquery-2.1.4.min.js}"></script>
    <script th:src="@{/js/style.js}"></script>
    
    <!-- Favicon -->
    <link rel="icon" type="image/png" th:href="@{/img/favicon.png}">
    
    </head>
    <body>
        <header>
            <div class="container">
                <div class="row">
                    <div class="col span-12">
                        <div class="head">
                            <h1>
                                <a th:href="@{/}">PORTFOLIO</a>
                            </h1>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col span-12">
                        <nav>
                            <div id="open">
                                <img th:src="@{/img/button.png}">
                            </div>
                            <div id="close">
                                <img th:src="@{/img/button2.png}">
                            </div>
                            <div id="navi">
                                <ul>
                                    <li><a th:href="@{/}">ホーム</a></li>
                                    <li><a th:href="@{/form}">お問い合わせ</a></li>
                                    <li><a th:href="@{/form2}">お問い合わせ2</a></li>
                                    <li><a th:href="@{/item/create}">アイテム追加</a></li>
                                </ul>
                            </div>
                        </nav>
                    </div>
                </div>
            </div>
        </header>
        <div class="mainimg">
            <img th:src="@{/img/subimg.jpg}" alt="お問い合わせ画像">
        </div>
        <main>
            <article>
                <div class="container">
                    <div class="row">
                        <div class="col span-12">
                            <div class="breadcrumb">
                                <ul>
                                    <li><a th:href="@{/demo}">ホーム</a> > アイテム登録</li>
                                </ul>
                            </div>
    
                            <th:block th:if="message != null">
                                <h2 th:class="msg" th:text="${message}"></h2>
                            </th:block>
    
                            <h2 class="underline">フォーム</h2>
                            <form th:action="@{/form}" th:object="${itemForm}"
                                method="post">
                                <p>
                                    <label for="name">お名前</label> <input class="full-width"
                                        type="text" id="name" name="name" maxlength="10"
                                        th:field="*{name}"> <span
                                        th:if="${#fields.hasErrors('name')}" th:errors="*{name}"
                                        th:class="msg"></span>
                                </p>
                                <p>
                                    <label for="email">価格</label> <input class="full-width"
                                        type="number" id="price" name="mail" th:field="*{price}"><span
                                        th:if="${#fields.hasErrors('price')}" th:errors="*{price}"
                                        th:class="msg"></span>
                                </p>
                                <p>
                                    <label for="message">商品説明</label>
                                    <textarea class="full-width" id="detail" name="detail"
                                        th:field="*{detail}"></textarea>
                                    <span th:if="${#fields.hasErrors('detail')}"
                                        th:errors="*{detail}" th:class="msg"></span>
                                </p>
                                <p>
                                    <input class="button" type="submit" value="送信">
                                </p>
                            </form>
                        </div>
                    </div>
                </div>
            </article>
        </main>
        <footer>
            <div class="container">
                <div class="row">
                    <div class="col span-12">
                        <h5>お知らせ</h5>
                        <p>電話での問合せは承っておりません。</p>
                        <p>回答にお時間頂くことがございます。予めご了承ください。</p>
                    </div>
                </div>
            </div>
        </footer>
        <p id="pagetop">
            <a href="#">TOP</a>
        </p>
    </body>
    </html>
    
[/code]

**model Item class**

[code]

    package com.example.demo.models;
    
    import javax.validation.constraints.NotBlank;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;
    
    import java.io.Serializable;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    import lombok.Data;
    
    @Data
    @Entity
    @Table(name = "item")
    public class ItemForm implements Serializable {
        private static final long serialVersionUID = -6647247658748349084L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private long id;
    
        @NotBlank
        @Size(max = 30)
        private String name;
    
        @NotNull
        private int price;
    
        @NotBlank
        @Size(max = 400)
        private String detail;
        
        public void clear() {
            name = null;
            price = 0;
            detail = null;
        }
    }
    
[/code]

**DB操作**

[code]

    package com.example.demo.repositries;
    
    import java.util.List;
    import java.util.Optional;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    import com.example.demo.models.Item;
    
    @Repository
    public interface ItemRepository extends JpaRepository<Item, String>{
        Optional<Item> findById(String id);
        List<Item> findAll();
    }
    
[/code]

**【新たなエラー】**

回答を頂いて `public String itemCreate(ItemForm itemForm, Model model) {`
とすることで正しくフォームが表示されるようになりました。

そして今度はpostするときに別のエラー発生してしまいます。  
エラーログから、前回のエラーと異なる部分だけ抜き出しました。

[code]

    Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'name' of bean class [com.example.demo.models.ItemForm]: Bean property 'name' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?   Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'itemForm' available as request attribute
    at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:622)   
    at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:612)   at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153)
    at org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:104) 
    at org.springframework.validation.AbstractBindingResult.getRawFieldValue(AbstractBindingResult.java:284)
    
[/code]

getter,setterに問題があるようです。ただ、getter,setterはclassの `@Data` にて自動的に作るようにしてあります。

getter,setterに問題があるのならば、getでフォームを表示したときには、何故エラーにならないのかも不明です。


CC BY-SA 4.0
2022-06-28T07:44:00.177
89646
2022-07-05T12:48:49.523
2022-07-05T12:48:49.523
7980
7980
question
java spring-boot
thymeleafで値を引き継げない。一度エラーが発生すると問題のないページもエラーになる


例外スタックトレースに出力されている通り、問題が発生しているのは

> template: "root/item/create" \- line 74, col 10  
>  Neither BindingResult nor plain target object for bean name 'itemForm'
> available as request attribute

つまり、

[code]

                            <form th:action="@{/form}" th:object="${itemForm}"
                                method="post">
                                <p>
                                    <label for="name">お名前</label> <input class="full-width"
                                        type="text" id="name" name="name" maxlength="10"
                                        th:field="*{name}"> <span
                                        th:if="${#fields.hasErrors('name')}" th:errors="*{name}"
                                        th:class="msg"></span>
    
[/code]

で、 `itemForm` オブジェクトの `name` プロパティを参照しようとしているが、 `itemForm`
オブジェクトが属性として設定されていないのでエラーになっています。

次のようにセットする必要があります(同じテンプレートファイルを利用している他のハンドラも同様に対処する必要があります):

[code]

        @GetMapping("/item/create")
        public String itemCreate(Item itemForm, Model model) {
            model.addAttribute("itemForm", itemForm);
            return "root/item/create";
        }
    
[/code]


CC BY-SA 4.0
2022-06-28T16:15:47.610
89653
2022-06-28T16:15:47.610
2808
89646
answer