如何使用Hibernate SchemaExport在运行时创建数据库模式?

时间:2013-08-09 02:28:48

标签: java hibernate schema schemaexport

我尝试在我的应用中使用SchemaExport在应用程序启动时创建数据库架构。我使用的是Spring 3.2,并且已在Spring配置文件中定义了SessionFactory bean。

我试图按如下方式使用它:

@Autowired
private LocalSessionFactoryBean session;

@Override
public void buildTable() throws Exception {
    SchemaExport export = new SchemaExport(session.getConfiguration());
    export.setDelimiter(";");
    export.execute(false, true, false, true);
}

我的Spring配置文件中将LocalSessionFactoryBean定义为:

 <!-- application datasource -->
<bean id="dataSource.jndi" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
    <property name="jndiName" value="java:comp/env/jdbc/db" />
</bean>

<!-- hibernate session -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" scope="singleton">
    <property name="dataSource" ref="dataSource.jndi" />
    <property name="configLocation" value="classpath:domain/hibernate/hibernate.cfg.xml" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
        </props>
    </property>
</bean>

但是,当我尝试运行该方法时,出现以下错误:

org.hibernate.HibernateException: No local DataSource found for configuration - 'dataSource' property must be set on LocalSessionFactoryBean
    at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.configure(LocalDataSourceConnectionProvider.java:51)
    at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:143)
    at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:84)
    at org.hibernate.tool.hbm2ddl.ManagedProviderConnectionHelper.prepare(ManagedProviderConnectionHelper.java:51)
    at org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:263)

我试图跟踪问题,看起来当SchemaExport尝试将架构写入数据库时​​,它会创建一个新的LocalSessionFactory:

来自org.hibernate.connection.ConnectionProviderFactory的

(为清晰起见而编辑):

private static ConnectionProvider initializeConnectionProviderFromConfig(String providerClass) {
    ConnectionProvider connections;
        connections = (ConnectionProvider) ReflectHelper.classForName( providerClass ).newInstance();
    return connections;
}

其中providerClass = org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider

因此,它不是使用我的SessionFactory bean中定义的现有ConnectionProvider,而是尝试创建一个新的。

如何在SchemaExport中使用现有的Spring配置的SessionFactory / ConnectionProvider / Hibernate配置对象?为了在我的应用程序中使用它,我还需要设置/配置SchemaExport吗?

1 个答案:

答案 0 :(得分:0)

看起来您的dataSource设置错误。

这是一个Spring + Hibernate 3示例:http://www.cavalr.com/blog/Spring_3_and_Hibernate_4_Example

对于它的价值,在您的XML中:

<!-- hibernate session -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" scope="singleton">
    <property name="dataSource" >
        <bean id="dataSource.jndi" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
            <property name="jndiName" value="java:comp/env/jdbc/db" />
        </bean>
    </property>
    <property name="configLocation" value="classpath:domain/hibernate/hibernate.cfg.xml" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
        </props>
    </property>
</bean>

像dataSource.jndi这样的属性(内部)bean不能声明为“singleton”范围。它们是原型,如果您需要单例范围,则必须将其创建为外部bean,并使用ref标记上的property进行设置。

此外,<property name="dataSource">会调用.getDataSource(),将bean定义为dataSource.jndi并不重要。如果要在dataSource中设置jndi属性,则必须执行<property name="dataSource.jndi">之类的操作。