6

我将 Hibernate 与 Spring 结合使用。作为数据库,我目前正在使用 HSQL,它将其数据存储在一个文件中(如 SQLite)。HSQL 文件的路径当前硬编码在 persistence.xml 中。如何在运行时访问和更改此值,以便用户可以从/向任意 HSQL 文件加载和保存?

持久性.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                                 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">

    <persistence-unit name="something-unit">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <properties>
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
            <property name="hibernate.connection.url" value="jdbc:hsqldb:file:~/something-db/somethingdb" />
            <property name="hibernate.connection.username" value="sa" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>

</persistence>

春天应用上下文.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:data="http://www.springframework.org/schema/data/jpa"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
               http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-2.5.xsd
               http://www.springframework.org/schema/data/jpa
               http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
               http://www.springframework.org/schema/tx
               http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">


    <!-- Database Setup -->

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="something-unit" />
    </bean>

    <data:repositories base-package="com.something.playlist"/>

    <!-- Transaction Setup -->

    <tx:annotation-driven/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

</beans>

感谢您的任何提示!

4

3 回答 3

3

您可以指定一个 JNDI 数据源并将其传递给 Hibernate。或者您可以通过实现接口 org.hibernate.connection.ConnectionProvider 来定义自己的插件策略来获取 JDBC 连接

有关更多提示,请参阅:http ://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html

编辑 2/16: StackOverflow 上有一个关于创建自定义 ConnectionProvider 的示例:如何在创建 Hibernate SessionFactory 时设置数据源?

如果您要即时更改数据源,而不是在启动时更改,则必须重新启动 Hibernate 会话工厂。要正确执行此操作,您必须确保在重新启动时没有任何事务在其中运行。以下问题/答案将帮助您:Hibernate Sessionfactory restart | 春天

于 2013-02-13T20:25:43.870 回答
1

一种常用的策略是在一个或多个 *.properties 文件中定义所有运行时配置,并使用 spring 的 PropertyPlaceholderConfigurer 加载值并替换 applicationContext.xml 中的占位符,在此处阅读更多信息:Bestways to deal with properties values in XML file in Spring、Maven 和 Eclipse

应用程序属性:

# Dadabase connection settings:
hibernate.connection.driver_class=org.hsqldb.jdbcDriver
hibernate.connection.url=jdbc:hsqldb:file:~/something-db/somethingdb
hibernate.connection.username=sa
hibernate.connection.password=changeit
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hbm2ddl.auto=update
... ...

applicationContext-dataStore.xml:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
    <list>
      <!-- Default location inside war file -->
      <value>classpath:app.properties</value>
      <!-- Environment specific location, a fixed path on deployment server -->
      <value>file:///opt/my-app/conf/app.properties</value>
    </list>
  </property>
  <property name="ignoreResourceNotFound" value="true"/>
</bean>

... ...

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="${hibernate.connection.driver_class}" />
  <property name="url" value="${hibernate.connection.url}" />
  <property name="username" value="${hibernate.connection.username}" />
  <property name="password" value="${hibernate.connection.password}" />
</bean>

这里的一个问题是PropertyPlaceholderConfigurer 不解析persistence.xml,解决方案是将所有hibernate 配置移动到Spring 的applicationContext.xml 中,因为没有必要在persistence.xml 中设置它们。在此处阅读更多内容:在 spring-context.xml 和 persistence.xml 中加载 .properties

持久性.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
  <persistence-unit name="JPAService" transaction-type="RESOURCE_LOCAL"/>
</persistence>

applicationContext-datSource.xml:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="${hibernate.connection.driver_class}"/>
  <property name="url" value="${hibernate.connection.url}"/>
  <property name="username" value="${hibernate.connection.username}"/>
  <property name="password" value="${hibernate.connection.password}"/>
</bean>

... ...

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
  <property name="persistenceXmlLocation" value="classpath:./META-INF/persistence.xml"/>
  <property name="persistenceUnitName" value="JPAService"/>
  <property name="dataSource" ref="dataSource"/>

  <property name="jpaVendorAdapter"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
          <property name="databasePlatform" value="${hibernate.dialect}"/> 
          <property name="showSql" value="true" /> 
          <property name="generateDdl" value="true"/>
      </bean> 
  </property>
  <property name="jpaProperties">
    <!-- set extra properties here, e.g. for Hibernate: -->
    <props>
      <prop key="hibernate.hbm2ddl.auto">${hbm2ddl.auto}</prop>
    </props>
  </property>
</bean>

请注意,每次更改 /opt/my-app/conf/app.properties 中的配置时都需要重新启动 Web 应用程序,以使更改生效。

希望这可以帮助。

于 2013-02-17T22:07:57.323 回答
1

如果您希望通过 JPA 抽象使用休眠,您可以编写您的代码或服务以使用 javax.persistence.EntityManagerFactory。自动装配其中之一并调用 createEntityManager(Map map); 您可以在地图中提供数据源。您可以使用自己的实现包装实体管理器,该实现将参数从线程本地拉出以创建数据源。

编辑:误读上下文并看到您正在使用 EntityManagerFactory。在这种情况下,只需阅读最后一部分,您使用委托从线程本地创建正确的数据源来包装工厂。

于 2013-02-18T14:48:11.807 回答