Results 1 to 4 of 4

Thread: PropertyResourceConfigurer depends on another

Hybrid View

  1. #1
    Join Date
    Dec 2004
    Posts
    5

    Default PropertyResourceConfigurer depends on another

    I want to conditionally apply one properties file based on the values specified in another properties file. application.properties is meant to modified by deployers and specifies the dbType like so:
    Code:
    dbType=oracle
    Then I have properties files that define specific properties per database type, like oracle.properties:
    Code:
    hibernate.dialect=net.sf.hibernate.dialect.OracleDialect
    or mssqlserver.properties:
    Code:
    hibernate.dialect=net.sf.hibernate.dialect.SQLServerDialect
    Those properties are not included in application.properties because they are not meant to be modified by deployers and we don't want Hibernate-specific settings to be exposed.

    I want to conditionally include one of the db-specific files based on the dbType value at run-time. If dbType is oracle, include oracle.properties; if dbType is mssqlserver, mssqlserver.properties, etc. I set up my bean definitions like this:
    Code:
    <bean id="appProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location"><value>application.properties</value></property>
    </bean>
    
    <bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
        <property name="location"><value>$&#123;dbType&#125;.properties</value></property>
    </bean>
    That doesn't work the way I expected it to; the resource loader in PropertyOverrideConfigurer attempts to load a file named "${dbType}.properties", not "oracle.properties".

    The reason for this is in the method invokeBeanFactoryPostProcessors() in AbstractApplicationContext. It queries the internal bean factory for all beans of type BeanFactoryPostProcessor. The first post-processor (appProperties) runs and and correctly sets the value of the property "location" on the bean definition for "hibernateProperties" to be "oracle.properties". Then it attempts to run the second post-processor ("hibernateProperties"), but which results in a Fil. That is because the post-processor bean was instantiated before the property value was modified by the first post-processor ("appProperties").

    As a result, I cannot have a PropertyResourceConfigurer that has values set by another PropertyResourceConfigurer (either PropertyPlaceholderConfigurer or PropertyOverrideConfigurer). I investigated modifying invokeBeanFactoryPostProcessors() in AbstractApplicationContext, but any changes to the bean definition would require a full bean factory refresh to appear, which doesn't seem like a good thing. Suggestions? Thanks.

  2. #2
    Join Date
    Dec 2004
    Posts
    5

    Default

    In my particular case, I now see that I can use PropertiesFactoryBean to load the second set of properties and set those on the sessionFactory directly. It appears that I could also use PropertyPathFactoryBean to refer to the properties loaded there, but that is really clunky and I don't know if that would apply to all cases.

  3. #3
    Join Date
    Dec 2004
    Posts
    5

    Default

    Rudely replying to myself again for the benefit of anyone who encounters this need. I have a clunky but effective solution. In one application context, define the following:
    Code:
    <bean id="appPropertiesPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>application.properties</value>
        </property>
    </bean> 
    
    <bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="location">
            <value>$&#123;dbType&#125;.properties</value>
        </property>
    </bean>
    Add that as a parent context of the original context. Then in the child context, put:
    Code:
    <bean id="hibernatePropertiesOverride" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
        <property name="properties">
            <bean ref="hibernateProperties" />
        </property>
    </bean>
    I don't like this because it forces you to break off a parent context that you wouldn't otherwise have had to create. It would be nice if you could add properties to the application context itself and then the default PropertyEditor for the String class would understand how to look them up and substitute the appropriate values.

  4. #4
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    for this specific case you could also use:
    Code:
    #dbType, possible values
    #oracle&#58;     Oracle
    #mssqlserve&#58; SQLServer
    dbType=Oracle
    
    #dialect
    hibernate.dialect=net.sf.hibernate.dialect.$&#123;dbType&#125;Dialect
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

Similar Threads

  1. Why depends spring on hibernate 2.1?
    By hiberman in forum Data
    Replies: 2
    Last Post: Aug 23rd, 2005, 02:15 PM
  2. Does Spring 1.1 depends on Xerces ?
    By antonypaul in forum Container
    Replies: 7
    Last Post: Jun 3rd, 2005, 07:30 AM
  3. A depends on B depends on A
    By Edward Kenworthy in forum Container
    Replies: 4
    Last Post: Jan 23rd, 2005, 06:56 AM
  4. NameNotFoundException: ejb not bound
    By alesj in forum EJB
    Replies: 2
    Last Post: Oct 19th, 2004, 11:55 AM
  5. Replies: 6
    Last Post: Sep 7th, 2004, 12:22 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •