SB - 如何向 LocalSessionFactoryBuilder 提供 hibernate.cfg.xml 文件?

SB - How to provide a hibernate.cfg.xml file to a LocalSessionFactoryBuilder?

简介

我正在尝试将工作 XML 配置的 spring 批处理作业转换为 javaconfig,我 运行 在设置会话时遇到了一些问题。我想使用hibernate.cfg.xml文件来配置连接(我也在其他地方使用它,所以我需要保留它)。

给定

有效的 xml 配置如下所示:

<!-- Standard Spring Hibernate Reader -->
<bean id="hibernateItemReader" class="org.springframework.batch.item.database.HibernateCursorItemReader" scope="step">
    <property name="sessionFactory" ref="sessionFactory" />         
    <property name="queryString" value="#{jobExecutionContext[HQL]}" />
    <property name="useStatelessSession" value="false"/>            
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" lazy-init="true">
    <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
    <property name="cacheableMappingLocations" value="classpath*:META-INF/mapping/*.hbm.xml"/>
</bean>

hibernate.cfg.xml 如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <!-- Connection to database  --> 
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/SAKILA</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">****</property>    

    <!-- Conversion from HQL to SQL in log -->
    <property name="show_sql">false</property>
    <property name="format_sql">true</property>
    <property name="use_sql_comments">true</property>    

    <!-- Session and pool settings -->
    <property name="hibernate.current_session_context_class">thread</property>
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
    <property name="hibernate.c3p0.timeout">1800</property>
    <property name="hibernate.c3p0.idle_test_period">1000</property>
    <property name="hibernate.c3p0.max_statements">50</property>    
  </session-factory>
</hibernate-configuration>

以下java配置..

@Bean
@Lazy(true)
public SessionFactory sessionFactory(){
    LocalSessionFactoryBean session = new LocalSessionFactoryBean();
    session.setConfigLocation(hibernateConfig());
    session.setCacheableMappingLocations(mappings());  
    return session.getObject();
}

@Bean
@StepScope
public HibernateCursorItemReader reader(@Value("#{jobExecutionContext[HQL]}") String HQLQuery){     
    HibernateCursorItemReader reader = new HibernateCursorItemReader<>();
    reader.setSessionFactory(sessionFactory());
    reader.setQueryString(HQLQuery);
    reader.setUseStatelessSession(false);
    return reader;
}

问题

reader.setSessionFactory(sessionFactory());

投掷: Caused by: java.lang.IllegalStateException: A SessionFactory must be provided

经过一些研究,我认为我需要使用 LocalSessionFactoryBuilder 而不是 LocalSessionFactoryBean。

@Autowired
@Bean
public SessionFactory sessionFactory2(){
    LocalSessionFactoryBuilder sessionBuilder  = new LocalSessionFactoryBuilder(dataSource());
    // ?? sessionBuilder.setConfigLocation(); ?? 
    sessionBuilder.addDirectory(new File(url.toURI()));
} 

但是,我不想提供数据源,因为我在 hibernate.cfg.xml 文件中配置了所有数据源连接信息。

How to make hibernate.cfg.xml to a datasource bean 上接受的答案建议保留 hibernate.cfg.xml 文件并添加 Spring 配置。

如何将 hibernate.cfg.xml 文件添加到 LocalSessionFactoryBuilder?

我明白了。我根本不想使用 LocalSessionFactoryBuilder。在我的程序中,我有以下 class:

public class HibernateUtil {    

    private static final SessionFactory SESSIONFACTORY = buildSessionFactory();
    private static final String HIBERNATE_CONFIGURATION_LOCATION = "hibernate.cfg.xml";  
    private static final String MAPPINGS_LOCATION = "src/main/resources/mappings";
    private static ServiceRegistry serviceRegistry;

    private static SessionFactory buildSessionFactory() {
        try {
            Configuration configuration = new Configuration();
            configuration.configure(HIBERNATE_CONFIGURATION_LOCATION).addDirectory(new File(MAPPINGS_LOCATION));
            serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
            SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            return sessionFactory;          
        } catch (Exception e) {
            System.err.println("Initial SessionFactory creation failed." + e);
            throw new ExceptionInInitializerError(e);
        }
    }

    public static SessionFactory getSessionFactory(){
        return SESSIONFACTORY;
    }

    public static void shutdown(){
        getSessionFactory().close();
    }   
}

调用 reader.setSessionFactory(HibernateUtil.getSessionFactory()); 对我有用!