需要一个无法找到的“org.hibernate.SessionFactory"类型的 bean [英] required a bean of type 'org.hibernate.SessionFactory' that could not be found
问题描述
每当启动应用程序 spring 启动时,我都会收到以下错误.
应用程序无法启动
说明:
com.base.model.AbstractDao 中的字段会话需要一个无法找到的org.hibernate.SessionFactory"类型的 bean.
Field session in com.base.model.AbstractDao required a bean of type 'org.hibernate.SessionFactory' that could not be found.
操作:
考虑在您的配置中定义一个org.hibernate.SessionFactory"类型的 bean.
Consider defining a bean of type 'org.hibernate.SessionFactory' in your configuration.
我已经添加了我的应用程序的实现:
I have added implementation of my application:
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>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.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-web</artifactId>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Hibernate dependency -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.5.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
应用程序属性
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username = root
spring.datasource.password = root
hibernate.dialect = org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
配置类
@Configuration
@EnableTransactionManagement
@ComponentScan({"configure"})
@PropertySource({"classpath:application.properties"})
public class HibernateConfiguration {
@Autowired
private Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory(){
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[]{"com.base","com.base.model"});
sessionFactory.setMappingResources(new String[]{"Employee.hbm.xml"});
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hiberante.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
return properties;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.userName"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
@Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf){
return hemf.getSessionFactory();
}
}
Employee.java
public class Employee implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private int id;
private String name;
private String country;
public int getId(){
return this.id;
}
public void setId(int id){
this.id = id;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public void setCountry(String country){
this.country = country;
}
public String getCountry(){
return this.getCountry();
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", country="
+ country + "]";
}
}
Employee.hbm.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.base.model.Employee" table="Person">
<id name="id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name" not-null="true"></column>
</property>
<property name="country" type="java.lang.String">
<column name="country"></column>
</property>
</class>
</hibernate-mapping>
EmployeeDaoImpl
@Component
public class EmployeeDataDaoImpl {
@Autowired
SessionFactory sessionFactory;
public List<Employee> findAllEmployee(){
//// Criteria cri = getSession().createCriteria(Employee.class);
// List<Employee> dbList = cri.list();
// for (Employee employee : dbList) {
// System.out.println(employee.getCountry());
// }
return null;
}
}
我在 stackoverflow 上查找了相同的错误代码,但没有一个解决方案有效,因此用我的代码再次发布在这里.希望其他人能指出我哪里出错了.
I have looked up the same error code on stackoverflow but none of the solutions worked and thus posting it here again with my code. Hoping someone else can point out where I am going wrong.
推荐答案
对于初学者来说,您的配置有一些事情
For starters there are a couple of things of with your configuration
- 混合来自不同 Spring 和 Hibernate 版本的 jar
- 也可能已经管理了依赖项
- 努力比 Spring Boot 更聪明.
对于 1. 和 2. 只需删除 spring-orm
和 hibernate-core
和 的
管理器依赖项.Spring Boot 已经在管理这些.您实际上可以删除所有
标记>hibernate-entitymanagerorg.springframework
依赖项,这些依赖项已经被 starters 引入(实际上也包括 hibernate 依赖项).
For 1. and 2. just remove the <version>
tag for spring-orm
and the hibernate-core
and hibernate-entitymanager
manager dependencies. Spring Boot is already managing those. You can actually remove all the org.springframework
dependencies those are already pulled in by the starters (and actually the hibernate ones also).
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
接下来在您的配置中,您至少配置了 2 个 SessionFactory
.我建议使用注释来定义您的实体而不是 hbm.xml
文件.
Next in your configuration you have at least 2 SessionFactory
's configured. I would suggest to use annotations to define your entities instead of hbm.xml
files.
@Entity
@Table("person")
public class Employee implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private int id;
@Column(nullable=false)
private String name;
private String country;
}
当使用 JPA 注释时,Hibernate 会自动检测你的实体(特别是与 Spring Boot 结合),这使得它非常强大.当然,您现在可以删除您的 Employee.hbm.xml
.
When using JPA annotations Hibernate will automatically detect your entities (especially combined with Spring Boot) which makes it very powerful. Ofcourse you can now remove your Employee.hbm.xml
.
接下来你的 EmployeeDataDaoImpl
我强烈建议使用普通的 JPA 而不是普通的 Hibernate.通常,这为您提供了足够的工作.
Next your EmployeeDataDaoImpl
I strongly suggest to use plain JPA over plain Hibernate. Generally that provides enough for you to work with.
@Repository
public class EmployeeDataDaoImpl {
@PersistenceContext
private EntityManager entityManger;
public List<Employee> findAllEmployee(){
return em.createQuery("select e from Employee e", Employee.class).getResultList();
}
}
通过这种设置,您基本上可以完全删除您的HibernateConfiguration
.是的,你可以,因为 Spring Boot 检测到 Hibernate 并自动创建一个 JpaTransactionManager
,启用事务并预配置一个 EntityManagerFactory
.
With this setup you can basically completely remove your HibernateConfiguration
. Yes you can as Spring Boot detects Hibernate and automatically creates a JpaTransactionManager
, enables transactions and preconfigured a EntityManagerFactory
.
如果您真的想使用带有 SessionFactory
的普通休眠,只需使用 HibernateJpaSessionFactoryBean
来公开 EntityManagerFactory 的底层
SessionFactory
代码>.
If you really want to use plain hibernate with a SessionFactory
just use a HibernateJpaSessionFactoryBean
to expose the underlying SessionFactory
of the EntityManagerFactory
.
@Bean
public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
HibernateJpaSessionFactoryBean factory = new HibernateJpaSessionFactoryBean();
factory.setEntityManagerFactory(emf);
return factory;
}
然而,正如前面提到的,我强烈建议使用普通 JPA,因为它更容易设置,而且在 JPA 的当前状态下,它提供的功能几乎与普通 Hibernate 一样多.
However as mentioned I would strongly suggest to use plain JPA as that is a lot easier to setup and with the current state of JPA it offers almost as much of the functionality as plain Hibernate does.
专业提示您依赖于 spring-boot-starter-data-jpa
这意味着您依赖于 Spring Data JPA.如果您使用 JPA,这将使事情变得更加容易.您可以删除 EmployeeDataDaoImpl
并创建一个接口并使用它.
Pro Tip
You have a dependency on spring-boot-starter-data-jpa
which means you are having a dependency on Spring Data JPA. Which would make things even easier if you would use JPA. You can remove your EmployeeDataDaoImpl
and just create an interface and use that.
public interface EmployeeRepository extends JpaRepository<Employee, Long> {}
就是这样,所有 CRUD 方法(findOne
、findAll
、save
等)都为您提供,无需您创建一个实现.
That is it, all the CRUD methods (findOne
, findAll
, save
etc.) are provided for you without you having to create an implementation.
这篇关于需要一个无法找到的“org.hibernate.SessionFactory"类型的 bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!