Кто-нибудь знает, как получить дескриптор Hibernate SessionFactory, созданный Spring Boot?
Spring Загрузка - обращение к спящему SessionFactory
Ответ 1
Вы можете выполнить следующее:
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);
}
}
Ответ 2
Самый простой и наименее подробный способ автоматического подключения вашей 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;
Начиная с Spring Boot 1.5 с Hibernate 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;
}
Ответ 3
Отличная работа Андреаса. Я создал версию 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);
}
Ответ 4
Другой способ, подобный ypodt's
В application.properties:
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
И в вашем классе конфигурации:
@Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
return hemf.getSessionFactory();
}
Затем вы можете autwire SessionFactory в своих сервисах, как обычно:
@Autowired
private SessionFactory sessionFactory;
Ответ 5
Работает с Spring Boot 2.1.0 и Hibernate 5
@PersistenceContext
private EntityManager entityManager;
Затем вы можете создать новый сеанс с помощью entityManager.unwrap(Session.class)
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
Ответ 6
Если действительно требуется доступ к SessionFactory через @Autowire, я бы лучше настроил другой EntityManagerFactory, а затем использовал его для настройки bean-компонента SessionFactory, например:
@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);
} }
Ответ 7
Если действительно требуется доступ к hibernate SessionFactory через @Autowire, я бы лучше сначала сконфигурировал другой bean-объект EntityManagerFactory (чтобы обойти проблему циклической ссылки и исключение создания bean-компонента), а затем сконфигурировал bean-компонент SessionFactory, выполнив следующие действия:
@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);
}
}