开发者

Update database settings in properties file in Spring

I am new to spring I am trying to create a Database Manager page which shows the database details on page load and updates the database settings when the user press submit

I followed this tutorial and set the database settings in properties file.

I managed to update the database settings in properties file programmatically. When I retrieved the database settings using the following code

DriverManagerDataSource databaseSource = (DriverManagerDataSource)context.getBean("dataSource");
databaseSource.getUsername();

I managed to get the old value and unable to get the new value

This is the mapping in applicationContext.xml file

<bean
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

    <property name="location">
        <value>classpath:/bundle/database.properties</value>
    </property>
</bean>

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">

    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

I checked the properties file and found it to be updated with the latest input.

What am I missing?

Thanks in advance

P.S I am using JSF1.2 with Spring 3

Update

Just making my requirement simple. I am creating a setparate dbsettings page, so that when user wishes to connect to different database he/she can just enter the details in dbsettings page and connect

Update

I used this code to retrieve the application context

private ApplicationContext context;

....

ServletContext servletContext = FacesUtil.getServletContext();
    this.context = WebApplicationContextUtils
            .getRequiredWebApplicationContext(servletContext);

If I change it into AbstractApplicationContext what change do I need in the above code?

UPDATE

this.context = (AbstractApplicationContext)WebApplicationContextUtils
            .getRequiredWebApplicationContext(servletContext);
    String valueForTheProperty = "";


    context.refresh();

When I add the lines above I am getting

org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.NullPointerException
org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:599)
org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:377)
org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:263)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
$Proxy1.getDatabasePasswordFromSettings(Unknown Source)
com.smartcall.delegate.DbSettingsDelegate.getDatabasePassswordFromSettings(DbSettingsDelegate.java:38)
com.smartcall.bean.DbSettingsBean.loadDatabaseSettings(DbSettingsBean.java:49)
com.smartcall.bean.DbSettingsBean.<init>(DbSettingsBean.java:41)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
java.lang.Class.newInstance0(Class.java:355)
java.lang.Class.newInstance(Class.java:308)
com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:185)
com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:368)
com.sun.faces.mgbean.BeanManager.create(BeanManager.java:230)
com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:86)
javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:68)
org.apache.el.parser.AstValue.getValue(AstValue.java:112)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
com.sun.faces.application.ApplicationImpl.createComponent(ApplicationImpl.java:246)
com.sun.facelets.tag.jsf.ComponentHandler.createComponent(ComponentHandler.java:224)
com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:139)
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHandler.java:314)
com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:169)
com.sun.facelets.tag.jsf.core.ViewHandler.apply(ViewHandler.java:109)
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49)
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25)
com.sun.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:95)
com.sun.facelets.FaceletViewHandler.buildView(FaceletViewHandler.java:524)
com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:567)
org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)

root cause

java.lang.NullPointerException
org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge.nextTimestamp(RegionFactoryCacheProviderBridge.java:85)
org.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:526)
org.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:535)
org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:493)
org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:377)
org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:263)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
$Proxy1.getDatabasePasswordFromSettings(Unknown Source)
com.smartcall.delegate.DbSettingsDelegate.getDatabasePassswordFromSettings(DbSettingsDelegate.java:38)
com.smartcall.bean.DbSettingsBean.loadDatabaseSettings(DbSettingsBean.java:49)
com.smartcall.bean.DbSettingsBean.<init>(DbSettingsBean.java:41)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
java.lang.Class.newInstance0(Class.java:355)
java.lang.Class.newInstance(Class.java:308)
com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:185)
com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:368)
com.sun.faces.mgbean.BeanManager.create(BeanManager.java:230)
com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:86)
javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:68)
org.apache.el.parser.AstValue.getValue(AstValue.java:112)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
com.sun.faces.application.ApplicationImpl.createComponent(ApplicationImpl.java:246)
com.sun.facelets.tag.jsf.ComponentHandler.createComponent(ComponentHandler.java:224)
com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:139)
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHandler.java:314)
com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:169)
com.sun.facelets.tag.jsf.core.ViewHandler.apply(ViewHandler.java:109)
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49)
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25)
com.sun.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:95)
com.sun.facelets.FaceletViewHandler.buildView(FaceletViewHandler.java:524)
com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:567)
org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)

When I comment out the line

context.refresh()

application is working fine. Plz help

UPDATE

DBSettingBean

public DbSettingsBean()
{
    dbSettingsDelegate = new DbSettingsDelegate();

    loadDatabaseSettings();
    submitButton.setRendered(false);
    testButton.setRendered(true);
}

public void loadDatabaseSettings()
{
    this.setUserName(dbSettingsDelegate.getDatabaseUserNameFromSettings());
    this.setPassword(dbSettingsDelegate.getDatabasePassswordFromSettings());
    this.setServerName(dbSettingsDelegate.getDatabaseServerNameFromSettings());
    this.setDataSourceName(dbSettingsDelegate.getDatabaseNameFromSettings());
}

public HtmlOutputText getText()
{
    return text;
}



public void setText(HtmlOutputText text)
{
    this.text = text;
}



public HtmlAjaxCommandButton getSubmitButton()
{
    return submitButton;
}



public void setSubmitButton(HtmlAjaxCommandButton submitButton)
{
    this.submitButton = submitButton;
}



public HtmlCommandButton getTestButton()
{
    return testButton;
}



public void setTestButton(HtmlCommandButton testButton)
{
    this.testButton = testButton;
}



public HtmlOutputText getStatusMessageComponent()
{
    return statusMessageComponent;
}

public void setStatusMessageComponent(HtmlOutputText statusMessageComponent)
{
    this.statusMessageComponent = statusMessageComponent;
}

public UIInput getPassworder()
{
    return passworder;
}

public void setPassworder(UIInput passworder)
{
    this.passworder = passworder;
}

public String getServerName()
{
    return serverName;
}

public void setServerName(String serverName)
{
    this.serverName = serverName;
}

public String getDataSourceName()
{
    return dataSourceName;
}

public void setDataSourceName(String dataSourceName)
{
    this.dataSourceName = dataSourceName;
}

public String getUserName()
{
    return userName;
}

public void setUserName(String userName)
{
    this.userName = userName;
}

public String getPassword()
{
    return password;
}

public void setPassword(String password)
{
    this.password = password;
}

public String testWhetherTheConnectionExists()
{       
    return dbSettingsDelegate.checkWhetherDatabaseConnectionExists(getUserName(), getPassword(), getDataSourceName(),getServerName());
}

and..

DbSettingsDelegate

public DbSettingsDelegate()
{
    try 
    {
        System.out.println("Dbsettings delegate: "+FacesContext.getCurrentInstance());
        dbSettingsService = (DbSettingsService) ServiceLocator
                        .getInstance().getService(
                        ServiceLocator.Services.DBSETTINGS);
    } 
    catch (Exception e) 
    {
        logger.debug("error in AddressBookDelegate constructor", e);
    }
}

public String getDatabaseUserNameFromSettings()
{
    return dbSettingsService.getDatabaseUserNameFromSettings();
}

public String getDatabasePassswordFromSettings()
{
    return dbSettingsService.getDatabasePasswordFromSettings();
}

public String getDatabaseServerNameFromSettings()
{
    return dbSettingsService.getDatabaseServerNameFromSettings();
}

public String getDatabaseNameFromSettings()
{
    return dbSettingsService.getDatabaseNameFromSettings();
}

public String checkWhetherDatabaseConnectionExists(String theUserName,String thePassword,String theDatabaseName,String theServerName)
{
    return dbSettingsService.checkWhetherTheDatabaseConnectionExists(theUserName, thePassword, theDatabaseName, theServerName);
}

and this is the code to retrieve database details to show to the user

ServletContext servletContext = FacesUtil.getServletContext();
    this.context = (AbstractApplicationContext)WebApplicationContextUtils
            .getRequiredWebApplicationContext(servletContext);
    String valueForTheProperty = "";
    DriverManagerDataSource databaseSource =  null;

    context.refresh();
    databaseSource = (DriverManagerDataSource)context.getBean("dataSource");



    if(theProperty.equalsIgnoreCase("username"))
    {
        valueForTheProperty = databaseSource.getUsername();
    }       
    else if(theProperty.equalsIgnoreCase("password"))
    {
        valueForTheProperty = databaseSource.getPassword();
    }
    else if(theProperty.equalsIgnoreCase("server"))
    {           
        valueForTheProperty = this.splitUrlAndGetValueForKey(databaseSource.getUrl(), "server");
        System.out.println("Server:  "+valueForTheProperty);
    }
    else
    {
        valueForTheProperty = this.splitUrlAndGetValueForKey(databaseSource.getUrl(), "databasename");
    }

UPDATE When I debugged the code I found these lines in the console. When context.refresh() is called

Dec 28, 2010 3:22:44 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: Running hbm2ddl schema update
Dec 28, 2010 3:22:44 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: fetching database metadata
Dec 28, 2010 3:22:44 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: updating schema
Dec 28, 2010 3:22:44 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: schema update complete

So I can assume some updation went on. Unable to identify why I am keep getting the old value

UPDATE The complete applicationCOntext.xml file

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<bean
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" scope="prototype">

    <property name="location">
        <value>classpath:/bundle/database.properties</value>
    </property>
</bean>

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">

    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>


<!-- Hibernate SessionFactory Definition -->
<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">


    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">
                org.hibernate.dialect.MySQLDialect
            </prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.cglib.use_reflection_optimizer">
                true
            </prop>
            <prop key="hibernate.cache.provider_class">
                org.hibernate.cache.HashtableCacheProvider
            </prop>
            <prop key="hibernate.connection.useUnicode">true</prop>
            <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
        </props>
    </property>

    <property name="dataSource">
        <ref bean="dataSource" />
    </property>
</bean>

<!-- Spring Data Access Exception Translator Definition -->
<bean id="jdbcExceptionTranslator"
    class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
    <property name="dataSource">
        <ref bean="dataSource" />
    </property>
</bean>

<!-- Hibernate Template Definition -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory">
        <ref bean="sessionFactory" />
    </property>
    <property name="jdbcExceptionTranslator">
        <ref bean="jdbcExc开发者_如何学GoeptionTranslator" />
    </property>
</bean>

<!--
    ========================= Start of SERVICE DEFINITIONS
    =========================
-->

<!-- Hibernate Transaction Manager Definition -->
<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
        <ref local="sessionFactory" />
    </property>
</bean>

<!-- AddressBook Service Definition -->
<bean id="loginServiceTarget" class="com.smartcall.service.impl.LoginServiceImpl">
    <property name="loginDAO">
        <ref local="loginDAO" />
    </property>
</bean>

<!-- Login DAO Definition: Hibernate implementation -->
<bean id="loginDAO"
    class="com.smartcall.dao.hibernate.HibernateLoginDAO">
    <property name="hibernateTemplate">
        <ref bean="hibernateTemplate" />
    </property>
</bean>

<!-- Transactional proxy for the AddressBook Service -->
<bean id="loginService"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager">
        <ref local="transactionManager" />
    </property>
    <property name="target">
        <ref local="loginServiceTarget" />
    </property>
    <property name="transactionAttributes">
        <props>
            <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

context.refresh() refreshes the whole applicationContext beans I thought. Ok now I removed those delgate and service in between and the application now calls straight

I am not using DBSettingsDelegate now

UPDATE

update properties file code

Properties properties = new Properties();
    String a = Thread.currentThread()
                .getContextClassLoader()
                .getResource("/com/smartcall/bundle/database.properties").getFile();

    a = a.replaceAll("%20", " ");
    String url = "";

        url = "jdbc:mysql://"+theServerName+":3306/"+theDatabaseName+"?characterEncoding=UTF-8";
        File file = new File(a);
        //file.setWritable(true);

        System.out.println(url);
        System.out.println(file.getAbsolutePath());

        FileInputStream stream = new FileInputStream(file);
        properties.load(stream);

        properties.put("jdbc.username", theUserName);
        properties.put("jdbc.password", thePassword);
        properties.put("jdbc.url", url);            

        properties.store(new FileOutputStream(file),null);  


You need to refresh your Application context and get the bean DriverManagerDataSource again in order to reflect the changes written to propertie files.

context.refresh();
DriverManagerDataSource databaseSource = (DriverManagerDataSource)context.getBean("dataSource");
databaseSource.getUsername();

Tip for getting File object of your resource:

    URI a = getClass().getResource("/com/smartcall/bundle/database.properties").toURI();
    File file = new File(a);

You will not need to decode the path, i.e. replacing %20 with " ". Referrence


The values are read when the application is started, they are set to the target objects (the data source in your case), and the properties file is no longer being read. So even if you change the values, they are not reflected anywhere.

For the PropertyPlaceholderConfigurer to reload the values you'd have to extend it and specify a reload period. But that still won't update the data source. You should also extend the data source class and make it re-read properties after a given interval. Or you can declare the DataSource to be of scope prototype, so that a new instance is obtained.each time, and the properties - reloaded.

This is if you don't want to restart the whole context (which might take a lot of time)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜