简体   繁体   English

无法使用Spring 5自动连接休眠5 sessionfactory

[英]Could not autowire hibernate 5 sessionfactory with spring 5

I'm trying to autowire hibernate 5 session factory bean with spring 5 in my DAO class. 我正在DAO类中尝试使用Spring 5自动连接休眠5会话工厂bean。 Maybe someone can see my mistakes here? 也许有人可以在这里看到我的错误? Tried using Hibernate 4, EntityManagerFactory but every time it's hopeless. 使用Hibernate 4,EntityManagerFactory进行了尝试,但是每次都没有希望。 Configuration class: 配置类:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"webApp"})
@EnableTransactionManagement
@PropertySource("classpath:props.dbProps.properties")
public class WebConfig implements WebMvcConfigurer {

private static final String DRIVER = "driver";
private static final String URL = "url";
private static final String USER_NAME = "name";
private static final String PASSWORD = "pass";
private static final String SCAN = "packages";
private static final String DIALECT = "dialect";
private static final String SHOW_SQL = "showSql";
private static final String HBM2DLL = "hbm2dll";

@Resource
private Environment env;

@Bean
public ViewResolver viewResolver(SpringTemplateEngine engine){
    ThymeleafViewResolver resolver = new ThymeleafViewResolver();
    resolver.setTemplateEngine(engine);
    return resolver;
}

@Bean
public SpringTemplateEngine templateEngine(SpringResourceTemplateResolver templateResolver){
    SpringTemplateEngine engine = new SpringTemplateEngine();
    engine.setTemplateResolver(templateResolver);
    return engine;
}

@Bean
public SpringResourceTemplateResolver templateResolver(){
    SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
    resolver.setPrefix("classpath:/templates/");
    resolver.setSuffix(".html");
    resolver.setTemplateMode(TemplateMode.HTML);
    return resolver;
}

@Bean
public MultipartResolver multipartResolver(){
    return new StandardServletMultipartResolver();
}

@Bean
public DataSource dataSource(){
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(env.getRequiredProperty(DRIVER));
    dataSource.setUrl(env.getRequiredProperty(URL));
    dataSource.setUsername(env.getRequiredProperty(USER_NAME));
    dataSource.setPassword(env.getRequiredProperty(PASSWORD));
    return dataSource;
}

@Bean
public LocalSessionFactoryBean getSessionFactory(){
    final LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
    lsfb.setDataSource(dataSource());
    lsfb.setPackagesToScan(env.getRequiredProperty(SCAN));
    lsfb.setHibernateProperties(hibProps());
    return lsfb;
}

@Bean
public PlatformTransactionManager transactionManager(){
    HibernateTransactionManager tx = new HibernateTransactionManager();
    tx.setSessionFactory(getSessionFactory().getObject());
    return tx;
}

private Properties hibProps(){
    Properties p = new Properties();
    p.put(DIALECT, env.getRequiredProperty(DIALECT));
    p.put(SHOW_SQL, env.getRequiredProperty(SHOW_SQL));
    p.put(HBM2DLL, env.getRequiredProperty(HBM2DLL));
    return p;
}

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if(!registry.hasMappingForPattern("/static/**")){
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/");
    }
}
}

Tried to autowire through constructor and setter - nothing helps. 试图通过构造函数和设置器自动装配-没有任何帮助。 DAO Class: DAO类:

package webApp.data;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import webApp.model.Human;

import java.util.List;

@org.springframework.stereotype.Repository
public class HumanRepositoryImpl implements Repository<Human> {

    @Autowired
    private SessionFactory sessionFactory;

    private Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public Human get(long id) {
        Human result = (Human)getSession().get(Human.class, id);
        return result;
    }

    @Override
    public Human getByName(String name) {
        Human result = (Human) getSession().createQuery("from human where name = '" + name + "'");
        return result;
    }

    @Override
    public void set(Human value) {
        getSession().save(value);
    }

    @Override
    public void update(Human value) {
        Human forUpdate = get(value.getId());
        forUpdate.setFirstName(value.getFirstName());
        forUpdate.setLastName(value.getLastName());
        forUpdate.setUsername(value.getUsername());
        forUpdate.setEmail(value.getEmail());
        forUpdate.setPassword(value.getPassword());
        getSession().update(forUpdate);
    }

    @Override
    public void delete(Human value) {
        Human forDelete = get(value.getId());
        if(forDelete != null)
            getSession().delete(forDelete);
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Human> list() {
        return getSession().createQuery("from human").list();
    }
}

Dependencies: Spring 5.0.2.Release, Hibernate 5.2.12.Final 依赖关系:Spring 5.0.2.Release,Hibernate 5.2.12.Final

Exception Stack Trace:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'humanRepositoryImpl': Unsatisfied dependency expressed through field 'sessionFactory'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.hibernate.SessionFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:758)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:409)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
    at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:890)
    at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:532)
    at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:853)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:344)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1514)
    at org.eclipse.jetty.maven.plugin.JettyWebAppContext.startWebapp(JettyWebAppContext.java:359)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1476)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:785)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:261)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545)
    at org.eclipse.jetty.maven.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:434)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:167)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131)
    at org.eclipse.jetty.server.Server.start(Server.java:449)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:105)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
    at org.eclipse.jetty.server.Server.doStart(Server.java:416)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:467)
    at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:333)
    at org.eclipse.jetty.maven.plugin.JettyRunMojo.execute(JettyRunMojo.java:180)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.hibernate.SessionFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1504)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1101)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583)
    ... 68 more

Do you add sessionfactory in database.xml file like this: 您是否像这样在database.xml文件中添加sessionfactory:

  <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
            <property name="dataSource" ref="dataSource"/>
            <property name="packagesToScan">
                <list>
                    <value>com.isgm.iis.model</value> <!-- replace with your package name -->
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                    <prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
                    <prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
                </props>
            </property>       
        </bean>

I don't think its a good design to mix up @EnableWebMvc with @EnableTransactionManagement. 我认为将@EnableWebMvc与@EnableTransactionManagement混合使用不是一个好的设计。 You should clear a separate class for Hibernate configuration in same package of class WebConfig. 您应该在WebConfig类的同一包中为Hibernate配置清除一个单独的类。 Remove the below code. 删除以下代码。

@EnableTransactionManagement
@PropertySource("classpath:props.dbProps.properties")

@Bean
public DataSource dataSource(){
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(env.getRequiredProperty(DRIVER));
    dataSource.setUrl(env.getRequiredProperty(URL));
    dataSource.setUsername(env.getRequiredProperty(USER_NAME));
    dataSource.setPassword(env.getRequiredProperty(PASSWORD));
    return dataSource;
}

@Bean
public LocalSessionFactoryBean getSessionFactory(){
    final LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
    lsfb.setDataSource(dataSource());
    lsfb.setPackagesToScan(env.getRequiredProperty(SCAN));
    lsfb.setHibernateProperties(hibProps());
    return lsfb;
}

@Bean
public PlatformTransactionManager transactionManager(){
    HibernateTransactionManager tx = new HibernateTransactionManager();
    tx.setSessionFactory(getSessionFactory().getObject());
    return tx;
}

private Properties hibProps(){
    Properties p = new Properties();
    p.put(DIALECT, env.getRequiredProperty(DIALECT));
    p.put(SHOW_SQL, env.getRequiredProperty(SHOW_SQL));
    p.put(HBM2DLL, env.getRequiredProperty(HBM2DLL));
    return p;
}

Clear a separate class like below. 清除一个单独的类,如下所示。 I have written code for Hibernate xml config, you could also config properties file. 我已经为Hibernate xml配置编写了代码,也可以配置属性文件。 Also, you haven't mentioned any class in setAnnotatedClasses method of LocalSessionFactoryBean, add those. 另外,您还没有在LocalSessionFactoryBean的setAnnotatedClasses方法中提及任何类,请添加这些类。 This configuration is recommended for Spring 5 with Hibernate 5. 对于带有Hibernate 5的Spring 5,建议使用此配置。

@Configuration
@EnableTransactionManagement
public class HibernateConfig {

    @Autowired
    private ApplicationContext context;

    @Bean
    public LocalSessionFactoryBean getSessionFactory() {
        LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
        factoryBean.setConfigLocation(context.getResource("classpath:hibernate.cfg.xml"));
        factoryBean.setAnnotatedClasses(User.class);
        return factoryBean;
    }

    @Bean
    public HibernateTransactionManager getTransactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(getSessionFactory().getObject());
        return transactionManager;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM