Java Spring启动-Hibernate SessionFactory的句柄

Java Spring启动-Hibernate SessionFactory的句柄,java,spring,hibernate,spring-boot,Java,Spring,Hibernate,Spring Boot,有人知道如何获得由Spring Boot创建的Hibernate SessionFactory的句柄吗?您可以通过以下方式实现这一点: SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class); 其中entityManagerFactory是JPAentityManagerFactory package net.andreaskluth.hibernatesample; imp

有人知道如何获得由Spring Boot创建的Hibernate SessionFactory的句柄吗?

您可以通过以下方式实现这一点:

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

}

伟大的工作,安德烈亚斯。我创建了一个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);
}

自动连接Hibernate SessionFactory的最简单、最不冗长的方法是:

这是使用Hibernate 4的Spring Boot 1.x的解决方案:

application.properties:

spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate4.SpringSessionContext
spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
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
配置类:

@Bean
public HibernateJpaSessionFactoryBean sessionFactory() {
    return new HibernateJpaSessionFactoryBean();
}
@EnableAutoConfiguration
...
...
@Bean
public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
    HibernateJpaSessionFactoryBean fact = new HibernateJpaSessionFactoryBean();
    fact.setEntityManagerFactory(emf);
    return fact;
}
@Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
    return hemf.getSessionFactory();
}
然后,您可以像往常一样在服务中自动连接
会话工厂

@Autowired
private SessionFactory sessionFactory;
@Autowired
private SessionFactory sessionFactory;
从带有Hibernate 5的Spring Boot 1.5开始,现在这是首选方式:

application.properties:

spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate4.SpringSessionContext
spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
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
配置类:

@Bean
public HibernateJpaSessionFactoryBean sessionFactory() {
    return new HibernateJpaSessionFactoryBean();
}
@EnableAutoConfiguration
...
...
@Bean
public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
    HibernateJpaSessionFactoryBean fact = new HibernateJpaSessionFactoryBean();
    fact.setEntityManagerFactory(emf);
    return fact;
}
@Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
    return hemf.getSessionFactory();
}

另一种类似于yglodt的方法

在application.properties中:

spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate4.SpringSessionContext
spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
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
在您的配置类中:

@Bean
public HibernateJpaSessionFactoryBean sessionFactory() {
    return new HibernateJpaSessionFactoryBean();
}
@EnableAutoConfiguration
...
...
@Bean
public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
    HibernateJpaSessionFactoryBean fact = new HibernateJpaSessionFactoryBean();
    fact.setEntityManagerFactory(emf);
    return fact;
}
@Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
    return hemf.getSessionFactory();
}
然后,您可以像往常一样在服务中自动连接SessionFactory:

@Autowired
private SessionFactory sessionFactory;
@Autowired
private SessionFactory sessionFactory;

它适用于SpringBoot2.1.0和Hibernate5

@PersistenceContext
private EntityManager entityManager;
然后可以使用entityManager.unwrap(Session.class)创建新会话

创建查询的示例:

session.createQuery("FROM Student");
application.properties:

spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate4.SpringSessionContext
spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate5.SpringSessionContext
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
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

如果确实需要通过@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

AFAIK Spring Boot不会自动配置Hibernate SessionFactory。它创建了一个JPA EntityManagerFactory。如果您将
会话工厂的创建移动到Spring
@Configuration
中,并创建一个
@Bean
方法来创建它,可能会更好。@geo这里没有创建任何东西:-)。访问基础的
SessionFactory
应该是一种特殊情况(例如配置目的),因此并不简单。如果很容易访问hibernate基础设施,那么您必须与使用hibernate访问
SessionFactory
而不是
EntityManagerFactory
的开发人员打交道。我想说的是,最好有一个
SessionFactory
类型的bean(使用与您类似的代码创建)如果需要多个places@geoand由于Hibernate 5.2 SessionFactory扩展了EntityManagerFactory。如果在社区中使用ItTyMaldEx工厂的绑定,您会考虑问题。对于社区,我使用代码< >代码> bean Bean /Code >,下面是强制性的<代码> Spring .jPA.Hybalnt.CurrnTysStutsOracle类= Org.Spring Frask.Orm HiBurnTe5.5. Spring Script上下文
<代码>应用程序。否则显示:
org.springframework.orm.jpa.JpaSystemException:未配置CurrentSessionContext!;嵌套异常为org.hibernate.HibernateException:未配置CurrentSessionContext我在哪里创建了这个bean?你需要一个SessionFactory:)你能把你的问题说得更清楚吗?正如Andreas的回答所示,只需将这个代码添加到@Component类,它本质上是一个服务类。它去哪里并不重要——任何弹簧连接的组件。通过这种方式,您可以将其包含在
@Autowired private SessionFactory SessionFactory
中并使用它。谢谢,您如何使用此SessionFactory创建新会话?@obesechicken13作为最佳实践@Bean定义,可以在
@配置
类中定义这些定义,作为补充说明,所谓的配置调用是指@SpringBootApplication调用应用程序。您可以将此方法粘贴到main方法之上。是否有任何方法可以在此处获取SessionFactoryBean?我需要从hibernate配置中访问hibernate映射噢,不用担心,我看到我可以将SessionFactory强制转换为映射,它可以工作我的SessionFactory返回null。有什么建议吗?HibernateJPASionFactoryBean现在已被删除有什么方法可以在这里获取SessionFactoryBean吗?我需要从hibernate配置中访问hibernate映射因此,这种方法在最新的spring boot中对我不起作用,说没有HibernateEntityManager Factory的实例可用,我可以看出,我可以将SessionFactory强制转换为MappingHibernateEntityManagerFactory现在已经被弃用了;创建查询等。。而且如果您深入研究这些方法的实现。entityManager本身正在将请求移交给会话实现类。因此,我在发布一个特定的版本后,对这个问题进行了讨论。Hibernate的家伙故意使会话访问变得困难,但使用实体管理器进行会话操作。我读了一些关于这个的东西,但是没有直接找到它。这个示例的Thx是唯一一个能够获得有效(而不是不推荐的)会话的!(在Spring Boot 2.2和Hibernate5中)这复制了接受的答案。当你发布一个答案的时候,应该是因为你有一些东西可以回答这个问题,但是没有任何现有的答案。
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);
  }

}