简体   繁体   中英

Java Spring Data Hibernate Search Engine

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.

**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

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

please check the code:

search input box

<div id="wrap">
                <form action="" autocomplete="on">
                    <input id="search" name="search" type="text"              placeholder="What're we looking for ?"></input>
                    <input id="search_submit" value="Rechercher" type="submit"></input>
                </form>
            </div>

Article controller

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);
    }
}

Article model

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;
    }
}

Application properties

# 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

POM XML

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>softuni.blog</groupId>
    <artifactId>blog</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>Blog</name>
    <description>Blog Project from the Software Technologies Course</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-search-orm</artifactId>
            <version>5.7.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-search-infinispan</artifactId>
            <version>5.7.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-search-elasticsearch</artifactId>
            <version>5.7.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.infinispan</groupId>
            <artifactId>infinispan-directory-provider</artifactId>
            <version>8.2.4.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.0.Alpha2</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>`enter code here`


</project>

I honestly don't understand you other questions (and you probably should ask them separately), but for question 2 I can tell you that a NoSuchMethodError is very likely to be caused by your using an incompatible version of Hibernate ORM with Hibernate Search.

To sum up:

  • Hibernate Search 5.7.0 and later should be used with Hibernate ORM 5.2.3 or later.
  • Hibernate Search 5.6.x and earlier should be used with Hibernate ORM 5.1.x or earlier.

EDIT : Your pom appears to contain a dependency to hibernate-entitymanager , and you didn't set the version for this dependency, so I suspect you're getting some older version. hibernate-entitymanager isn't required to use JPA starting with Hibernate ORM 5.2, so you should try to remove it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM