🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

982閲覧

結合したカラムのバリデーションチェック

KeitaUenishi

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2020/12/12 04:41

編集2020/12/13 03:17

前提・実現したいこと

現在個人で各エンタメや劇場などにおける集客管理ツールのようなものを作成しています。
現在2つのテーブルにある
・公演日(live_list)親テーブルの日付情報 dateId(Prymary Key)
・顧客リスト(customer_list)子テーブルの日付情報 dateId
を結合し、それぞれのテーブルごとにCRUD処理を実装しています。

機能としては
公演日を登録 → その公演日の顧客リストを登録 というアプリケーションになります

実際の処理として顧客リストの新規登録をする際には、公演日の日付と同一のdateIdでしか登録できないようにcontroller側から公演日のdateIdを渡し、それをhiddenで編集できないようにしています。
そのバリデーションチェックがうまくいきません。

発生している問題・エラーメッセージ

各所省略しています

org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates//customer/customerNew.html]") at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE] at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE] …… 2020-12-12 12:50:45.889 ERROR 20136 --- [nio-8080-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates//customer/customerNew.html]")] with root cause java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'liveList' available as request attribute ......

該当のソースコード

LiveList.java

java

1package product.domain; 2 3import java.util.List; 4 5import javax.validation.constraints.Digits; 6import javax.validation.constraints.NotBlank; 7import javax.validation.constraints.NotNull; 8import javax.validation.constraints.Size; 9 10import lombok.Data; 11 12@Data 13public class LiveList { 14 15 /** 日付ID */ 16 @NotNull 17 @Digits(integer = 8, fraction = 0) 18 private Long dateId; 19 20 /** 会場 */ 21 @NotBlank 22 @Size(max = 32, message = "{error.maxsize}") 23 private String place; 24 25 /** 備考 */ 26 private String remarks; 27 28 /** 子クラス(来場客リスト)の要素定義 */ 29 private List<CustomerList> customers; 30 31} 32 33

CustomerList.java

java

1package product.domain; 2 3import javax.validation.constraints.Digits; 4import javax.validation.constraints.NotBlank; 5import javax.validation.constraints.NotNull; 6import javax.validation.constraints.Size; 7 8import lombok.Data; 9 10@Data 11public class CustomerList { 12 13 /** ID */ 14 private Long id; 15 16 /** 日付ID */ 17 @NotNull 18 @Digits(integer = 8, fraction = 0) 19 private Long dateId; 20 21 /** 名前 */ 22 @NotBlank 23 @Size(min = 1, max = 50) 24 private String name; 25 26 /** 枚数 */ 27 @NotNull 28 private int number; 29 30 /** 備考 */ 31 private String comment; 32 33}

customerNew.html 

html

1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org"> 3<head> 4<meta charset="utf-8" /> 5<title>新規登録ページ</title> 6<link rel="stylesheet" href="/css/bootstrap.css" /> 7<script src="/js/jquery.js"></script> 8<script src="/js/bootstrap.js"></script> 9</head> 10<body> 11 <div class="container"> 12 <h1>取り置きを新規登録</h1> 13 14 <form th:action="@{/customer}" th:method="post" th:object="${customerList}"> 15 <p th:object="${liveList}"> 16 <div class="form-group"> 17 <input class="form-control" 18 type="hidden" name="id"> 19 <input class="form-control" 20 type="hidden" name="dateId" th:object="${liveList}" th:field="${liveList.dateId}" /> 21 </div> 22 <p/> 23 <div class="form-group"> 24 <label class="control-label">名前</label> <input class="form-control" 25 type="text" name="name" /> 26 <span class="text-danger" th:if="${#fields.hasErrors('name')}" th:errors="*{customerList.name}"></span> 27 </div> 28 <div class="form-group"> 29 <label class="control-label">枚数</label> <input class="form-control" 30 type="number" name="number" /> 31 <span class="text-danger" th:if="${#fields.hasErrors('number')}" th:errors="*{customerList.number}"></span> 32 </div> 33 <div class="form-group"> 34 <label class="control-label">メモ</label> <input class="form-control" 35 type="text" name="comment" /> 36 </div> 37 <button class="btn btn-Primary" type="submit">登録</button> 38 </form> 39 <div class="pull-right"> 40 <a class="btn btn-link" href="/liveList">一覧画面へ</a> 41 </div> 42 </div> 43</body> 44</html>

試したこと

Controllerから受け渡す値の確認
BindingResultの位置確認(@validのあとにする)
view側でのth:objectで受け取る値の変更、追加
エラー文にある「Neither BindingResult nor plain target object for bean name 'liveList' available as request attribute」にあるように、画面から送る値か受け取っている値に何らかの問題があるとみているのですがどう問題があるかがわからない状態です。

初学者のため初歩の質問かもしれませんが、何卒ご教授いただけると幸いです。

新規登録で各項目を空白にした場合のデバッグ画面
イメージ説明

補足情報(FW/ツールのバージョンなど)

OS Windows10
IDE Eclipse Version: 2020-06 (4.16.0)
java 11
Spring Boot 2.4.0

GitHub

###追記

customerNew.html(変更後)

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8" /> <title>新規登録ページ</title> <link rel="stylesheet" href="/css/bootstrap.css" /> <script src="/js/jquery.js"></script> <script src="/js/bootstrap.js"></script> </head> <body> <div class="container"> <h1>取り置きを新規登録</h1> <form th:action="@{/customer}" th:method="post" th:object="${customerList}"> <div class="form-group"> <input class="form-control" type="hidden" name="id"> <input class="form-control" type="hidden" name="dateId" th:field="${customerList.dateId}" /> </div> <div class="form-group"> <label class="control-label">名前</label> <input class="form-control" type="text" name="name" /> <span class="text-danger" th:if="${#fields.hasErrors('name')}" th:errors="*{customerList.name}"></span> </div> <div class="form-group"> <label class="control-label">枚数</label> <input class="form-control" type="number" name="number" /> <span class="text-danger" th:if="${#fields.hasErrors('number')}" th:errors="*{customerList.number}"></span> </div> <div class="form-group"> <label class="control-label">メモ</label> <input class="form-control" type="text" name="comment" /> </div> <button class="btn btn-Primary" type="submit" >登録</button> <!-- th:href="@{/customer/customerNew/{dateId}(dateId=*{dateId})}" --> </form> <div class="pull-right"> <a class="btn btn-link" href="/liveList">一覧画面へ</a> </div> </div> </body> </html>

CustomerListController.java(変更箇所コメントアウト)

package product.controller; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import product.domain.CustomerList; import product.service.CustomerListService; import product.service.LiveListService; /** * お客さんのリストを操作するコントローラー * @author keita * */ @Controller @RequestMapping("customer") public class CustomerListController { @Autowired private CustomerListService customerListService; @Autowired private LiveListService liveListService; // お客さん情報新規作成画面の表示 @GetMapping("/customerNew/{dateId}") public String newCustomerList(@PathVariable("dateId") Long dateId, @ModelAttribute CustomerList customerList, Model model) { //LiveList liveList = liveListService.findOne(dateId); //model.addAttribute("liveList", liveList); model.addAttribute("customerList", customerList); return "customer/customerNew"; } // お客さん情報編集画面の表示 @GetMapping("{id}/edit") public String edit(@PathVariable Long id, Model model) { CustomerList customerList = customerListService.findOne(id); model.addAttribute("customerList", customerList); return "customer/customerEdit"; } // customerデータの保存 @PostMapping public String customerCreate( @Valid @ModelAttribute CustomerList customerList, BindingResult result, Model model) { if (result.hasErrors()) { return "/customer/customerNew"; } customerListService.insert(customerList); return "redirect:/liveList"; } // お客さんデータの更新 @GetMapping("/update/{id}") @Transactional(readOnly = false) public String update(@PathVariable Long id, @Valid @ModelAttribute CustomerList customerList, BindingResult result) { if (result.hasErrors()) { return "/customer/customerEdit"; } customerList.setId(id); customerListService.update(customerList); return "redirect:/liveList"; } // お客さんデータの削除 @PostMapping("/{id}") public String delete(@PathVariable Long id) { customerListService.delete(id); return "redirect:/liveList"; } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/12/12 09:06

提示されたHTMLはtemplates//customer/customerNew.html でいいんですよね? (でもパスに//2つ入ってるのは本当に?という気はしますが)
m.ts10806

2020/12/12 09:13

LiveList 、CustomerList の定義もご提示ください。
m.ts10806

2020/12/12 09:14

エラー的には java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'liveList' available as request attribute liveListの属性が取れてないってことのように見えます。デバッグとしては「viewに渡そうとしているオブジェクトの中身」のチェックですね。
KeitaUenishi

2020/12/13 01:40 編集

ありがとうございます! 追記させていただきました。 ・htmlに関してはcustomer/customerNew.htmlで間違いないです よろしければパスに//2つ入っている部分がどちらでわかるか教えていただけますか? 自分ではどこに当たるのかわかりませんでした…  重ねて質問申し訳ありません。 ・通常で新規登録した場合は値が正常に取れているのは確認できているのですが、Viewに渡そうとしているオブジェクトとなるとnewCustomerListメソッドの値の見直しですかね… 現状は、エラーを拾った場合の遷移先に問題がある? という仮説でcustomerCreateメソッドにdateIdの値を渡してみる、などを試しており、受け取れてないエラーが出ていました。
KeitaUenishi

2020/12/13 03:10

Viewに渡そうとしているオブジェクトの中身を確認したところ、customerListにdateIdの値がすでに入っていることが確認できました。そのため画面に渡すliveListを削除し、customerListのみにすることで上記のエラーに関しては表示されなくなりました。ありがとうございます! 現在、次の問題として新規登録を空欄で行おうとした際に 「Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'customerList' of bean class [product.domain.CustomerList]: Bean property 'customerList' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?」 とエラーが出ております。 試したこと ・lombokを削除し、CustomerListクラスにgetter,setterを記述する。 ・gradleプロジェクトのリフレッシュ 等を試しております。 現状変更したControllerとviewを追記しておきます。 もし何かお気づきの点等ございましたら助言頂けますと幸いです。
guest

回答1

0

自己解決

コメント欄での変更内容より

<span class="text-danger" th:if="${#fields.hasErrors('name')}" th:errors="*{customerList.name}"></span> <span class="text-danger" th:if="${#fields.hasErrors('number')}" th:errors="*{customerList.number}"></span>

こちらのふたつのエラー表示部分を

<span class="text-danger" th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span> <span class="text-danger" th:if="${#fields.hasErrors('number')}" th:errors="*{number}"></span>

と修正することでバリデーションメッセージが表示されました!
色々なところがごちゃごちゃとしてしまっていたので、アドバイスいただいた件から掘り下げていくとしっかり解決に近づいていけました!ありがとうございました!

投稿2020/12/13 03:37

KeitaUenishi

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問