Wednesday, February 11, 2015

How to Handle Http Session Expiration on Login Page

We had a problem where if you sat on the login page for longer than the http session timeout period and then entered your username/password and attempted to login, you would get redirected back to the login page and have to enter it a 2nd time.  This got annoying so to fix this we added code to our custom exception handler to catch the ViewExpiredException.  A custom exception handler will catch all uncaught exceptions and is useful for displaying a generic "Something went wrong" page.    For information on how to set up a custom Exception handler see this blog by Frank Nimphius

The relevant part of the code I added to this exception handler is shown below.  It performs these steps
  • Retrieve username & password from request
  • Log user in
  • redirect to home page
 If the user entered an incorrect username/password then redirecting to home page will actually redirect back to the login page because the home page requires authentication and a valid login to access.
if (throwable instanceof ViewExpiredException) {
  ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
  String pathInfo = extContext.getRequestPathInfo();
  if (pathInfo.equals("/login")) {
      String username = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("usernameInput");
      String password = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("passwordInput");
      Login login = new Login();
      String action = login.login(username, password); // login the user even though the http session was expired.


The Login class is our own managed bean that is used by the login page.  It performs a bunch of thing, including creating a login history record among others, but the pertinent thing it does to actually login the user is this line 
                 authSuccess =  ServletAuthentication.login(user, pw, request, response);

 Our login page has a number of hidden fields that also need to be accessed during login and if you need to retrieve extra fields you can retrieve them the same way as shown above for the username and password fields.

Wednesday, October 15, 2014

What is the Entity Cache?

The ADF model layer uses an Entity Cache to manage updates to the database. This feature is one of the more misunderstood areas of the ADF framework because it’s not something you need a real good understanding of to create an ADF application. Here is a simple way to think about how the entity cache works.

If you are familiar with how the database command line works you know that you can insert or update rows in the database and until you commit, no one else accessing the system will see your changes until you commit them.   You can update a row, insert a row, delete a row and then re-query the tables you’ve changed and you will see your changes but no one else will.   This relates to the isolation transactional property of the ACID  (Atomicity, Consistency, Isolation, Durability)    features of modern databases.    You should not use the feature in a web application because you should never post data without immediately following up with a commit in the same request.   Since the request is coming from a web page if you were to post without committing you run the risk of never completing the commit and leaving the table with locked rows.   

In ADF this problem is solved using the Entity Cache.   We can think of the Entity cache as a work area containing pending changes but the changes do not hold a lock in the database.   The cache adds an additional layer between the database session and the pending changes.  These pending changes never get posted to the database until a commit is performed.   In addition when you run a entity based query, after executing the query,  the framework will look in the Entity cache to see if any of the rows returned have pending changes and will merge the pending changes with the results just retrieved.   This simulates the behavior of a post without a commit.   Only the specific user sees their own pending changes but it does this without ever posting the changes so no lock is created on the table (Assuming jbo.locking.mode is set to the default optimistic setting not pessimistic).

The entity cache allows one view object to display uncommitted rows that were updated in another view object (within the same application module) that is using one or more of the same entities.  It also allows changes to be propagated across these view objects without ever communicating with the database.  For example, if the user updates a UI field linked to one view object and somewhere else on the page, a different view object using that same entity is displaying that value,  All you need to do is refresh that other part of the page and you will see the pending change.

Every entity has its own entity cache.    The cache will contain rows to update, rows to add and rows to delete for a single table.    When it is time to commit, the framework simply has to look in the entity caches, post each entity change and then perform a single commit.

Because the rows were not locked, it is possible that another user or process could have updated the same row. The framework will compare the original values that are also stored in the entity cache with the values currently in the database and if they differ you will get an error "JBO-25014: Another user has changed the row with primary key oracle.jbo.Key". Also see yet-another-reason-for-jbo-25014.

There is a lot more to the entity cache but hopeful this simple explanation will help.  For more in-depth information on the Entity Cache See

What Happens at Runtime: When View Objects and Entity Objects Cooperate


Friday, August 29, 2014

Adding a regex QBE validator for numeric columns

I had a table containing a column that was a Number type.  If you tried to filter on a non numeric value a ConverterException would be thrown.   That was fixed by putting a Number converter on the filter input text to allow only numbers.   That worked except now you couldn't use the Query by Example (QBE) Search criteria Operators.  

These are the supported operators

Operator Description
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to

You can write a custom QBE adapter to fix this but that seemed like overkill.

To fix this I changed the filter to be an input text and added a  regular expression validator to allow these operators.  The pattern I used is below.   I didn't find a regex example for QBE Numeric filtering and I'm not a regex expert (is anyone?)  so it took a while to get the regex string just right.  Hopefully this will save someone some time.
Here's the pattern
^[ ]*[<>]?([<=]|[>=])?[ ]*[0-9]+[ ]?(?i)([ ]+AND[ ]+[<>]?[ ]*[0-9]*|[ ]+OR[ ]+[<>]?[ ]*[0-9]*)?[ ]*$

<af:column sortProperty="Count" filterable="true"     headerText="Count"  id="c6">
<f:facet name="filter">
<af:inputText  value="#{vs.filterCriteria.Count}" columns="8" id="Count">                                                 
<af:validateRegExp pattern="^[ ]*[<>]?([<=]|[>=])?[ ]*[0-9]+[ ]?(?i)([ ]+AND[ ]+[<>]?[ ]*[0-9]*|[ ]+OR[ ]+[<>]?[ ]*[0-9]*)?[ ]*$" 
                  messageDetailNoMatch="Please Enter Number Only"/>
<af:outputText value="#{row.Count}"    id="ot7" />      

Examples of Things you can put in the filter
> 10
>10  AND <  50
> 10 and < 50
10 or 50

 If the column is a String type (even through it might contain numbers) you don't have this problem and wouldn't need to add a regex Validator. 

Wednesday, December 18, 2013

How to View Service Proxy Request/Response message in Jdeveloper

In order to view the XML SOAP envelope of an ADF service Proxy, add this line to your server startup and the XML will be dumped the jdeveloper console output. 
  In Jdeveloper, the server startup command line is accessed from

Run Menu
Choose Active Run Configuration
Manage Run Configurations 
Edit Default

Add the line to the end of the Java Options.

 Also if  you see a large work:WorkContext section in the SOAP header, you can remove that by adding this line to the startup.

Thursday, October 31, 2013

How to make popup that can be dragged past edge of browser window.

I had a large dialog that I wanted to be able to move out of the way so that I could see what was behind it without closing it.   Normally any part of the dialog cannot be dragged off the edge of the browser window.   Configuring this turned out to be pretty simple.  Just add an inline style for the margin and give negative numbers to the sides you want to drag off the edge of the screen.  In the example below I don't want the top to be draggable past the top edge (because the top bar wouldn't be visible to drag it back down)  The left and right I set to -200 so that I could drag it 200 pixels to the left or right of the windows edge and 300 pixels past the bottom of the window.   This allows me to move it mostly out of the way without having to close it.

   <af:popup id="ppcal" clientComponent="true">
<af:dialog id="d1" title="Calculator"
               modal="false" type="ok"
               inlineStyle="width:450px; margin:0px -200px -300px; padding:-200.0px>

Tuesday, September 10, 2013

Displaying external content in a IFRAME within a popup dialog

I recently had a requirement to display some non ADF content inside a popup dialog.   There are a number of blogs on how to do this (see this one)  so I won't rehash them here.  I did however run into one problem in that when you drag the dialog around on the page and the mouse cursor slips into the frame containing the external content, the mouse events get captured by the frame and the dialog stops dragging.  Then if you release the mouse button and move outside of the frame, the dialog is now stuck to the end of your mouse cursor because the page lost the mouse up event and still thinks the mouse button is pressed.   To fix this I had to write a javascript mouse event handler and attach it to the frame to propagate mouse events in the frame to the parent page.

I found the basis for my solution here.  mousemove-when-over-an-iframe

I modified this slightly in that my particular page didn't need to save the original onMouseMove and onMouseUp handlers.

To wire this up add a client listener to the popup
  <af:clientListener type="popupOpened"     method="popupOpened"/>

// This method attaches the frame with id of "fid" to the mouse event handler

 function popupOpened(e){
      var frame = document.getElementById( e.getSource().findComponent("fid").getClientId()+'::f');

// iframe causes the page to lose the mouse events when dragging the dialog
// this fixes it by propagating mouse events in the iframe to the parent page

function bubbleIframeMouseMove(iframe){
     iframe.contentWindow.onmousemove = propagateToParent;
     iframe.contentWindow.onmouseup = propagateToParent;
      function propagateToParent(e){
        // Create a new event for the this window
        var evt = document.createEvent("MouseEvents");
        // We'll need this to offset the mouse move appropriately
        var boundingClientRect = iframe.getBoundingClientRect();
        // Initialize the event, copying exiting event values
        // for the most part
            true, // bubbles
            false, // not cancelable
            e.clientX + boundingClientRect.left,
            e.clientY +,
            null // no related element

        // Dispatch the mousemove event on the iframe element

Friday, July 19, 2013

Using XML data in ADF View Object

I recently was tasked with creating a generic preferences table that can be used to story any type of web site preference.   This needed to be generic enough so that new types of preferences can be added without requiring a data model change.  Using XML in the value column was the perfect solution for this.

This is how the table is defined


The first type of preference I needed to add was a URL link. I defined this in XML

<url >
<label>Yahoo </label>

I insert this xml into the value column and "CUSTOMLINK" into the preference column along  with the USER_ID and primary key USER_PREFERENCE_ID sequence.

Here is the query I used to retrieve my custom url links.  Notice that I'm not actually returning any column from the table.   All of the columns returned are coming from the xml nodes in the value column.  This query uses a feature of Oracle available since 10.2 (XMLTABLE).  You can think of it as a table within a column that the row is being joined to.  "url "is the alias for this table containing all of the xml elements as table columns.

    --  XMLTable defines a join with contents of value column treating it like a table
                       PASSING XMLTYPE(USER_PREFERENCE.value) 
                       label  VARCHAR2(40) PATH 'label',
                       location  VARCHAR2(1025) PATH 'location',
                       open VARCHAR2(40) PATH 'open',
                       sortorder VARCHAR2(4) PATH 'sortorder',
                       permission VARCHAR2(40) PATH 'permission'
                       ) as url
    AND  USER_ID = :UserIdBind
    order by sortorder

I used a read only view object for this.   I could have created a entity based view object and use expert mode to insert similar sql.   For storing and committing data in the value column I would need to add custom code to the setters for the 4 xml based columns and there construct the xml containing the values from all of these columns and then set that xml into the value column.

This gives me great flexibility for adding additional columns to my query without making any changes to the data model.  Querying XML will probably not perform well if you have a huge result sets but  is a great solution for queries that return a small number of rows as this one does.