【发布时间】:2014-09-23 16:46:22
【问题描述】:
有谁知道如何获取 Spring Boot 创建的 Hibernate SessionFactory 的句柄?
【问题讨论】:
-
AFAIK Spring Boot 不会自动配置 Hibernate SessionFactory。它创建一个 JPA EntityManagerFactory
标签: java spring hibernate spring-boot
有谁知道如何获取 Spring Boot 创建的 Hibernate SessionFactory 的句柄?
【问题讨论】:
标签: java spring hibernate spring-boot
您可以通过以下方式完成此操作:
SessionFactory sessionFactory =
entityManagerFactory.unwrap(SessionFactory.class);
其中 entityManagerFactory 是一个 JPA EntityManagerFactory。
package net.andreaskluth.hibernatesample;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SomeService {
private SessionFactory hibernateFactory;
@Autowired
public SomeService(EntityManagerFactory factory) {
if(factory.unwrap(SessionFactory.class) == null){
throw new NullPointerException("factory is not a hibernate factory");
}
this.hibernateFactory = factory.unwrap(SessionFactory.class);
}
}
【讨论】:
SessionFactory 的创建移动到Spring @Configuration 并使用@Bean 方法来创建它可能会更好。
SessionFactory 应该是一种特殊情况(例如配置目的),因此并不简单。如果访问休眠基础设施很容易,您必须应对习惯于休眠访问SessionFactory 而不是EntityManagerFactory 的开发人员。
SessionFactory 类型的 bean(使用与您类似的代码创建)
@Bean 中使用该代码,以下是application.properties 文件中的强制spring.jpa.properties.hibernate.current_session_context_class = org.springframework.orm.hibernate5.SpringSessionContext,否则会出现:org.springframework.orm.jpa.JpaSystemException: No CurrentSessionContext configured!; nested exception is org.hibernate.HibernateException: No CurrentSessionContext configured!
自动装配 Hibernate SessionFactory 的最简单且最简洁的方法是:
这是 Spring Boot 1.x 与 Hibernate 4 的解决方案:
application.properties:
spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate4.SpringSessionContext
配置类:
@Bean
public HibernateJpaSessionFactoryBean sessionFactory() {
return new HibernateJpaSessionFactoryBean();
}
然后你可以像往常一样在你的服务中自动连接SessionFactory:
@Autowired
private SessionFactory sessionFactory;
从带有 Hibernate 5 的 Spring Boot 1.5 开始,现在这是首选方式:
application.properties:
spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate5.SpringSessionContext
配置类:
@EnableAutoConfiguration
...
...
@Bean
public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
HibernateJpaSessionFactoryBean fact = new HibernateJpaSessionFactoryBean();
fact.setEntityManagerFactory(emf);
return fact;
}
【讨论】:
伟大的工作安德烈亚斯。我创建了一个 bean 版本,以便可以自动装配 SessionFactory。
import javax.persistence.EntityManagerFactory;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
....
@Autowired
private EntityManagerFactory entityManagerFactory;
@Bean
public SessionFactory getSessionFactory() {
if (entityManagerFactory.unwrap(SessionFactory.class) == null) {
throw new NullPointerException("factory is not a hibernate factory");
}
return entityManagerFactory.unwrap(SessionFactory.class);
}
【讨论】:
@Autowired private SessionFactory sessionFactory 中并使用它。
@Configuration 类中定义此类 @Bean 定义
它适用于 Spring Boot 2.1.0 和 Hibernate 5
@PersistenceContext
private EntityManager entityManager;
然后你可以使用 entityManager.unwrap(Session.class) 来创建新的 Session
Session session = null;
if (entityManager == null
|| (session = entityManager.unwrap(Session.class)) == null) {
throw new NullPointerException();
}
示例创建查询:
session.createQuery("FROM Student");
application.properties:
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:db11g
spring.datasource.username=admin
spring.datasource.password=admin
spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
【讨论】:
另一种类似于yglodt的方式
在 application.properties 中:
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
在你的配置类中:
@Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
return hemf.getSessionFactory();
}
然后你可以像往常一样在你的服务中自动装配 SessionFactory:
@Autowired
private SessionFactory sessionFactory;
【讨论】:
如果确实需要通过@Autowire 访问SessionFactory,我宁愿配置另一个EntityManagerFactory,然后用它来配置SessionFactory bean,如下所示:
@Configuration
public class SessionFactoryConfig {
@Autowired
DataSource dataSource;
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Bean
@Primary
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource);
emf.setJpaVendorAdapter(jpaVendorAdapter);
emf.setPackagesToScan("com.hibernateLearning");
emf.setPersistenceUnitName("default");
emf.afterPropertiesSet();
return emf.getObject();
}
@Bean
public SessionFactory setSessionFactory(EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.unwrap(SessionFactory.class);
} }
【讨论】:
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
entityManagerFactory 是一个 JPA EntityManagerFactory。
【讨论】: