Hibernate JTA:读取每个环境的数据库连接参数

时间:2015-10-16 08:48:21

标签: java hibernate jpa jta

我正在编写一个使用hibernate的javaEE应用程序。该应用程序将在多个环境(dev,qa,prod等)上运行。将具有与它们中的每一个相关联的单独的dbs。我想为每个环境分别设置jdbc-url,username,password等hibernate属性。

我当前的persistence.xml看起来像是:

    <persistence-unit name="PU" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <validation-mode>CALLBACK</validation-mode>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
            <property name="hibernate.hbm2ddl.auto" value="validate" />

            <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
            <property name="hibernate.event.merge.entity_copy_observer" value="allow"/>

            <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
            <property name="hibernate.connection.url" value="jdbc:oracle:thin:@host/schema"/>

            <property name="hibernate.connection.username" value="abc"/>
            <property name="hibernate.connection.password" value="***"/>    

        </properties>
    </persistence-unit>

我在我的java代码中使用了持久性单元:

@PersistenceContext(unitName = "PU")
private EntityManager em; 

有没有办法可以将存储在不同属性文件中的hibernate属性注入到不同环境的EntityManager中?

请注意我使用的是JTA,因此无法使用EntityManagerFactory。我也不是&amp;不想用春天。

5 个答案:

答案 0 :(得分:5)

BAAAAAAD的想法是在您的应用程序WAR / EAR包中包含特定于环境的信息(通过包含多个配置,或者为不同的环境创建不同的包)。例如,应在容器中维护不同的数据库。

在您的情况下,您的persistence.xml应如下所示:

<persistence>
   <persistence-unit name="PU">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>jdbc/fooAppDs</jta-data-source>
      <properties>
         ... ...
      </properties>
   </persistence-unit>
</persistence>

当然你应该为jdbc/fooAppDs提供相应的资源参考。

通过这样做,您可以在任何环境中部署应用程序。您只需在容器中创建正确的数据源并将其分配给jdbc/fooAppDs

我认为另一种方法可行,但我不建议,是在类路径中创建hibernate.cfg.xml。您可能希望拥有本地文件系统位置并将其添加到类路径中,而不是将文件放在JAR / WAR / EAR中。

答案 1 :(得分:1)

由于您不想使用Spring等外部库来引导持久性单元,为什么不使用构建系统来执行此操作。如果你正在使用maven,你可以使用maven filteringprofiles的混合来基于属性文件进行过滤,或者如果你使用任何其他构建工具,你可以添加一个任务(或等效的)来复制根据某些外部系统/环境变量将文件内容从不同文件归档到实际文件。

答案 2 :(得分:1)

我们在不同文件中使用DEV,QA,PROD,UAT等每个环境的维护属性文件,并在构建期间复制其中一个。

Ant build

<property environment="env" /> 
                <!-- ***** COMMAND LINE ARGUMENTS DEMOED HERE -->
                <property name="build_type" value= "${env.build_type}"/>

<copy todir="deploy">
    <fileset dir="src_dir"/>
    <globmapper from=${env.build_type}".persistence.xml" to="persistence.xml"/>
 </copy>

像这样运行构建

ant -Denv.build_type=PROD

这会将PROD.persistence.xml复制到persistence.xml

ant -Denv.build_type=DEV

这会将DEV.persistence.xml复制到persistence.xml

答案 3 :(得分:0)

使用Spring Profile,您可以启动实体管理器bean,具体取决于将引用环境dev-persistence.xml, test-persisitence.xml, prod-persistence.xml等persistence.xml的活动配置文件。您可以使用web.xml设置Active配置文件。大多数情况下,web.xml不会发生太大变化,因此您可以使用为该环境设置的spring profile活动属性将web.xml保留在您的存储库中。

答案 4 :(得分:0)

您可以将spring-config.xml文件配置为以下

  
      
  1. MYSQL
  2.   
<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/kaya_db" />
    <property name="username" value="root" />
    <property name="password" value="nxtlife" />
</bean>
<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="packagesToScan" value="com.nxtlife.model" />
    <property name="hibernateProperties">

        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
</bean>
<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager"
    p:sessionFactory-ref="sessionFactory">
</bean>
  

2.类似于其他数据库,如oracle,postgre,具有不同的datasource名称,sessionfactory和transactionmanager。   3.最后,您可以使用以下sessionfactory名称获取会话工厂的对象

@Modifier("sessionfactoryname")
@Autowired
private SessionFactory obj;

类似于不同的数据库