title: Java Spring Data Hibernate Search Engine
body: <p>error:
  org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'searchController' method 
  public java.lang.String softuniBlog.controller.SearchController.search(java.lang.String,org.springframework.ui.Model)
  to {[/search]}: There is already 'searchController' bean method
  public java.lang.String softuniBlog.controller.SearchController.index() mapped. </p>
  
  <p>**I`m trying to build search engine for my blog and have 3 questions.
      1) Why In application properties last 3 rows are "can not resolve"
      2) How can I fix the error I have, app is working but when try url /search?q=someText it trows exception:
  [Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: org.hibernate.engine.spi.SessionDelegatorBaseImpl.(Lorg/hibernate/engine/spi/SessionImplementor;)V] with root cause</p>
  
  <p>java.lang.NoSuchMethodError: org.hibernate.engine.spi.SessionDelegatorBaseImpl.(Lorg/hibernate/engine/spi/SessionImplementor;)V
      3) How can take search query from input form instead from url </p>
  
  <pre><code>please check the code:
  </code></pre>
  
  <p>search input box</p>
  
  <pre><code>&lt;div id="wrap"&gt;
                  &lt;form action="" autocomplete="on"&gt;
                      &lt;input id="search" name="search" type="text"              placeholder="What're we looking for ?"&gt;&lt;/input&gt;
                      &lt;input id="search_submit" value="Rechercher" type="submit"&gt;&lt;/input&gt;
                  &lt;/form&gt;
              &lt;/div&gt;
  </code></pre>
  
  <p>Article controller </p>
  
  <pre><code>package softuniBlog.controller;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.security.access.prepost.PreAuthorize;
  import  org.springframework.security.authentication.AnonymousAuthenticationToken;
  import org.springframework.security.core.context.SecurityContextHolder;
  import org.springframework.security.core.userdetails.UserDetails;
  import org.springframework.stereotype.Controller;
  import org.springframework.ui.Model;
  import org.springframework.web.bind.annotation.GetMapping;
  import org.springframework.web.bind.annotation.PathVariable;
  import org.springframework.web.bind.annotation.PostMapping;
  import org.springframework.web.bind.annotation.RequestParam;
  import org.springframework.web.multipart.MultipartFile;
  import softuniBlog.bindingModel.ArticleBindingModel;
  import softuniBlog.entity.Article;
  import softuniBlog.entity.User;
  import softuniBlog.repository.ArticleRepository;
  import softuniBlog.repository.UserRepository;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.Arrays;
  
  @Controller
  public class ArticleConstroller {
      @Autowired
      private ArticleRepository articleRepository;
      @Autowired
      private UserRepository userRepository;
      @GetMapping("/article/create")
      @PreAuthorize("isAuthenticated()")
      public String create(Model model){
          model.addAttribute("view", "/article/create");
          return "base-layout";
      }
  
  
      @PostMapping("/article/create")
      @PreAuthorize("isAuthenticated()")
      public String createProcess(ArticleBindingModel articleBindingModel){
  
          UserDetails user = (UserDetails) SecurityContextHolder
                  .getContext()
                  .getAuthentication()
                  .getPrincipal();
  
          User userEntity =  this.userRepository.findByEmail(user.getUsername());
  
          String databasePathImage = null;
  
          String[] allowedContentTypes = {
                  "image/png",
                  "image/jpg",
                  "image/jpeg"
          };
  
          boolean isContentTypeAllowed =
                  Arrays.asList(allowedContentTypes)
                           .contains(articleBindingModel.getImage().getContentType());
  
          if(isContentTypeAllowed){
              String imagesPath = "\\src\\main\\resources\\static\\img\\";
              String imagePathRoot = System.getProperty("user.dir");
              String imageSaveDirectory = imagePathRoot + imagesPath;
  
              String fileName = articleBindingModel.getImage().getOriginalFilename();
  
              String savePath = imageSaveDirectory + fileName;
  
              File imageFile = new File(savePath);
              try {
                  articleBindingModel.getImage().transferTo(imageFile);
                  databasePathImage = "/img/" + fileName;
              } catch (IOException e) {
                  System.out.println(e.getMessage());
              }
  
  
          }
  
  
          Article articleEntity = new Article(
                  articleBindingModel.getTitle(),
                  articleBindingModel.getContent(),
                  userEntity,
                  databasePathImage
          );
          this.articleRepository.saveAndFlush(articleEntity);
          return "redirect:/";
  
      }
  
  
      @GetMapping("/article/edit/{id}")
      @PreAuthorize("isAuthenticated()")
      public String edit(@PathVariable Integer id, Model model){
          if(!this.articleRepository.exists(id)){
              return "redirect:/";
          }
          Article article = this.articleRepository.findOne(id);
  
          if(!this.isUserAuthorOrAdmin(article)){
              return "redirect:/";
          }
  
          model.addAttribute("view", "article/edit");
          model.addAttribute("article", article);
  
          return "base-layout";
      }
  
  
  
      @GetMapping("/article/{id}")
      public String details(Model model, @PathVariable Integer id) {
          if(!this.articleRepository.exists(id)){
              return "redirect:/";
          }
  
          if(!(SecurityContextHolder.getContext().getAuthentication()
                  instanceof AnonymousAuthenticationToken)){
              UserDetails principal = (UserDetails) SecurityContextHolder.getContext()
                      .getAuthentication().getPrincipal();
  
              User entityUser = this.userRepository.findByEmail(principal.getUsername());
  
              model.addAttribute("user", entityUser);
          }
  
          Article article = this.articleRepository.findOne(id);
          model.addAttribute("view", "article/details");
          model.addAttribute("article", article);
  
          return "base-layout";
      }
  
      @PostMapping("/article/edit/{id}")
      @PreAuthorize("isAuthenticated()")
      public String editProcess(@PathVariable Integer id, ArticleBindingModel articleBindingModel) {
          if(!this.articleRepository.exists(id)){
              return "redirect:/";
          }
          Article article = this.articleRepository.findOne(id);
          if(!this.isUserAuthorOrAdmin(article)){
              return "redirect:/";
          }
          article.setTitle(articleBindingModel.getTitle());
          article.setContent(articleBindingModel.getContent());
          this.articleRepository.saveAndFlush(article);
          return "redirect:/article/" + article.getId();
  
      }
  
      @GetMapping("/article/delete/{id}")
      @PreAuthorize("isAuthenticated()")
      public String delete(@PathVariable Integer id, Model model){
          if(!this.articleRepository.exists(id)){
              return "redirect:/";
          }
  
          Article article = this.articleRepository.findOne(id);
          if(!this.isUserAuthorOrAdmin(article)){
              return "redirect:/";
          }
          model.addAttribute("article", article);
          model.addAttribute("view", "article/delete");
  
          return "base-layout";
      }
  
      @PostMapping("/article/delete/{id}")
      @PreAuthorize("isAuthenticated()")
      public String deleteProcess(@PathVariable Integer id) {
          if(!this.articleRepository.exists(id)){
              return "redirect:/";
          }
          Article article = this.articleRepository.findOne(id);
          if(!this.isUserAuthorOrAdmin(article)){
              return "redirect:/";
          }
          this.articleRepository.delete(article);
  
          return "redirect:/";
  
      }
  
      private boolean isUserAuthorOrAdmin(Article article){
          UserDetails user = (UserDetails) SecurityContextHolder
                  .getContext()
                  .getAuthentication()
                  .getPrincipal();
  
          User userEntity = this.userRepository.findByEmail(user.getUsername());
          return userEntity.isAdmin() || userEntity.isAuthor(article);
      }
  }
  </code></pre>
  
  <p>Article model</p>
  
  <pre><code>import javax.validation.constraints.NotNull;
  
  import javax.persistence.*;
  import java.util.Date;
  
  @Entity
  @Indexed
  @Table(name = "articles")
  public class Article {
  
      private Integer id;
      @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
      @NotNull
      private String title;
      @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
      @NotNull
      private String content;
  
  
      private Date date;
  
      private User author;
  
      private String imagePath;
  
      public Article(String title, String content, User author, String imagePath) {
          this.title = title;
          this.content = content;
          this.author = author;
          this.imagePath = imagePath;
          this.date = new Date();
      }
  
      public Article(){
  
      }
  
  
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      public Integer getId() {
          return id;
      }
  
      public void setId(Integer id) {
          this.id = id;
      }
  
      @Column(name = "title", nullable = false)
  
      public String getTitle() {
          return title;
      }
  
      public void setTitle(String title) {
          this.title = title;
      }
  
      @Column(name = "content", nullable = false, columnDefinition = "text")
      public String getContent() {
          return content;
      }
  
      public void setContent(String content) {
          this.content = content;
      }
  
      @Column(name = "date", nullable = true)
      public Date getDate() {
          return date;
      }
  
      public void setDate(Date date) {
          this.date = date;
      }
  
      @ManyToOne()
      @JoinColumn(nullable = false, name = "authorId")
      public User getAuthor() {
          return author;
      }
  
      public void setAuthor(User author) {
          this.author = author;
      }
      @Transient
      public String getSummary(){
          return this.getContent().substring(0, this.getContent().length()/2) + "...";
      }
  
      public String getImagePath() {
          return imagePath;
      }
  
      public void setImagePath(String imagePath) {
          this.imagePath = imagePath;
      }
  }
  </code></pre>
  
  <p>Application properties </p>
  
  <pre><code># Database connection with the given database name
  spring.datasource.url = jdbc:mysql://localhost:3306/javablog
  
  # Username and password
  spring.datasource.username = root
  spring.datasource.password =
  
  # Show or not log for each sql query
  spring.jpa.show-sql = true
  
  # Hibernate ddl auto (create, create-drop, update): with "update" the database
  # schema will be automatically updated accordingly to java entities found in
  # the project
  # Using "create" will delete and recreate the tables every time the project is started
  spring.jpa.hibernate.ddl-auto = update
  
  # Naming strategy
  spring.jpa.hibernate.naming.strategy = org.hibernate.cfg.ImprovedNamingStrategy
  
  # Allows Hibernate to generate SQL optimized for a particular DBMS
  spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
  
  spring.jpa.properties.hibernate.search.default.directory_provider = filesystem
  
  # Using the filesystem DirectoryProvider you also have to specify the default
  # base directory for all indexes (make sure that the application have write
  # permissions on such directory)
  spring.jpa.properties.hibernate.search.default.indexBase = ../java/softuniBlog/lucene/indexes
  
  #Turn off Thymeleaf cache
  spring.thymeleaf.cache = false
  </code></pre>
  
  <p>POM XML</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;groupId&gt;softuni.blog&lt;/groupId&gt;
      &lt;artifactId&gt;blog&lt;/artifactId&gt;
      &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
      &lt;packaging&gt;jar&lt;/packaging&gt;
  
      &lt;name&gt;Blog&lt;/name&gt;
      &lt;description&gt;Blog Project from the Software Technologies Course&lt;/description&gt;
  
      &lt;parent&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
          &lt;version&gt;1.4.2.RELEASE&lt;/version&gt;
          &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;
      &lt;/parent&gt;
  
      &lt;properties&gt;
          &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
          &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
          &lt;java.version&gt;1.8&lt;/java.version&gt;
      &lt;/properties&gt;
  
      &lt;dependencies&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
              &lt;scope&gt;runtime&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;mysql&lt;/groupId&gt;
              &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
              &lt;scope&gt;runtime&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.thymeleaf.extras&lt;/groupId&gt;
              &lt;artifactId&gt;thymeleaf-extras-springsecurity4&lt;/artifactId&gt;
              &lt;version&gt;2.1.2.RELEASE&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
              &lt;artifactId&gt;hibernate-search-orm&lt;/artifactId&gt;
              &lt;version&gt;5.7.0.Final&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
              &lt;artifactId&gt;hibernate-entitymanager&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
              &lt;artifactId&gt;hibernate-search-infinispan&lt;/artifactId&gt;
              &lt;version&gt;5.7.0.Final&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
              &lt;artifactId&gt;hibernate-search-elasticsearch&lt;/artifactId&gt;
              &lt;version&gt;5.7.0.Final&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.infinispan&lt;/groupId&gt;
              &lt;artifactId&gt;infinispan-directory-provider&lt;/artifactId&gt;
              &lt;version&gt;8.2.4.Final&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator --&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
              &lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;
              &lt;version&gt;6.0.0.Alpha2&lt;/version&gt;
          &lt;/dependency&gt;
  
      &lt;/dependencies&gt;
  
      &lt;build&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                  &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
      &lt;/build&gt;`enter code here`
  
  
  &lt;/project&gt;
  </code></pre>