spring boot2を学習しているのですが、データベースアクセスの検索部分でうまくいきません。
以下は、HeloController.javaです。
package com.tuyano.springboot; import java.util.List; import java.util.Optional; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import com.tuyano.springboot.repositories.MyDataRepository; @Controller public class HeloController { @Autowired MyDataRepository repository; @Autowired MyDataDaoImpl dao; @RequestMapping(value = "/",method = RequestMethod.GET) public ModelAndView index(ModelAndView mav) { mav.setViewName("index"); mav.addObject("msg","MyDataのサンプルです。"); Iterable<MyData> list = dao.getAll(); mav.addObject("datalist",list); return mav; } @RequestMapping(value = "/",method = RequestMethod.POST) @Transactional(readOnly=false) public ModelAndView form(@ModelAttribute("formModel")@Validated MyData mydata, BindingResult result,ModelAndView mov) { ModelAndView res = null; if(!result.hasErrors()) { repository.saveAndFlush(mydata); res = new ModelAndView("redirect:/"); }else { mov.setViewName("index"); mov.addObject("msg","sorry,error is occured..."); Iterable<MyData> list = repository.findAll(); mov.addObject("datalist",list); res = mov; } return res; } @RequestMapping(value="/find", method = RequestMethod.GET) public ModelAndView find(ModelAndView mav) { mav.setViewName("find"); mav.addObject("title","Find Page"); mav.addObject("msg","MyDataのサンプルです"); mav.addObject("value",""); Iterable<MyData> list = dao.getAll(); mav.addObject("datalist",list); return mav; } @RequestMapping(value = "/find",params = "search",method = RequestMethod.POST) public ModelAndView search(@RequestParam(name="fstr")String param, ModelAndView mav) { mav.setViewName("find"); if(param == "") { mav = new ModelAndView("redirect:/find"); } else { mav.addObject("title","Find result"); mav.addObject("msg","「" + param + "」の検索結果"); mav.addObject("value",param); List<MyData> list = dao.find(param); mav.addObject("datalist",list); } return mav; } @RequestMapping(value = "/find",params = "confirm_data",method = RequestMethod.POST) public ModelAndView empty_check(@RequestParam(name="fstr")String param,ModelAndView mav) { mav.setViewName("find"); mav.addObject("title","Find result"); mav.addObject("msg",""); // mav.addObject("value",); List<MyData> list = dao.empty(); System.out.println(list); mav.addObject("datalist",list); return mav; } @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET) public ModelAndView edit(@ModelAttribute MyData mydata, @PathVariable int id, ModelAndView mav) { mav.setViewName("edit"); mav.addObject("title", "edit mydata."); Optional<MyData> data = repository.findById((long)id); // Optionalオブジェクトが保持する値を返す(date.get()) mav.addObject("formModel",data.get()); System.out.println("ok"); return mav; } @RequestMapping(value="/edit",method=RequestMethod.POST) @Transactional(readOnly=false) public ModelAndView update(@ModelAttribute MyData mydata,ModelAndView mav){ repository.saveAndFlush(mydata); System.out.println(mydata); return new ModelAndView("redirect:/"); } @RequestMapping(value = "/delete/{id}",method = RequestMethod.GET) public ModelAndView delete(@PathVariable int id,ModelAndView mav) { mav.setViewName("delete"); mav.addObject("title","delete mydata."); Optional<MyData> data = repository.findById((long)id); System.out.println(data.get()); mav.addObject("formModel",data.get()); return mav; } @RequestMapping(value = "/delete",method = RequestMethod.POST) public ModelAndView remove(@RequestParam long id,ModelAndView mav) { repository.deleteById(id); return new ModelAndView("redirect:/"); } @PostConstruct public void init() { MyData d1 = new MyData(); d1.setName("tuyano"); d1.setAge(123); d1.setMail("syoda@tuyano.com"); d1.setMemo("a"); repository.saveAndFlush(d1); MyData d2 = new MyData(); d2.setName("hanako"); d2.setAge(15); d2.setMail("hanako@flower"); d2.setMemo("b"); repository.saveAndFlush(d2); MyData d3 = new MyData(); d3.setName("sachiko"); d3.setAge(37); d3.setMail("sachico@happy"); d3.setMemo("c"); repository.saveAndFlush(d3); } } class DataObject{ private int id; private String name; private String value; public DataObject(int id, String name, String value){ super(); this.id = id; this.name = name; this.value = value; } public int getId(){ return id;} public void setId(int id){ this.id = id;} public String getName() { return name;} public void setName(String name){ this.name = name; } public String getValue(){ return value; } public void setValue(String value){ this.value = value; } }
以下は、MyDataDaoImpl.javaです
package com.tuyano.springboot; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; import org.springframework.stereotype.Repository; @Repository public class MyDataDaoImpl implements MyDataDao<MyData> { private static final long serialVersionUID = 1L; @PersistenceContext private EntityManager entityManager; public MyDataDaoImpl() { super(); } public MyDataDaoImpl(EntityManager manager) { entityManager = manager; } @Override public List<MyData> getAll(){ List<MyData> list = null; CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<MyData> query = builder.createQuery(MyData.class); Root<MyData> root = query.from(MyData.class); query.select(root); list = (List<MyData>)entityManager.createQuery(query).getResultList(); return list; } @Override public MyData findById(long id) { return (MyData)entityManager.createQuery("from MyData where id = " + id).getSingleResult(); } @Override public List<MyData> findByName(String name) { return (List<MyData>)entityManager.createQuery("from MyData where nama = " + name).getResultList(); } @Override public List<MyData> find(String fstr) { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<MyData> query = builder.createQuery(MyData.class); Root<MyData> root = query.from(MyData.class); query.select(root).where(builder.equal(root.get("name"),fstr)); List<MyData> list = null; list = (List<MyData>) entityManager.createQuery(query).getResultList(); return list; } @Override public List<MyData> empty(){ CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<MyData> query = builder.createQuery(MyData.class); Root<MyData> root = query.from(MyData.class); query.select(root).where(builder.isEmpty(root.get("name"))); List<MyData> list = null; list = (List<MyData>) entityManager.createQuery(query).getResultList(); return list; } }
以下は、find.htmlです
<!DOCTYPE html> <html> <head> <title>find page</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style> h1 { font-size:18pt; font-weight:bold; color:gray; } body { font-size:13pt; color:gray; margin:5px 25px; } tr{ margin:5px; } th{ padding:5px; color:white; background:darkgray; } td{ padding:5px; color:black; background:#e0e0ff; } </style> </head> <body> <h1 th:text="${title}">find page</h1> <p th:text="${msg}"> <table> <form action="/find" method="post"> <tr><td>検索:</td> <td><input type="text" name="fstr" size="20" th:value="${value}"></td></tr> <tr><td></td><td><input type="submit" name = "search"><td></td> <tr><td>空チェック:</td> <tr><td></td><td><input type="submit" name = "confirm_data" value="中身を確認する"><td></td> </form> </table> <hr/> <table> <tr><th>ID</th><th>名前</th><th>メール</th><th>年齢</th></tr> <tr th:each="obj : ${datalist}"> <td th:text="${obj.id}"></td> <td th:text="${obj.name}"></td> <td th:text="${obj.mail}"></td> <td th:text="${obj.age}"></td> </tr> </table> </body> </html>
Eclipseの再生ボタンを押し、http://localhost:8080/find
にアクセスすると、以下の画面が表示されます。
しかし、「中身を確認する」ボタンを押すと、エラーとなってしまいます。
![]
こちらCaused by: java.lang.IllegalArgumentException: unknown collection expression type [org.hibernate.query.criteria.internal.path.SingularAttributePath]
などで検索したのですが、解決できませんでした。
ご助言頂けましたら、幸いです。
あなたの回答
tips
プレビュー