I have a problem with a JSF page which I can't solve. I have a JSF page which is used to store application settings into database table. This is the source code of the JSF page:
<div id="settingsdiv" style="width:550px; height:400px; position:absolute; background-color:r; top:20px; left:1px"> <h:panelGrid columns="2"> <h:panelGroup>User Session Timeout</h:panelGroup> <h:panelGroup> <h:selectOneMenu value="#{ApplicationController.settings['SessionTTL']}"> <f:selectItem itemValue="#{ApplicationController.settings['SessionTTL']}" itemLabel="#{ApplicationController.settings['SessionTTL']}" /> <f:selectItem itemValue="two" itemLabel="Option two" /> <f:selectItem itemValue="three" itemLabel="Option three" /> <f:selectItem itemValue="custom" itemLabel="Define custom value" /> <f:ajax render="input" /> </h:selectOneMenu> <h:panelGroup id="input"> <h:inputText value="#{ApplicationController.settings['SessionTTL']}" rendered="#{ApplicationController.settings['SessionTTL'] == 'custom'}" required="true" /> </h:panelGroup> </h:panelGroup> <h:panelGroup>Maximum allowed users</h:panelGroup> <h:panelGroup> <h:selectOneMenu value="#{ApplicationController.settings['MaxUsersActive']}"> <f:selectItem itemValue="#{ApplicationController.settings['MaxUsersActive']}" itemLabel="#{ApplicationController.settings['MaxUsersActive']}" /> <f:selectItem itemValue="two" itemLabel="Option two" /> <f:selectItem itemValue="three" itemLabel="Option three" /> <f:selectItem itemValue="custom" itemLabel="Define custom value" /> <f:ajax render="inputl" /> </h:selectOneMenu> <h:panelGroup id="inputl"> <h:inputText value="#{ApplicationController.settings['MaxUsersActive']}" rendered="#{ApplicationController.settings['MaxUsersActive'] == 'custom'}" required="true" /> </h:panelGroup> </h:panelGroup> </h:panelGrid> </div> <div id="settingsdiv" style="width:350px; height:400px; position:absolute; background-color:transparent; top:20px; left:400px"> </div> <div id="settingsdiv" style="width:150px; height:60px; position:absolute; background-color:transparent; top:380px; left:800px"> <h:commandButton value="Save Settings" action="#{ApplicationController.updateDBSettings()}"/> </div> </h:form>
And this is the managed bean:
import java.io.Serializable; import javax.enterprise.context.SessionScoped; // or import javax.faces.bean.SessionScoped; import javax.inject.Named; /* include SQL Packages */ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import javax.annotation.PostConstruct; import javax.sql.DataSource; import javax.annotation.Resource; import javax.faces.context.FacesContext; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; // or import javax.faces.bean.ManagedBean; import org.glassfish.osgicdi.OSGiService; @Named("ApplicationController") @SessionScoped public class Application implements Serializable { /* This Hash Map will be used to store setting and value */ private HashMap<String, String> settingsMap = null; public Application(){ } /* Call the Oracle JDBC Connection driver */ @Resource(name = "jdbc/Oracle") private DataSource ds; /* Hash Map * Send this hash map with the settings and values to the JSF page */ public HashMap<String, String> getsettings(){ return settingsMap; } /* Get a Hash Map with settings and values. The table is genarated right * after the constructor is initialized. */ @PostConstruct public void initSettings() throws SQLException { settingsMap = new HashMap<String, String>(); if(ds == null) { throw new SQLException("Can't get data source"); } /* Initialize a connection to Oracle */ Connection conn = ds.getConnection(); if(conn == null) { throw new SQLException("Can't get database connection"); } /* With SQL statement get all settings and values */ PreparedStatement ps = conn.prepareStatement("SELECT * from GLOBALSETTINGS"); try { //get data from database ResultSet result = ps.executeQuery(); while (result.next()) { settingsMap.put(result.getString("SettingName"), result.getString("SettingValue")); } } finally { ps.close(); conn.close(); } } /* JSF returns the updated values into the HashMap */ /* Update Settings Values */ public void updateDBSettings() throws SQLException { String SQL_Statement = null; if (ds == null) throw new SQLException(); Connection conn = ds.getConnection(); if (conn == null) throw new SQLException(); try { conn.setAutoCommit(false); boolean committed = false; try { /* Insert the new settings values with one SQL statement */ SQL_Statement = "UPDATE GLOBALSETTINGS " + "SET \"SettingValue\" = " + "CASE " + "WHEN \"SettingName\" = 'SessionTTL' THEN ? " + "WHEN \"SettingName\" = 'MaxUsersActive' THEN ? " + "END " + "WHERE \"SettingName\" IN ('SessionTTL', 'MaxUsersActive')"; /* Exete thre SQL statement */ PreparedStatement updateQuery = conn.prepareStatement(SQL_Statement); updateQuery.setString(1, settingsMap.get("SessionTTL")); updateQuery.setString(2, settingsMap.get("MaxUsersActive")); updateQuery.executeQuery(); conn.commit(); committed = true; } finally { if (!committed) conn.rollback(); } } finally { /* Release the resource after all SQL queries are executed */ conn.close(); } } }
This is the problem that I face:
When I open the JSF page I get these menus:
1.png
Then I select custom from the menu:
2.png
I get this input field next to the menu:
3.png
Then I enter custom value from the keyboard:
4.png
But when I click Save button I get this. I can see that the database field is updated but the values is "custom"
3.png
When I enter the same twice value I get this:
6.png
I seems that when I click custom and I enter the custom value the HashMap is not updated. It's strange that when I do it again the HashMap is updated and the value is correct. How I can fix this problem?
I tried to reload the map from the DB after save. Basically, I called initSettings() in the end of updateDBSettings() but there was no change.
Best Wishes