我在Spring Boot中准备了一个应用程序,演示了使用和
Hibernate Search的功能。
问题/错误:当我尝试运行该应用程序时,它会给我一个错误:
Exception in thread "main" java.lang.IllegalArgumentException: java.lang.Object is not an indexed entity or a subclass of an indexed entity
I have referred the link : http://blog.netgloo.com/2014/10/27/using-mysql-in-spring-boot-via-spring-data-jpa-and-hibernate/
我的代码:
------------------------------ Application.java -------------- -----
package netgloo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
------------------------------- BuildSearchIndex.java ------------- --------
package netgloo;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
/**
* The only meaning for this class is to build the Lucene index at application
* startup. This is needed in this example because the database is filled
* before and each time the web application is started. In a normal web
* application probably you don't need to do this.
*/
@Component
public class BuildSearchIndex implements ApplicationListener<ContextRefreshedEvent> {
@PersistenceContext
private EntityManager entityManager;
/**
* Create an initial Lucene index for the data already present in the
* database.
* This method is called during Spring's startup.
*
* @param event Event raised when an ApplicationContext gets initialized or
* refreshed.
*/
@Override
public void onApplicationEvent(final ContextRefreshedEvent event) {
try {
FullTextEntityManager fullTextEntityManager =
Search.getFullTextEntityManager(entityManager);
fullTextEntityManager.createIndexer().startAndWait();
}
catch (InterruptedException e) {
System.out.println(
"An error occurred trying to build the serach index: " +
e.toString());
}
return;
}
}
---------------------------------控制器------------- ------------
package netgloo.controllers;
import java.util.List;
import netgloo.models.Employee;
import netgloo.search.EmployeeSearch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController {
@Autowired
private EmployeeSearch emprSearch;
@RequestMapping("/")
@ResponseBody
public String index() {
return "Welcome !!!:)";
}
@RequestMapping("/search")
public String search(String query, Model model) {
List<Employee> searchResults = null;
try {
searchResults = emprSearch.search(query);
} catch (Exception ex) {
return "";
}
model.addAttribute("searchResults", searchResults);
return "search";
}
}
------------------------------模型---------------- ---------------
package netgloo.models;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
@Entity
@Table(name = "employees")
public class Employee {
// An autogenerated id (unique for each user in the db)
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotNull
private String email;
@NotNull
private String name;
// Public methods
public Employee() { }
public Employee(long id) {
this.id = id;
}
public Employee(String email, String name) {
this.email = email;
this.name = name;
}
// Getter and setter methods
// ...
}
/////////////////////////// EmployeeSearch.java///////////////// //////
package netgloo.search;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import netgloo.models.Employee;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.springframework.stereotype.Repository;
@Repository
@Transactional
public class EmployeeSearch {
// Spring will inject here the entity manager object
@PersistenceContext
private EntityManager entityManager;
public List<Employee> search(String text) {
// get the full text entity manager
FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search
.getFullTextEntityManager(entityManager);
// create the query using Hibernate Search query
QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Employee.class)
.get();
// a very basic query by keywords
org.apache.lucene.search.Query query = queryBuilder.keyword().onFields("name", "city", "email").matching(text)
.createQuery();
// wrap Lucene query in an Hibernate Query object
org.hibernate.search.jpa.FullTextQuery jpaQuery = fullTextEntityManager.createFullTextQuery(query, Employee.class);
// execute search and return results (sorted by relevance as default)
@SuppressWarnings("unchecked")
List<Employee> results = jpaQuery.getResultList();
return results;
}
}
///////////////////////// search.html /////////////////// ///////////////
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Search</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<ol>
<li th:each="employee : ${searchResults}">
<b><span th:text="${employee.username}"></span></b> -
<span th:text="${employee.city}"></span> -
<span th:text="${employee.email}"></span>
</li>
</ol>
<p th:if="${searchResults.isEmpty()}">
<strong>Hint</strong>: the query "<a href='/search?query=amy'>amy</a>"
should return some results.
</p>
</body>
</html>
/////////////////////////// application.properties///////////////// //////
# Datasource settings
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/myschema
spring.datasource.username=root
spring.datasource.password=admin123
# Hibernate settings
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy =org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.show-sql = true
# Specify the DirectoryProvider to use (the Lucene Directory)
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 = c:\\indexeFiles
# ===============================
# = THYMELEAF
# ===============================
spring.thymeleaf.cache = false
server.port=9001
///////////////////////////////的pom.xml ///////////// //////////////
<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>netgloo</groupId>
<artifactId>spring-boot-hibernate-search</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-hibernate-search</name>
<description>How to integrate Hibernate Search in Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Maven artifact identifier for Hibernate Search -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>4.5.1.Final</version>
</dependency>
<!-- Optional: to use JPA 2.1 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>netgloo.Application</start-class>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
我的Stacktrace:
Exception in thread "main" java.lang.IllegalArgumentException: java.lang.Object is not an indexed entity or a subclass of an indexed entity
at org.hibernate.search.impl.MassIndexerImpl.toRootEntities(MassIndexerImpl.java:102)
at org.hibernate.search.impl.MassIndexerImpl.<init>(MassIndexerImpl.java:74)
at org.hibernate.search.impl.DefaultMassIndexerFactory.createMassIndexer(DefaultMassIndexerFactory.java:47)
at org.hibernate.search.impl.FullTextSessionImpl.createIndexer(FullTextSessionImpl.java:181)
at org.hibernate.search.jpa.impl.FullTextEntityManagerImpl.createIndexer(FullTextEntityManagerImpl.java:349)
at netgloo.BuildSearchIndex.onApplicationEvent(BuildSearchIndex.java:38)
at netgloo.BuildSearchIndex.onApplicationEvent(BuildSearchIndex.java:1)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:773)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:140)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at netgloo.Application.main(Application.java:10)
谢谢!!!
答案 0 :(得分:3)
至少可以说,您的实体应注明@Indexed
。您还应根据您的要求使用@Field
注释实体类的字段。