<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7675276419915284401</id><updated>2012-01-26T10:05:59.093-08:00</updated><title type='text'>Oracle ADF 11g Tips</title><subtitle type='html'>Oracle Application Development Framework using Jdeveloper</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-6811564914431999912</id><published>2012-01-24T12:23:00.000-08:00</published><updated>2012-01-24T12:23:45.623-08:00</updated><title type='text'>Executing iterator binding in deferred Mode when there are required bind variable parameters</title><content type='html'>An iterator binding can be set to execute in "deferred" mode.&amp;nbsp; This is the default behavior if you don't change it.&amp;nbsp;&amp;nbsp; What this means is that the query will not execute unless the page needs to display it's data.&amp;nbsp;&amp;nbsp; This is great for use on a page that doesn't initially display the data to the user, like in a popup or tab that is not initially disclosed.&amp;nbsp; If the popup is displayed or the tab is disclosed, then and only then will the query be executed.&amp;nbsp; Also for tables that are set to lazy load (retrieve it's data after the page initially loads) this prevents the query from executing until the page is first displayed and the "Fetching data..."&amp;nbsp; message is displayed over the table.&amp;nbsp; A problem arises when the view object requires named bind variables.&amp;nbsp; The bind variables do not get set unless you add an ExecuteWithParams action binding to the task flow.&amp;nbsp;&amp;nbsp; Calling an ExecuteWithParams will execute the query but that defeats the value of setting the iterator binding to "deferred"&amp;nbsp;&amp;nbsp; So how do I set the bind variables without executing the query?&lt;br /&gt;&lt;br /&gt;Here is one technique:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Edit the View object, select the Java panel and check the "Generate View Object Class" and "Include bind_variable accessors. &lt;/li&gt;&lt;li&gt;Edit the Client Interface and add the setMyValueBind()&amp;nbsp; method to the interface.&lt;/li&gt;&lt;li&gt;Select the Data Control panel and click the refresh icon to refresh the data controls.&lt;/li&gt;&lt;li&gt;Find your view object in the data controls panel and expand it.&amp;nbsp; You should see the setMyValueBind method under the list of attributes.&lt;/li&gt;&lt;li&gt;Drag the method call over onto your task flow and add an EL expression to set the bind variables value.&lt;/li&gt;&lt;li&gt;insert the method call into the chain of operations that execute prior to displaying the page.&lt;/li&gt;&lt;/ul&gt;That is all that is needed.&amp;nbsp; The first time the data is displayed, the iterator binding will execute the query using the set bind parameters and if the user never displays the popup or tab that displays the data, the query will not need to be executed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-6811564914431999912?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/6811564914431999912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2012/01/executing-iterator-binding-in-deferred.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/6811564914431999912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/6811564914431999912'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2012/01/executing-iterator-binding-in-deferred.html' title='Executing iterator binding in deferred Mode when there are required bind variable parameters'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-7879122173432447373</id><published>2012-01-13T15:14:00.000-08:00</published><updated>2012-01-13T15:16:54.419-08:00</updated><title type='text'>How to cancel a long running query from the UI</title><content type='html'>I've long wondered if there was any way to cancel a query that is taking too long to complete from the page where the query is being run, similar to hitting the cancel button in SQL Developer.&amp;nbsp;&amp;nbsp; I noticed that the view object class has a cancelQuery() method on it but how do you call that when the thread is busy running the query.&amp;nbsp;&amp;nbsp; I did some experimenting and found that if I overrode the executeQuery method in the view and saved the view object on the session I could then use that to cancel the query from another task flow running in another tab or browser window.&lt;br /&gt;&amp;nbsp;&amp;nbsp; Here is the code&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@Override&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void executeQuery() {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Map sessionScope =&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ADFContext.getCurrent().getSessionScope();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sessionScope.put("MyQuery",this);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try{&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; super.executeQuery();&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } finally{&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // only keep on the Session&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //for the duration of the query &amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; sessionScope.remove("MyQuery");&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;On a different page put a button for canceling the query that calls this action method&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;public void cancelQueries(ActionEvent actionEvent) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Map sessionScope = ADFContext.getCurrent().getSessionScope();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ViewObjectImpl vo = (ViewObjectImpl)sessionScope.get("MyQuery");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (vo!=null){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (vo.isDead()==false){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; vo.cancelQuery();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sessionScope.remove("MyQuery");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;This will cause the query to throw a "JBO-27126&lt;span class="msg"&gt; Long running query has been canceled" Exception.&lt;/span&gt;&lt;br /&gt;&lt;span class="msg"&gt;In order to prevent the page from becoming broken you must catch this exception in the executeQueryForCollection method and re-throw a new JboException which will be displayed to the user.&amp;nbsp;&amp;nbsp; See &lt;a href="http://andrejusb.blogspot.com/2011/08/how-to-control-long-sql-execution-time.html"&gt;this blog &lt;/a&gt;for an example of that.&lt;/span&gt;&lt;br /&gt;&lt;span class="msg"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="msg"&gt;This seems to work fine but how would I put a button on the same browser tab as the one running the query.&amp;nbsp;&amp;nbsp; I haven't implemented that but I can think of a couple of ways that might be done.&amp;nbsp; One would be to have the button call a javascript method that makes a custom AJAX call back to a plain old servlet that retrieves the users session and calls the cancelQuery method.&amp;nbsp; Another might be to add an inline frame that has a URL to a different task flow and page containing only the single button.&amp;nbsp; ADF doesn't let you submit a button on the same page until the page is no longer busy but using an inline frame is the same as running the task flow on another tab so concurrent requests are allowed.&lt;/span&gt;&lt;br /&gt;&lt;span class="msg"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="msg"&gt;I make no guarantees that this isn't violating some threading rules for view objects by calling the cancelQuery method on a different thread but for my experiments the query was canceled fine and the other page woke up and displayed the timeout message.&amp;nbsp; Results may vary.&lt;/span&gt;&lt;br /&gt;&lt;span class="msg"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="msg"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-7879122173432447373?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/7879122173432447373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2012/01/how-to-cancel-long-running-query-from.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/7879122173432447373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/7879122173432447373'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2012/01/how-to-cancel-long-running-query-from.html' title='How to cancel a long running query from the UI'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-9021140387019899704</id><published>2011-09-22T11:48:00.000-07:00</published><updated>2011-09-22T12:08:07.181-07:00</updated><title type='text'>How to Ignore Time Component of Date column when filtering on Date.</title><content type='html'>When you create a table that supports column filtering,&amp;nbsp; the default behavior for filtering on dates is to compare the date directly.&amp;nbsp; This means that if the date in the database has a time component the row will not match and no results will be found.&amp;nbsp;&amp;nbsp;&amp;nbsp; If you don't need to display the time along with the date in the table then you can just put a trunc(...) around the date in the original query.&amp;nbsp;&amp;nbsp; If you do need to display the time then you can add another view attribute to your query that outputs the trunc'd version of the date.&amp;nbsp;&amp;nbsp; The new column will not be displayed but will be used for sorting and filtering.&amp;nbsp;&amp;nbsp; The af:column component has a sortProperty attribute that usually contains the column attribute name for the column displayed below it.&amp;nbsp;&amp;nbsp; This does not have to be the case however.&amp;nbsp; The sortProperty can be set to any column in the view object so that when you put a value in the filter field it filters and sorts on a different column then the one displayed below it.&amp;nbsp; Set the sortProperty for the date/time column to the date only column and you will get the desired behavior.&amp;nbsp; When you filter on a date it will return all rows with that date regardless of the time portion of the date.&lt;br /&gt;&lt;br /&gt;There is another way to accomplish this that will make every Date filter within your application time agnostic so that developers do not need to add this extra column every time they want to filter on the date portion of a date/time column.To do this you need to create a custom SQL builder class that extends OracleSQLBuilderImpl and override the getFormattedLHSCompareFragment method (Left Hand Side Compare Fragment)&amp;nbsp; This is called whenever filtering is performed.&amp;nbsp;&amp;nbsp; In this method add the trunc(...) around the value.&amp;nbsp; Sample code is shown below. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This class is activated by adding a JVM parameter on startup&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; -Djbo.SQLBuilder=com.yourCompany.model.custom.MySQLBuilderImpl&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid black; overflow: auto;"&gt;&lt;pre&gt;/**&lt;br /&gt; * Override method in OracleSQLBuilderImpl in order to trunc (remove time component)&lt;br /&gt; * when filtering on Dates in tables (Query By Example) QBE&lt;br /&gt; * This class is activated by adding a JVM parameter&lt;br /&gt; *  -Djbo.SQLBuilder=com.yourCompany.model.custom.MySQLBuilderImpl&lt;br /&gt; */&lt;br /&gt;public class MySQLBuilderImpl extends OracleSQLBuilderImpl {&lt;br /&gt;    &lt;br /&gt;    private static final Log log = LogFactory.getLog(MySQLBuilderImpl.class);&lt;br /&gt;    private static SQLBuilder mSQLBuilderInterface=null;  &lt;br /&gt;    &lt;br /&gt;    public MySQLBuilderImpl() {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Gets the singleton instance of this class.&lt;br /&gt;   * @return a &lt;tt&gt;SQLBuilder&lt;/tt&gt; object.&lt;br /&gt;   */&lt;br /&gt;  synchronized public static SQLBuilder getInterface()&lt;br /&gt;  {&lt;br /&gt;     if (mSQLBuilderInterface == null)&lt;br /&gt;     {&lt;br /&gt;        if (Diagnostic.isOn())&lt;br /&gt;        {&lt;br /&gt;           Diagnostic.println("OracleSQLBuilder reached getInterface");&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        mSQLBuilderInterface = (SQLBuilder)(new MySQLBuilderImpl());&lt;br /&gt;&lt;br /&gt;        if (Diagnostic.isOn())&lt;br /&gt;        {&lt;br /&gt;           Diagnostic.println(mSQLBuilderInterface.getVersion());&lt;br /&gt;        }&lt;br /&gt;     }&lt;br /&gt;     return mSQLBuilderInterface;&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public String getFormattedLHSCompareFragment(ViewObject vo, ViewCriteria vc,&lt;br /&gt;                                               AttributeDef attrDef,&lt;br /&gt;                                               int sqltype, String lhs,&lt;br /&gt;                                               Object rhs) {&lt;br /&gt;   String value =   super.getFormattedLHSCompareFragment(vo, vc, attrDef, sqltype, lhs, rhs);&lt;br /&gt;   &lt;br /&gt;    if (sqltype==Types.DATE || sqltype==Types.TIMESTAMP) {&lt;br /&gt;      &lt;br /&gt;      // only apply trunc to database columns, not view alias names used for in-memory filtering&lt;br /&gt;      // ADF does not handle a trunc for a in-memory filter and will get an error&lt;br /&gt;      Integer attr = vo.getAttributeIndexOf(value); // &lt;br /&gt;      if (attr == -1){  // not found, meaning it's a database column name, not an attribute name.&lt;br /&gt;      &lt;br /&gt;       value = "TRUNC("+value+")";&lt;br /&gt;        if (log.isDebugEnabled()) {&lt;br /&gt;            log.debug("MySQLBuilderImpl truncating date value:"+value);&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    return value;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-9021140387019899704?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/9021140387019899704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2011/09/how-to-ignore-time-component-of-date.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/9021140387019899704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/9021140387019899704'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2011/09/how-to-ignore-time-component-of-date.html' title='How to Ignore Time Component of Date column when filtering on Date.'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-6173921218308017654</id><published>2011-01-18T11:38:00.000-08:00</published><updated>2011-01-18T11:51:49.832-08:00</updated><title type='text'>Commiting an ADF view that contains an outer join</title><content type='html'>Here is my problem&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I have a ADF writable View of table1 that that contains a left outer join to table2.&amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Table2 has a foreign key to table1.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Both Table1 and Table2 contain editable fields displayed in the UI.&lt;/li&gt;&lt;li&gt;Table1 contains an existing row to be edited and will always be commited but I don't want to create a row in table2 unless the user enters data in one of table2's fields &lt;/li&gt;&lt;/ul&gt;My problem was that if I tried to commit, I would get an "attribute x is required" message because the foreign key was missing.&amp;nbsp; To solve this I opened the view in jdeveloper, clicked on the Java tab and selected the "Generate View Row Class" so that a ViewRowImpl.java class is created.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;I then opened this generated class and updated the setter for each attribute that can be edited in the UI. Below is an example. The red text was what I added.&amp;nbsp;&amp;nbsp; KeyAttribute is the primary key of table1 KeyAttribute2 is the foreign key in table2.&amp;nbsp; They need to be set to the same value before table2 can be commited. If there is currently no matching row in table2, KeyAttribute2 will be null.&amp;nbsp; KeyAttribute1 is a DBSequence and KeyAttribute2 is a Number, hence the call to getSequenceNumber to convert it to a Number.&amp;nbsp; With this code, now I don't get the error any more and also it won't commit a row in table2 if no data for it has been entered.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setMyDate(Date value) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #660000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (value!=null &amp;amp;&amp;amp; getKeyAttribute2() == null){&lt;/span&gt;&lt;br /&gt;&lt;div style="color: #660000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setKeyAttribute2(getKeyAttribute().getSequenceNumber());&lt;/div&gt;&lt;div style="color: #660000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setAttributeInternal(MYDATE, value);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;This works great when the row you are editing in table1 already exists.&amp;nbsp; If you want to create a new row in table1 and commit it at the same time as a new row in table2 it is a bit more challenging as you will need to generate a DBSequence to be added to both the Primary and Foreign key fields but only to the foreign key field if other data exists for table2, otherwise you will create a empty row in table2 with only the foreign key.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-6173921218308017654?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/6173921218308017654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2011/01/commiting-adf-view-that-contains-outer.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/6173921218308017654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/6173921218308017654'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2011/01/commiting-adf-view-that-contains-outer.html' title='Commiting an ADF view that contains an outer join'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-6492867153550301642</id><published>2010-12-13T13:43:00.000-08:00</published><updated>2010-12-13T14:07:11.853-08:00</updated><title type='text'>Accessing ADF components using client side script</title><content type='html'>&lt;div style="color: black;"&gt;Occasionally there is a need to access a client side component using javascript.&amp;nbsp;&amp;nbsp; One technique is to send script&amp;nbsp; down to the page from the backing bean that looks up the component using the ADF javascript method &lt;br /&gt;&lt;pre class="jive-pre" style="color: black;"&gt;&lt;code class="jive-code jive-java"&gt;AdfPage.PAGE.findComponent('clientIdOfComponent');&lt;/code&gt;&lt;/pre&gt;&lt;pre class="jive-pre" style="color: black;"&gt;&lt;code class="jive-code jive-java"&gt;&lt;/code&gt;&lt;/pre&gt;That technique works well but requires that you bind the component to the backing bean or look up the component using the full naming container path.&amp;nbsp; The technique I am going to describe allows you to declaratively access a UI component in script without having to add java code in the backing bean.&amp;nbsp; Because the getClientId(FacesContext) &amp;nbsp; method of the UIComponent requires a parameter it cannot be called directly within a EL expression on the page. The only parameter that can be passed in a EL Expression is the key to a Map object.&amp;nbsp; Because of this I created a Application scope helper bean&amp;nbsp; (ClientIdMap) that implements the Map interface.&amp;nbsp;&amp;nbsp; It's not a real map and it's sole purpose is to evaluate the Key as a EL expression and return the Client ID of the component it finds. Just add this as an Application scope bean to the adfc-config.xml file.&amp;nbsp; (unused methods are not shown but must be implemented).&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;public class ClientIdMap implements Map {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @param key el expression where UIComponent is stored&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @return client side component ID&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Object get(Object key) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String returnValue = "";&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object val = JSFUtils.resolveExpression("#{"+key+"}");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(val instanceof UIComponent){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; returnValue = ((UIComponent)val).getClientId(FacesContext.getCurrentInstance());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return returnValue;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then add this line to the top of your page which sets the client ID into a javascript variable that can then be used by your script.&amp;nbsp; Don't ask how the double nested single quotes work but they do.&lt;br /&gt;&lt;br /&gt;&amp;lt;trh:script text="var myPopup = '#{ClientIdMap['requestScope.myComponent']}';"/&amp;gt;&lt;br /&gt;&lt;br /&gt;Notice that for this to work, an EL expression (without the surrounding #{}) must be passed that is the same as the binding for the component.&amp;nbsp; Note that you can bind a component to a backing bean or directly to requestScope as shown.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&amp;lt;af:popup binding="#{requestScope.myComponent}" id="myPopup"&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Binding to requestScope is easiest because it can be added at runtime without restarting the server.&lt;br /&gt;&lt;br /&gt;Then to retrieve the UIComponent do something like this (shows the popup without making an ajax call to the server)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="jive-pre" style="color: black;"&gt;&lt;code class="jive-code jive-java"&gt;var popup = AdfPage.PAGE.findComponent(&lt;/code&gt;myPopup&lt;code class="jive-code jive-java"&gt;);&lt;/code&gt;&lt;/pre&gt;&lt;pre class="jive-pre" style="color: black;"&gt;&lt;code class="jive-code jive-java"&gt;var hints = {autodismissNever:true};&lt;br /&gt;popup.show(hints);&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The advantage of retrieving the ClientId from the binding instead of adding the fully qualified path in your javascript is that ADF may add indexes to your client ID that may change.&amp;nbsp; (&lt;a href="http://jplmelanson.wordpress.com/2010/04/20/adf-app-param-oracle-adfinternal-view-rich-region-dynamicclientid-disabled/"&gt;see this link&lt;/a&gt;) Also, if someone adds a naming container around your page, region or component the Client ID will change so it's never a good idea to hard code the client ID.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-6492867153550301642?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/6492867153550301642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2010/12/accessing-adf-components-using-client.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/6492867153550301642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/6492867153550301642'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2010/12/accessing-adf-components-using-client.html' title='Accessing ADF components using client side script'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-9063080549523049981</id><published>2010-12-13T12:17:00.000-08:00</published><updated>2010-12-13T14:13:32.676-08:00</updated><title type='text'>Removing rows from a Query Collection</title><content type='html'>Here's a &lt;a href="http://adfcodebits.blogspot.com/2010/05/bit-16-removing-row-from-query.html"&gt;link to a blog &lt;/a&gt;that describes how to remove Rows from a query Collection without deleting the row from the database.&amp;nbsp; This works for entity based views but I had a need to remove rows from a Query Collection of a non-entity based read only view.&amp;nbsp;&amp;nbsp; &amp;nbsp; The way I did this was to add a transient attribute "Displayed" to the view.&amp;nbsp; I then create a view criteria (filterCriteria) that filters out any row where Displayed='False'.&amp;nbsp; In the "Edit View Criteria" dialog I set the Query Execution Mode to "In Memory" &amp;nbsp; After executing the query in my backing bean I loop through the rows and set the Displayed attribute to 'False" for any row I don't want to display.&amp;nbsp;&amp;nbsp; Then I apply an in-memory filter by executing the following &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setApplyViewCriteriaName(filterCriteria);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setQueryMode(QUERY_MODE_SCAN_VIEW_ROWS);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; super.executeQuery();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Normally you would just filter the original results using SQL but in my case the rules for determining which rows to remove did not translated easily to SQL so this technique was employed.&amp;nbsp; This might be useful if you were filtering out rows based on the users permissions and those permissions were stored in LDAP and couldn't be made part of the query.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-9063080549523049981?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/9063080549523049981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2010/12/removing-rows-from-query-collection.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/9063080549523049981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/9063080549523049981'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2010/12/removing-rows-from-query-collection.html' title='Removing rows from a Query Collection'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-6459678592659253430</id><published>2010-06-30T11:45:00.000-07:00</published><updated>2010-06-30T11:45:24.017-07:00</updated><title type='text'>Case Insensitive Search</title><content type='html'>&lt;span style="font-family: inherit;"&gt;&lt;/span&gt;We had an interesting problem when migrating to the PS2 version of jdeveloper.   All of our&amp;nbsp; &lt;a href="http://fusionstack.blogspot.com/2009/08/adf-table-and-qbe.html"&gt;QBE &lt;/a&gt;table filters that previously were case insensitive became case sensitive.   &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ADF supports &lt;a href="http://www.oracle.com/technology/products/jdev/howtos/10g/dynamiccrit/index.html#caseinsensitivequeries"&gt;case-insensitive queries&lt;/a&gt; but it relies on use of the UPPER() function to wrap the criteria and column selection.&amp;nbsp; We made design decisions a long time ago, that (A) the business data would not be converted to all upper case, and (B) the application search screens would not convert user criteria to upper case.  To make all searches case-insensitive, the application use Oracle’s &lt;a href="http://www.dba-oracle.com/t_case_insensitive_indexes_searches.htm"&gt;case-insensitive string comparison feature&lt;/a&gt; NLS_COMP=LINGUISTIC and NLS_SORT=BINARY_CI (where CI means case-insensitive).  Further, to support indexed case-insensitive searches, the data modeler added linguist-sort indexes on all indexed character strings.  That works fine for the “=” operator but we found out it does not work for the LIKE operator.   I understand that this has been fixed in the 11g database.  Unfortunately our 11G front-end is connected to a 10g database so filtering using the like operator will invalidate the indexes and produce a full table scan.&amp;nbsp; Furthermore, the use of the UPPER() function on the table column will invalidate the linguistic sort index so we can't use the ADF way of making filters be case insensitive.&lt;br /&gt;&lt;br /&gt;The reason filters on tables became case sensitive in PS2 was that even though the database was case insensitive by default, ADF would perform an &lt;a href="http://download-uk.oracle.com/docs/html/B25947_01/bcadvvo005.htm"&gt;in-memory filter&lt;/a&gt; immediately after executing the query and the in-memory filter, being case sensitive would remove all of the non-matching rows from the result set.&amp;nbsp; The fix for this was a little tricky.&amp;nbsp;&amp;nbsp; All of our view objects inherit from a custom base class we created.&amp;nbsp; In this class we have overridden the getViewCriteraClause(boolean forQuery) method.&amp;nbsp;&amp;nbsp; This method is called whenever ADF is about to apply view criteria (i.e. filter)&amp;nbsp; for either a database or a in-memory query.&amp;nbsp;&amp;nbsp; It conveniently lets you know which type (forQuery) it is requesting.&amp;nbsp; So now all we need to do is return null when forQuery==false and no criteria will be applied to in-memory filters.&amp;nbsp;&amp;nbsp; But what if we actually want to perform in-memory filtering? &amp;nbsp; Well, we can check the &lt;a href="http://download-uk.oracle.com/docs/html/B25947_01/bcadvvo005.htm"&gt;query mode&lt;/a&gt; to determine if the query is a "database only" query&amp;nbsp; and no in-memory filtering should be performed.&amp;nbsp;&amp;nbsp; The problem caused in PS2 was because ADF was performing this in-memory filter even though the query mode had not been set to do so. Therefore we can detect this condition and only allow in-memory filtering when the view's query mode is set to do so.&lt;br /&gt;&lt;br /&gt;In the example code below, I'm allowing the in-memory filter to occur but simply calling vc.setUpperColumns(true); to put the UPPER() clause around the in-memory filter making it case insensitive.  I want to do just the opposite when the query is bound for the database.   There is one section of code added there to support date filters where we skip the in-memory filter all together by returning null.  I'll talk about that in a later blog.&lt;br /&gt;&lt;br /&gt;&lt;div style="overflow:auto; border:1px solid black"&gt;&lt;br /&gt;&lt;font size = "-2"&gt;&lt;br /&gt; &lt;pre&gt;   public String getViewCriteriaClause(boolean forQuery) { &lt;br /&gt;&lt;br /&gt;    if (forQuery == false){&lt;br /&gt;         // clause is for cache (in-memory)&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;  // WARNING - It is possible to set the criteria mode to cache and the query mode&lt;br /&gt;  // to database.  That will query for a larger result set, then immediately filter it down in-memory&lt;br /&gt;  // queryModeDoesNotUseCache will be true in that case even though it performs a&lt;br /&gt;  // in-memory filter after the fact.  Doing so is not recommended as it wastes memory unless you&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;            boolean queryModeDoesNotUseCache =&lt;br /&gt;                ((getQueryMode() &amp; ~QUERY_MODE_SCAN_DATABASE_TABLES) == 0);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            ViewCriteria[] vcs =&lt;br /&gt;                getApplyViewCriterias(ViewCriteria.CRITERIA_MODE_CACHE);&lt;br /&gt;            if (vcs != null &amp;&amp; vcs.length &gt; 0) {&lt;br /&gt;&lt;br /&gt;                boolean criteriaForCacheModeOnlyFound = false; //&lt;br /&gt;                for (ViewCriteria vc : vcs) {&lt;br /&gt;&lt;br /&gt;                    criteriaForCacheModeOnlyFound |=&lt;br /&gt;                            (vc.getCriteriaMode() == ViewCriteria.CRITERIA_MODE_CACHE);&lt;br /&gt;&lt;br /&gt;                    if (vc.isUpperColumns() == false) {&lt;br /&gt;                        vc.setUpperColumns(true); // puts UPPER(..) around the values for filtering in-memory&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                if (queryModeDoesNotUseCache &amp;&amp;&lt;br /&gt;                    !criteriaForCacheModeOnlyFound) {&lt;br /&gt;                    // if query mode does not apply to cache and criteria mode&lt;br /&gt;                    // is not "cache only" mode (i.e not for both cache &amp; database)&lt;br /&gt;                    // don't apply any in-memory filter.&lt;br /&gt;                    // This is needed in PS2 to prevent in-memory filtering of dates which causes&lt;br /&gt;                    // no results because the time component is compared as well.&lt;br /&gt;                    // see CustomSQLBuilderImpl which has a PS2 workaround to trunc the date&lt;br /&gt;                    // so the date filters work (without comparing time component)&lt;br /&gt;                    // trunc will fail if applied to a in-memory filter on PS2&lt;br /&gt;                    return null;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;    } else{&lt;br /&gt;      &lt;br /&gt;      ViewCriteria[] vcs =&lt;br /&gt;          getApplyViewCriterias(ViewCriteria.CRITERIA_MODE_QUERY);&lt;br /&gt;      if (vcs != null &amp;&amp; vcs.length &gt; 0) {&lt;br /&gt;          for (ViewCriteria vc : vcs) {&lt;br /&gt;&lt;br /&gt;              if (vc.isUpperColumns()) {&lt;br /&gt;                  vc.setUpperColumns(false); // remove UPPER(..) around the values for database queryies&lt;br /&gt;              }&lt;br /&gt;          }&lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;        String clause = super.getViewCriteriaClause(forQuery);&lt;br /&gt;&lt;br /&gt;        return clause;&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/font&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-6459678592659253430?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/6459678592659253430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2010/06/case-insensitive-search.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/6459678592659253430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/6459678592659253430'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2010/06/case-insensitive-search.html' title='Case Insensitive Search'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-5227022190858021509</id><published>2010-06-29T16:50:00.000-07:00</published><updated>2010-06-30T10:08:11.639-07:00</updated><title type='text'>Creating Page level accelerator (hot) keys</title><content type='html'>ADF allows you to set access keys on buttons.&amp;nbsp; For example&lt;br /&gt;&lt;pre&gt;&amp;lt;af:commandtoolbarbutton accesskey="o" &lt;br /&gt;            action="OpenDetails" text="Open" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The accessKey must be a single character and in firefox, in order to use the access key you have to hit Alt+Shift+o.&lt;br /&gt;&lt;br /&gt;What if you want to use an accelerator key for other types of keystrokes? Menu Items are the only component that supports accelerator keys so for example to add a hot key for CTRL+0&amp;nbsp; you would need to add a menu item somewhere on the page&amp;nbsp; &lt;br /&gt;&lt;pre&gt;&amp;lt;af:commandMenuItem action="OpenDetails" &lt;br /&gt;                       accelerator="ctrl 0" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A menu item needs to hang inside a af:menu and af:menu needs to hang inside a menuBar so if you only want to use the accelerator feature without displaying a menu you will need to hide the menu container (menuBar).&lt;br /&gt;&lt;br /&gt;using inlineStyle="display:none".&amp;nbsp;&amp;nbsp; Now have the menu item perform the same action as the button and you have just created an accelerator key stroke for your button.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-5227022190858021509?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/5227022190858021509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2010/06/creating-page-level-accelerator-hot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/5227022190858021509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/5227022190858021509'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2010/06/creating-page-level-accelerator-hot.html' title='Creating Page level accelerator (hot) keys'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-7242639355783079903</id><published>2010-06-15T08:12:00.000-07:00</published><updated>2010-06-15T08:17:43.958-07:00</updated><title type='text'>Displaying newly added row in a table</title><content type='html'>With the new release&amp;nbsp; of jdeveloper (&lt;a href="http://www.oracle.com/technology/software/products/jdev/htdocs/soft11.html"&gt;PS2&lt;/a&gt;) There was a table that I thought wasn’t refreshing after adding a new  row to it.   It actually was refreshing but when the table refreshed,  the scroll bar moved slightly  but not noticeably down so that that the  added row was scrolled off the top of the screen so that the table looked  like it hadn’t changed.  I discovered that there is a property of the  table “DisplayRow” that can contain "default", "first", "last" or selected.    The dropdown shows that selecting “default”  should be the same as  selecting “first” but I found this not to be the case.   When I changed  it from “default” to  “first” it fixed the problem and now the added row  is displayed at the top of the table after refreshing without moving  the scrollbar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-7242639355783079903?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/7242639355783079903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2010/06/displaying-newly-added-row-in-table.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/7242639355783079903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/7242639355783079903'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2010/06/displaying-newly-added-row-in-table.html' title='Displaying newly added row in a table'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-151202260712823220</id><published>2010-06-04T15:54:00.000-07:00</published><updated>2010-06-04T16:20:01.635-07:00</updated><title type='text'>Preventing long numbers from displaying in exponential notation when exporting to excel</title><content type='html'>&lt;span style="font-family: arial;"&gt;The af:exportCollectionActionListener behavior  in ADF Faces Rich client provides a  simple way of exporting table content to excel spreadsheets.   There is one issue with that though in that long numbers will display in exponential notation.  This is the fault of Excel not the export.   Opening the spreadsheet in "Open Office" doesn't exhibit that behavior.  There was a work-around for this problem as described in a &lt;/span&gt;&lt;a style="font-family: arial;" href="http://blogs.oracle.com/groundside/2010/05/formating_columns_in_excel_created_by_afexportcollectionactionlistener.html"&gt;blog by Duncan Mills&lt;/a&gt;&lt;span style="font-family: arial;"&gt; but that work-around no longer works in the PS2 release of Jdeveloper, however I was able to modify that solution and make it work.  The work around was to put hidden text around the data in the column that put a =TEXT(...)  or =TRIM(...) tag around the long data value.  This tag would get exported and inform excel that the value was to be displayed as text.  This didn't work in PS2 becaus&lt;/span&gt;&lt;code style="font-family: arial;"&gt;e elements with the visible='false' attribute no longer get exported.   My work-around was to set the element to be visible but add a inline style to the text component of "display:none".  Now it gets exported to excel but doesn't show up in the UI.  Problem solved. &lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-151202260712823220?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/151202260712823220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2010/06/preventing-long-numbers-from-displaying.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/151202260712823220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/151202260712823220'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2010/06/preventing-long-numbers-from-displaying.html' title='Preventing long numbers from displaying in exponential notation when exporting to excel'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7675276419915284401.post-1775658444473540415</id><published>2009-05-05T16:34:00.000-07:00</published><updated>2009-05-05T18:05:39.549-07:00</updated><title type='text'>How to force a table to refresh itself</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"  &gt;Sometimes you will need to refresh a table from a method in a backing bean.&lt;br /&gt;&lt;br /&gt;I thought I’d pass along this technique as it is simpler than other methods works across region boundaries instead of using&lt;a href="http://biemond.blogspot.com/2009/01/passing-adf-events-between-task-flow.html"&gt; contextual events&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;When you have a table somewhere on your page (any &lt;a href="http://jdevadf.oracle.com/adf-richclient-demo/docs/apidocs/oracle/adf/view/rich/component/rich/fragment/RichRegion.html"&gt;region&lt;/a&gt;) that needs refreshing, perform the following steps&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul  style="font-family:arial;"&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;In a backing bean method, set a Boolean.TRUE into a requestScope variable. (see code in red below).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;In the executable bindings for your table, add a invokeAction executable (named refreshIfNeeded) and bind it to the Execute or ExecuteWithParams action binding for your table’s view (on the left hand side).&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;Set the refreshIfNeeded binding to refresh “Always”&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;Add a refresh condition expression that references your request scope variable.&lt;/span&gt; &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(204, 0, 0);font-family:arial;" &gt;getRequestScope().put("refreshNeeded", Boolean.TRUE);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_yWM57wdqk5o/SgDeLMgdv6I/AAAAAAAAAAk/10sg0mJFIOU/s1600-h/REFRESH.JPG"&gt;&lt;img style="cursor: pointer; width: 400px; height: 277px;" src="http://4.bp.blogspot.com/_yWM57wdqk5o/SgDeLMgdv6I/AAAAAAAAAAk/10sg0mJFIOU/s400/REFRESH.JPG" alt="" id="BLOGGER_PHOTO_ID_5332506242723987362" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;protected Map getRequestScope(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;         return (Map)resolveExpression("#{requestScope}");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;/**&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;* Method for taking a reference to a JSF binding expression and returning&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;* the matching object (or creating it).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;@SuppressWarnings(value={"deprecation"})&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;public static Object resolveExpression(String expression) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     FacesContext ctx = FacesContext.getCurrentInstance();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     Application app = ctx.getApplication();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     javax.faces.el.ValueBinding bind = app.createValueBinding(expression);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     Object value= bind.getValue(ctx);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     return value;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7675276419915284401-1775658444473540415?l=dkleppinger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dkleppinger.blogspot.com/feeds/1775658444473540415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dkleppinger.blogspot.com/2009/05/how-to-force-table-to-refresh-itself.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/1775658444473540415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7675276419915284401/posts/default/1775658444473540415'/><link rel='alternate' type='text/html' href='http://dkleppinger.blogspot.com/2009/05/how-to-force-table-to-refresh-itself.html' title='How to force a table to refresh itself'/><author><name>dkleppinger</name><uri>http://www.blogger.com/profile/02266023115878336856</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_yWM57wdqk5o/TCuBcmeJSeI/AAAAAAAAAA0/8FsFtT-x10Y/s1600-R/00553b4.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_yWM57wdqk5o/SgDeLMgdv6I/AAAAAAAAAAk/10sg0mJFIOU/s72-c/REFRESH.JPG' height='72' width='72'/><thr:total>4</thr:total></entry></feed>
