前提・実現したいこと
CRUD処理のうちの検索機能を名前の姓・または名が一致した時に検索が可能なようにしたいと考えています。
参考URLを参考にして作成を進めていたところ、名前の姓が空欄の際に検索ボタンを押すと下記のエラーが発生してしまいます。
エラーメッセージを見るに、最初の姓がnullになっているためJPQLが途中になってしまいエラーなのかなという予想なのですが、参考URLを見てもどこをどう修正していいのかわからずにいます。
ご助力いただけますと幸いです。よろしくお願いします
発生している問題・エラーメッセージ
This application has no explicit mapping for /error, so you are seeing this as a fallback. Wed Nov 18 11:52:29 GMT+09:00 2020 There was an unexpected error (type=Internal Server Error, status=500). org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: null near line 1, column 57 [SELECT u From com.example.addresslist.user.User u WHERE ]; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: null near line 1, column 57 [SELECT u From com.example.addresslist.user.User u WHERE ] org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: null near line 1, column 57 [SELECT u From com.example.addresslist.user.User u WHERE ]; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: null near line 1, column 57 [SELECT u From com.example.addresslist.user.User u WHERE ]
該当のソースコード
list.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> //省略 </head> <body> <form class="form-group" action="/search" method="post" id="search" > <a><input class="form-control border border-info" type="text" name="name" id="name" th:value="${name}" size="30" maxlength= "15" placeholder="姓" /></a> <a><input class="form-control border border-info" type="text" name="sname" id="sname" th:value="${sname}" size="30" maxlength= "15" placeholder="名"></a> <input type="submit" class="btn btn-outline-secondary" value="検索"/> </form> <div id="tablearea"> <table class="table table-hover"> <thead> <tr class="border border-info"> <th scope="col" class="col_name">名前</th> <th scope="col" class="col_sname"></th> <th scope="col" class="col_zip">郵便番号</th> <th scope="col" class="col_address">住所</th> <th scope="col" class="col_tel">電話番号</th> <th class="col_edit"></th> <th class="col_delete"></th> </tr> </thead> <tr th:each=" obj:${allLists}" th:object="${obj}"> <td th:text="*{name}"></td> <td th:text="*{sname}"></td> <td th:text="*{zip}"></td> <td th:text="*{address}"></td> <td th:text="*{tel}"></td> <td> <form th:action="@{/edit}" method="get"> <input type="submit" class="btn btn-outline-secondary btn-sm" name="edit" value="編集"> <input type="hidden" name="id" th:value="${obj.id}"> </form> </td> <td> <form th:action="@{/edit}" method="post"> <input type="submit" class="btn btn-outline-info btn-sm" name="delete" value="削除" onclick="return confirm('削除してもよろしいですか?')"> <input type="hidden" name="id" th:value="${obj.id}"> </form> </td> </tr> </table> </div> <hr> <form action="/new"> <input type="submit" id="add" class="btn btn-outline-secondary" value="新規追加" /> </form> </body> </html>
SearchRepositoryCustom.java
package com.example.addresslist.search; import java.io.Serializable; import java.util.List;//DAOclass import com.example.addresslist.user.User; public interface SearchRepositoryCustom extends Serializable { public List<User> search(String name,String sname,String address,String tel, String zip); }
SearchRepositoryCustomImp.java
package com.example.addresslist.search; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.Query; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.addresslist.user.User; @Service public class SearchRepositoryCustomImp implements SearchRepositoryCustom{ /** * */ private static final long serialVersionUID = 1L; @Autowired EntityManager manager; @SuppressWarnings("unchecked") //ListからList<User>に @Override public List<User> search(String name, String sname, String address, String tel, String zip ) { StringBuilder sql = new StringBuilder(); sql.append("SELECT u From User u WHERE "); boolean andflg = false; boolean nameflg = false; boolean snameflg = false; boolean addressflg = false; boolean telflg = false; boolean zipflg = false; if (!"".equals(name) && name != null) { sql.append(" u.name LIKE :name "); andflg = true; nameflg = true; } if (!"".equals(sname) && sname != null) { if (andflg) sql.append("AND "); sql.append(" u.sname LIKE :sname "); andflg = true; snameflg = true; } Query query = manager.createQuery(sql.toString()); if (nameflg) query.setParameter("name", "%" + name + "%"); if (snameflg) query.setParameter("sname", "%" + sname + "%"); return query.getResultList(); } }
SearchService.java
package com.example.addresslist.search; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.addresslist.repository.UserRepository; import com.example.addresslist.user.User; @Service public class SearchService { @Autowired UserRepository repos; @Autowired SearchRepositoryCustom repositoryCustom; public List<User> search(String name, String sname, String address, String tel, String zip){ List<User> lists; if ("".equals(name) && "".equals(sname) ) { lists = repos.findAll(); } else { lists = repositoryCustom.search(name,sname, address,tel, zip); } return lists; } }
AddressListController.java
package com.example.addresslist.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.web.bind.annotation.RequestParam; import com.example.addresslist.repository.UserRepository; import com.example.addresslist.search.SearchService; import com.example.addresslist.user.User; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import java.util.ArrayList; import java.util.List; import javax.validation.Valid; @Controller public class AddressListController { private final UserRepository repos; @Autowired SearchService service; public AddressListController(UserRepository repos) { this.repos = repos; } /* 一覧画面(初期画面)への遷移 */ @GetMapping("/") public String index(@RequestParam(required = false) String name, @RequestParam(required = false) String address, @RequestParam(required = false) String tel, @RequestParam(required = false) String zip, @RequestParam(required = false) String sname, Model model) { List<User> allLists = repos.findAll(); model.addAttribute("allLists", allLists); return "users/list"; } @PostMapping("/") public String create(Model model, @ModelAttribute User users) { User user = new User(); user.setName(users.getName()); user.setSname(users.getSname()); user.setAddress(users.getAddress()); user.setTel(users.getTel()); user.setZip(users.getZip()); repos.save(user); List<User> allLists = repos.findAll(); model.addAttribute("allLists", allLists); return "users/list"; } //省略 //検索機能 @GetMapping("/search") public String index() { return "users/list"; } @PostMapping("/search") public String search(Model model , @RequestParam(required = false) String name, @RequestParam(required = false) String address, @RequestParam(required = false) String tel, @RequestParam(required = false) String zip, @RequestParam(required = false) String sname) { model.addAttribute("name", name); model.addAttribute("sname", sname); model.addAttribute("address", address); model.addAttribute("tel", tel); model.addAttribute("zip", zip); List<User> allLists = service.search(name, address,tel, zip,sname); model.addAttribute("allLists", allLists); return "users/list"; } }
試したこと
参考URL https://dev.classmethod.jp/articles/spring-data-jpa-search-2/
あなたの回答
tips
プレビュー