web-dev-qa-db-fra.com

requis un bean de type 'org.hibernate.SessionFactory' introuvable

J'obtiens l'erreur suivante à chaque démarrage de l'application au printemps.


LA DEMANDE N'A PAS ÉTÉ DEMARRÉE


La description:

La session de terrain dans com.base.model.AbstractDao nécessitait un bean de type 'org.hibernate.SessionFactory' introuvable.

Action:

Pensez à définir un bean de type 'org.hibernate.SessionFactory' dans votre configuration.

J'ai ajouté l'implémentation de mon 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>

application.property

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

classe de configuration

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

}

J'ai recherché le même code d'erreur sur stackoverflow mais aucune des solutions n'a fonctionné et l'affiche donc ici à nouveau avec mon code. En espérant que quelqu'un d'autre puisse montrer où je me trompe.

7
kapil joshi

Pour commencer, il y a quelques choses avec votre configuration

  1. Pots de mélange de différentes versions Spring et Hibernate
  2. Trop de dépendances déjà gérées
  3. Essayer d'être plus intelligent que Spring Boot.

Pour 1. et 2. retirez simplement le <version> tag pour spring-orm et le hibernate-core et hibernate-entitymanager dépendances du gestionnaire. Spring Boot les gère déjà. Vous pouvez réellement supprimer tous les org.springframework les dépendances qui sont déjà récupérées par les démarreurs (et en fait aussi les hibernants).

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

Ensuite, dans votre configuration, vous avez configuré au moins 2 SessionFactory. Je suggère d'utiliser des annotations pour définir vos entités au lieu de hbm.xml des dossiers.

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

}

Lorsque vous utilisez des annotations JPA, Hibernate détectera automatiquement vos entités (en particulier combinées avec Spring Boot), ce qui le rend très puissant. Bien sûr, vous pouvez maintenant supprimer votre Employee.hbm.xml.

Ensuite, votre EmployeeDataDaoImpl je suggère fortement d'utiliser JPA ordinaire sur Hibernate ordinaire. Généralement, cela vous permet de travailler avec.

@Repository
public class EmployeeDataDaoImpl  {


    @PersistenceContext
    private EntityManager entityManger;


    public List<Employee> findAllEmployee(){
        return em.createQuery("select e from Employee e", Employee.class).getResultList();
    }
}

Avec cette configuration, vous pouvez essentiellement supprimer complètement votre HibernateConfiguration. Oui, car Spring Boot détecte Hibernate et crée automatiquement un JpaTransactionManager, active les transactions et préconfigure un EntityManagerFactory.

Si vous voulez vraiment utiliser hibernate ordinaire avec un SessionFactory utilisez simplement un HibernateJpaSessionFactoryBean pour exposer le SessionFactory sous-jacent du EntityManagerFactory.

@Bean
public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
    HibernateJpaSessionFactoryBean factory = new HibernateJpaSessionFactoryBean();
    factory.setEntityManagerFactory(emf);
    return factory;
}

Cependant, comme mentionné, je suggérerais fortement d'utiliser JPA ordinaire car c'est beaucoup plus facile à configurer et avec l'état actuel de JPA, il offre presque autant de fonctionnalités que Hibernate ordinaire.

Astuce Pro Vous avez une dépendance sur spring-boot-starter-data-jpa ce qui signifie que vous dépendez de Spring Data JPA. Ce qui rendrait les choses encore plus faciles si vous utilisiez JPA. Vous pouvez supprimer votre EmployeeDataDaoImpl et simplement créer une interface et l'utiliser.

public interface EmployeeRepository extends JpaRepository<Employee, Long> {}

C'est tout, toutes les méthodes CRUD (findOne, findAll, save etc.) vous sont fournies sans que vous ayez à créer une implémentation.

13
M. Deinum

Votre configuration SessionFactory est incorrecte. À partir de votre pom.xml, je vois que vous utilisez la mise en veille prolongée version 5, donc votre configuration devrait être:

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

Et vous avez également différentes versions de pots d'hibernation dans votre pom.xml, essayez d'utiliser les mêmes versions.

3