SpringMVC转SpringBoot 2.x Hibernate 获取SessionFactory

如果可以改动代码,可以直接更改获取Session的方式,如果不方便改动代码,就配置Bean。

直接获取Session

可以直接更改获取Session的代码:

    @Autowired
    private EntityManagerFactory entityManagerFactory;

    public Session getSession() {
        return entityManagerFactory.unwrap(SessionFactory.class).getCurrentSession();
        // 或
        //return entityManagerFactory.unwrap(SessionFactory.class).openSession();
    }

getCurrentSession需配置current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext,且需要声明事务,openSession需要手动关闭Session。

SpringData JPA支持配置

Hibernate5.2.x以上版本:

@Configuration
@EnableTransactionManagement
public class HibernateConfig {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private JpaProperties jpaProperties;

    @Primary
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(dataSource)
                .properties(jpaProperties.getProperties())
                .packages("com.demo.entity")    // 设置实体类
                .build();
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactory(builder).getObject());
    }

    @Bean
    public SessionFactory sessionFactory(@Qualifier("entityManagerFactory") EntityManagerFactory emf){
        return emf.unwrap(SessionFactory.class);
    }
}

Hibernate5.2版本改动较大,建议旧版代码使用5.2以下版本,可以在pom.xml中指定Hibernate的版本:

	<properties>
        // other...
        <hibernate.version>5.0.12.Final</hibernate.version>
	</properties>
	
	<dependencies>
	    // other...
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
   </dependencies>

配置SessionFactory:

@Configuration
@EnableTransactionManagement
public class HibernateConfig {

    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Bean
    public SessionFactory sessionFactory() {
        if (entityManagerFactory.unwrap(SessionFactory.class) == null) {
            throw new NullPointerException("factory is not a hibernate factory");
        }
        return entityManagerFactory.unwrap(SessionFactory.class);
    }
}

使用方法:

    @Autowired
    private SessionFactory sessionFactory;

非SpringData JPA支持配置

@Configuration
public class HibernateConfig {

    @Autowired
    private DataSource dataSource;

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
        localSessionFactoryBean.setDataSource(dataSource);

        Properties properties = new Properties();
        properties.put("hibernate.dialect","org.hibernate.dialect.MySQL5Dialect");
        properties.put("hibernate.show_sql", "true");
        properties.put("hibernate.hbm2ddl.auto","none");
        properties.put("hibernate.current_session_context_class","org.springframework.orm.hibernate5.SpringSessionContext");
        localSessionFactoryBean.setPackagesToScan("com.demo.entity");
        localSessionFactoryBean.setHibernateProperties(properties);

        return localSessionFactoryBean;
    }
}

使用方法:

    @Autowired
    private SessionFactory sessionFactory;

getCurrentSession非事务读数据库

旧版SpringMVC代码使用getCurrentSession来获取Session,这样不用手动去关闭Session,但是这种方式访问数据库都必须配置事务,不配置事务会出现错误:Could not obtain transaction-synchronized Session for current thread。然而所有方法都配置事务,如果使用了数据库读写分离中间件(如阿里的PolarDB),则无法分流到只读数据库。这种情况下可配置OpenSessionInViewFilter来使Controller在没有配置事务的情况下读取数据库。

@WebFilter(filterName="openSessionFilter",urlPatterns="/*")
@Order(1)
public class OpenSessionFilter implements Filter {

    private final OpenSessionInViewFilter filter;

    public OpenEntityManagerInViewFilter() {
        filter = new OpenSessionInViewFilter();
        filter.setSessionFactoryBeanName("sessionFactory");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        filter.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        filter.doFilter(request, response, chain);
    }

    @Override
    public void destroy() {
        filter.destroy();
    }
}

在启动类添加注解@ServletComponentScan

@ServletComponentScan(basePackages = {"com.demo.filter"})
@SpringBootApplication
public class WebApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值