我正在开发一个SpringMVC + CRUD + Hibernate搜索示例:
当我搜索特定文本时,它会给我这个错误:
**Error** : HTTP Status 500 - Handler dispatch failed; nested exception is java.lang.NoSuchFieldError: session
I tried all the examples given here :
http://www.programcreek.com/java-api-examples/index.php?api=org.hibernate.search.jpa.FullTextEntityManager, but nothing works :
我的代码:
//////////////////////////// search.jsp的//////////////// ////////////
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form"
prefix="springForm"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Search Page</title>
</head>
<body>
<%-- <ol>
<li th:each="person : ${searchResults}">
<b><span th:text="${person.name}"></span></b> -
<span th:text="${person.address}"></span> -
<span th:text="${person.salary}"></span>
<span th:text="${person.gender}"></span>
</li>
</ol> --%>
<springForm:form action="/MainAssignment3/search" method="GET"
commandName="person">
<tr>
<td>Enter Search Text:</td>
<td><input type="text" name="text">
<input type="submit" value="submit" onclick="/MainAssignment3/search"></input> </td>
</tr>
</springForm:form>
<table border="1">
<tr>
<th>id</th>
<td>name<springForm:errors path='${person.name}' /></td>
<td>address<springForm:errors path='${person.address}' /></td>
<td>gender<springForm:errors path='${person.gender}' /></td>
<td>salary<springForm:errors path='${person.salary}' /></td></tr>
<c:forEach var="p" items='${searchResults}' varStatus="status">
<tr>
<td>${p.id}</td>
<td>${p.name}</td>
<td>${p.address}</td>
<td>${p.gender}</td>
<td>${p.salary}</td>
</tr>
</c:forEach>
</table>
<%-- <p th:if="${searchResults.isEmpty()}">
<strong>Hint</strong>: the query "<a href='/search?query=any'>any</a>"
should return some results.
</p> --%>
</body>
</html>
/////////////////////////////搜索方法的实施//////////
package com.dao;
import java.util.List;
import java.util.Map;
import javax.persistence.Cache;
import javax.persistence.EntityGraph;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnitUtil;
import javax.persistence.SynchronizationType;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.metamodel.Metamodel;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
import org.hibernate.search.query.dsl.EntityContext;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.model.Person;
@Transactional
@Repository
public class PersonDAOImpl implements PersonDAO, java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
//private EntityManager em;
//private FullTextEntityManager ftem;
private EntityManagerFactory efact;
private static final Logger logger = (Logger) LoggerFactory
.getLogger(PersonDAOImpl.class);
@Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf) {
this.sessionFactory = sf;
}
public void save(Person p) {
// TODO Auto-generated method stub
Session s = sessionFactory.openSession();
Transaction tx = s.beginTransaction();
s.saveOrUpdate(p);
tx.commit();
s.close();
System.out.println("Record successfully inserted");
}
@SuppressWarnings("deprecation")
public List<Person> list() {
// TODO Auto-generated method stub
Session session = this.sessionFactory.getCurrentSession();
@SuppressWarnings("unchecked")
List<Person> personsList = session.createQuery("from Person").list();
for (Person p : personsList) {
logger.info("Person List::" + p);
}
return personsList;
}
public void updatePerson(Integer id) {
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
Person p = new Person();
Person person = session.get(Person.class, p.getId());
session.createQuery("from Person");
person.setName(p.getName()); // modify the loaded object somehow
session.update(person);
//t.commit();
session.close();
}
public Person getPersonById(int id) {
// TODO Auto-generated method stub
Session session = this.sessionFactory.getCurrentSession();
Person p = (Person) session.load(Person.class, new Integer(id));
logger.info("Person loaded successfully, Person details=" + p);
return p;
}
public void removePerson(Integer id) {
Session session = sessionFactory.getCurrentSession();
// Transaction t = session.beginTransaction();
Person p = (Person) session.load(Person.class, new Integer(id));
session.delete(p);
// t.commit();
logger.info("Person deleted successfully, person details=");
}
@SuppressWarnings("unchecked")
public List<Person> search(String text) {
/*// TODO Auto-generated method stub
// FullTextEntityManager ftEntityManager = EntityManagerHolder.getFullTextEntityManager();
//FullTextEntityManager fullTextEntityManager = (FullTextEntityManager) ((EntityContext) entityManager).get();
FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
//FullTextSession fullTextEntityManager =Search.getFullTextSession(sessionFactory.getCurrentSession());
QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();
org.apache.lucene.search.Query query = queryBuilder.keyword().onFields("name", "address", "salary","gender").matching(text).createQuery();
//org.hibernate.search.jpa.FullTextQuery jpaQuery = fullTextEntityManager.createFullTextQuery(query, Person.class);
FullTextQuery jpaQuery= fullTextEntityManager.createFullTextQuery(query, Person.class);
@SuppressWarnings("unchecked")
List<Person> results = jpaQuery.getResultList();
em.refresh(Person.class);
return results;*/
/* // Create a Query Builder
QueryBuilder qb = getFullTextEntityManager().getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();
// Create a Lucene Full Text Query
org.apache.lucene.search.Query luceneQuery = (org.apache.lucene.search.Query) qb.bool()
.must(qb.keyword().onFields("name", "address", "salary","gender").matching(text).createQuery());
Query fullTextQuery = (Query) getFullTextEntityManager().createFullTextQuery(luceneQuery, Person.class);
// Run Query and print out results to console
List<Person> result = (List<Person>) fullTextQuery.getResultList();
return result;
}
protected FullTextEntityManager getFullTextEntityManager() {
if (ftem == null) {
ftem = Search.getFullTextEntityManager(em);
}
return ftem;
}
*//**
* Get the JPA Entity Manager (required for the DBUnit Tests).
* @return Entity manager
*//*
protected EntityManager getEntityManager() {
return em;
}
*//**
* Sets the JPA Entity Manager (required to assist with mocking in Unit Test)
* @param em EntityManager
*//*
protected void setEntityManager(EntityManager em) {
this.em = em;
}
*/ EntityManager em = efact.createEntityManager();
FullTextEntityManager fullTextEntityManager =
org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
em.getTransaction().begin();
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder().forEntity(Person.class).get();
org.apache.lucene.search.Query luceneQuery = qb
.keyword()
.onFields("name", "address", "salary","gender")
.matching(text)
.createQuery();
// wrap Lucene query in a javax.persistence.Query
javax.persistence.Query jpaQuery =
fullTextEntityManager.createFullTextQuery(luceneQuery, Person.class);
// execute search
List result = jpaQuery.getResultList();
em.getTransaction().commit();
em.flush();
em.close();
return result;
} }
////////////////////////////控制器////////////////// ///////////
@Controller
public class MainController {
@Autowired
private PersonService ps;
@RequestMapping("/")
public ModelAndView listPersons(ModelAndView model) throws IOException {
List<Person> listper = ps.list();
model.addObject("personsList", listper);
model.setViewName("index");
return model;
}
@RequestMapping("/search")
public ModelAndView search(String query, Model model,HttpServletRequest req)
{
String name = req.getParameter("name");
String address = req.getParameter("address");
String salary = req.getParameter("salary");
String gender = req.getParameter("gender");
model.addAttribute("name", name);
model.addAttribute("address", address);
model.addAttribute("salary", salary);
model.addAttribute("gender", gender);
List<Person> searchResults = null;
searchResults = ps.search(query);
//NullPointerException in the above line
model.addAttribute("searchResults", searchResults);
return new ModelAndView("search");
}
///////////////////////////////// ServiceImplementation ///////////// ///////
public List<Person> search(String text) {
// TODO Auto-generated method stub
return pdao.search(text);
}
/////////////////////////的栈跟踪 ////////////// ////////
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'springConfig': Unsatisfied dependency expressed through field 'ps': Error creating bean with name 'PersonService': Unsatisfied dependency expressed through field 'pdao': Error creating bean with name 'personDAOImpl' defined in file [C:\spring-tool 3.6. (64 bit)\sts-bundle\pivotal-tc-server-developer-3.0.2.SR2\base-instance\wtpwebapps\MainAssignment3\WEB-INF\classes\com\dao\PersonDAOImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type [javax.persistence.EntityManager] found for dependency [javax.persistence.EntityManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManager] found for dependency [javax.persistence.EntityManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'personDAOImpl' defined in file [C:\spring-tool 3.6. (64 bit)\sts-bundle\pivotal-tc-server-developer-3.0.2.SR2\base-instance\wtpwebapps\MainAssignment3\WEB-INF\classes\com\dao\PersonDAOImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type [javax.persistence.EntityManager] found for dependency [javax.persistence.EntityManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManager] found for dependency [javax.persistence.EntityManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'PersonService': Unsatisfied dependency expressed through field 'pdao': Error creating bean with name 'personDAOImpl' defined in file [C:\spring-tool 3.6. (64 bit)\sts-bundle\pivotal-tc-server-developer-3.0.2.SR2\base-instance\wtpwebapps\MainAssignment3\WEB-INF\classes\com\dao\PersonDAOImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type [javax.persistence.EntityManager] found for dependency [javax.persistence.EntityManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManager] found for dependency [javax.persistence.EntityManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'personDAOImpl' defined in file [C:\spring-tool 3.6. (64 bit)\sts-bundle\pivotal-tc-server-developer-3.0.2.SR2\base-instance\wtpwebapps\MainAssignment3\WEB-INF\classes\com\dao\PersonDAOImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type [javax.persistence.EntityManager] found for dependency [javax.persistence.EntityManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManager] found for dependency [javax.persistence.EntityManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency.
//////////////////////////////////////的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>org.springframework.samples.service.service</groupId>
<artifactId>MainAssignment3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<!-- Generic properties -->
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Web -->
<jsp.version>2.2</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>2.5</servlet.version>
<!-- Spring -->
<spring-framework.version>4.3.2.RELEASE</spring-framework.version>
<!-- Hibernate / JPA -->
<hibernate.version>5.2.1.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-engine</artifactId>
<version>5.5.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.5.4.Final</version>
</dependency>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version> </dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.3</version>
</dependency>
<dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId>
<version>1.1</version> </dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- Other Web dependencies -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<!-- Spring and Transactions -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Test Artifacts -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
我尝试了两种方法:Hibernate Session和JPA
方法1:JPA
DAO实施:
@PersistenceUnit
private EntityManagerFactory emf;
private EntityManager em;
private FullTextEntityManager ftem;
public void createFullTextEntityManager() {
em = emf.createEntityManager();
ftem = Search.getFullTextEntityManager(em);
}
@Autowired
private SessionFactory sessionFactory;
@SuppressWarnings("unchecked")
public List<Person> search(String text) throws InterruptedException {
EntityManager em = emf.createEntityManager();
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
em.getTransaction().begin();
fullTextEntityManager.createIndexer().startAndWait();
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder().forEntity(Person.class).get();
org.apache.lucene.search.Query luceneQuery = qb
.keyword()
.onFields("name", "address", "salary","gender")
.matching(text)
.createQuery();
// wrap Lucene query in a javax.persistence.Query
javax.persistence.Query jpaQuery =
fullTextEntityManager.createFullTextQuery(luceneQuery, Person.class);
// execute search
List result = jpaQuery.getResultList();
em.getTransaction().commit();
em.close();
return result;
}}
方法2:休眠会话
DAOImpl:
@Autowired
private SessionFactory sessionFactory;
private Session session=null;
public void setSessionFactory(SessionFactory sf) {
this.sessionFactory = sf;
}
@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" })
public List<Person> search(String text) throws InterruptedException{
FullTextSession fullTextSession = Search.getFullTextSession(session);
try {
Transaction tx = fullTextSession.beginTransaction();
org.hibernate.search.query.dsl.QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Person.class ).get();
org.apache.lucene.search.Query query = qb.keyword().onFields("name", "address", "salary","gender").matching(text).createQuery();
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(query, Person.class);
List result = hibQuery.list();
Iterator<Person> it = result.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p);
}
tx.commit();
}
finally{
session.close();
}
return null;
}
}
答案 0 :(得分:1)
hibernate-core的版本设置为 5.2.1.Final ,而hibernate-entitymanager设置为 5.1.0.Final :这些不兼容,在hibernate-entitymanager和hibernate-core的情况下,版本必须相同。
Hibernate Search使用自己的版本控制,您选择的版本 5.5.4.Final 与Hibernate ORM 5.1.0.Final 兼容,但与 5.2.1.Final
所以,我建议:
没有必要依赖hibernate-search-engine,因为这是hibernate-search-orm的依赖。
答案 1 :(得分:0)
&#34; efact&#34;属性为null,你没有注入&#34; efact&#34;通过xml(因为你的代码中没有setter或构造函数来做)并且你没有使用注释。 然后你必须在&#34; EntityManagerFactory efact&#34;上添加@Autowired。或使用xml。
答案 2 :(得分:0)
尝试在pom.xml文件中将 hibernate-core 的依赖关系从 5.2.1.Final 更改为 5.0.9.Final 。您可以在hibernate-search http://hibernate.org/search/documentation/getting-started的文档中阅读更多相关信息。祝你好运!
答案 3 :(得分:0)
hibernate-search-orm 5.5不支持Hibernate-core:5.2。
尝试更新依赖 hibernate-search-orm 。
我正在使用5.7.0.Beta2并等待稳定版本。
答案 4 :(得分:-1)
您可以使用2种方法使用Hibernate Search,使用JPA或Hibernate会话。混合它们并没有错,因为Hibernate EntityManager建立在Hibernate和Hibernate Annotations的核心之上。但是,我不建议你这样做,因为它会使情况复杂化并使学习Hibernate Search变得更加困难。
@Transactional
@Repository
public class PersonDAOImpl implements PersonDAO, Serializable {
@PersistenceUnit
private EntityManagerFactory emf;
private EntityManager em;
private FullTextEntityManager ftem;
public void createFullTextEntityManager() {
em = emf.createEntityManager();
ftem = Search.getFullTextEntityManager(em);
}
public List<Person> search(String keyword) {
// TODO your logic here with full-text entity manager ...
}
// ...
}
@Transactional
@Repository
public class PersonDAOImpl implements PersonDAO, Serializable {
@Autowired
private SessionFactory sessionFactory;
private Session session;
private FullTextSession fts;
public void createFullTextSession() {
session = sessionFactory.openSession();
fts = Search.getFullTextSession(session);
}
public List<Person> search(String keyword) {
// TODO your logic here with full-text session ...
}
// ...
}
请参阅Getting started with Hibernate Search获取complet官方教程。