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)
精彩评论