需要一个无法找到的“org.hibernate.SessionFactory"类型的 bean [英] required a bean of type 'org.hibernate.SessionFactory' that could not be found

查看:16
本文介绍了需要一个无法找到的“org.hibernate.SessionFactory"类型的 bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当启动应用程序 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

  1. 混合来自不同 Spring 和 Hibernate 版本的 jar
  2. 也可能已经管理了依赖项
  3. 努力比 Spring Boot 更聪明.

对于 1. 和 2. 只需删除 spring-ormhibernate-core 标记>hibernate-entitymanager 管理器依赖项.Spring Boot 已经在管理这些.您实际上可以删除所有 org.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 方法(findOnefindAllsave 等)都为您提供,无需您创建一个实现.

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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆