What is a bug? especially in a framework that is used to develop applications? Is it only something that is described differently in manual? I will be writing more about that in this blog by presenting the functionality of the framework i am working on. Jdeveloper and fusion middleware
Sunday, August 30, 2009
LOV execute query many times (Fixed in 11.1.1.3)
Not only you cant use performance tuning since there are bugs if you use range paging:
http://adfbugs.blogspot.com/2009/07/performance-tuning-lovs-and-range.html
and Up to row number:
http://adfbugs.blogspot.com/2009/08/lov-view-object-tuning-only-up-to-row.html
but also because every time you open LOV and select a value it execute query many times.
To test that, i override the method executeQuery for collection and print the query:
@Override
protected void executeQueryForCollection(Object object, Object[] object2, int i) {
System.out.println("EmployeesLOV executes Query :" + this.getQuery());
super.executeQueryForCollection(object, object2, i);
}
when i open the lov and select a value i get the following log:
EmployeesLOV executes Query :Select * from Employees
30-Aug-2009 17:25:04 oracle.adfinternal.view.faces.renderkit.rich.RichRenderKit isNavigating
SEVERE: The original view root was not set.
EmployeesLOV executes Query :SELECT * FROM (Select * from Employees) QRSLT WHERE ( ( ( (EMPLOYEE_ID = :vc_temp_2 ) ) ) )
EmployeesLOV executes Query :Select * from Employees
so the LOV query is executed 3 times !?
If i type a value to fields that many LOV values start with this value then it is executed many times !!!.
EmployeesLOV executes Query :SELECT * FROM (Select * from Employees) QRSLT WHERE ( ( (EMPLOYEE_ID LIKE :vc_temp_2 ) ) )
30-Aug-2009 17:31:34 oracle.adfinternal.view.faces.renderkit.rich.RichRenderKit isNavigating
SEVERE: The original view root was not set.
EmployeesLOV executes Query :SELECT * FROM (Select * from Employees) QRSLT WHERE ( ( (EMPLOYEE_ID LIKE :vc_temp_2 ) ) )
EmployeesLOV executes Query :SELECT * FROM (Select * from Employees) QRSLT WHERE ( ( (EMPLOYEE_ID LIKE :vc_temp_2 ) ) )
EmployeesLOV executes Query :SELECT * FROM (Select * from Employees) QRSLT WHERE ( ( (EMPLOYEE_ID LIKE :vc_temp_2 ) ) )
EmployeesLOV executes Query :SELECT * FROM (Select * from Employees) QRSLT WHERE ( ( (EMPLOYEE_ID LIKE :vc_temp_2 ) ) )
EmployeesLOV executes Query :SELECT * FROM (Select * from Employees) QRSLT WHERE ( ( (EMPLOYEE_ID = :vc_temp_2 ) ) )
EmployeesLOV executes Query :Select * from Employees
Also while you scroll up and down in LOV the query is also executed many times.
Finaly if you type a value that many LOV values start with this value and scroll down then other values that dont start with this value are visible:
And if you select the value then you get a strange error:
Is this a bug?
Is there a way to use LOVs with a lot of data?
Test case:
http://adfbugs.googlecode.com/files/TestPerformance.zip
For the test case i put in Employees table about 100000 rows with the following procedure:
create or replace
PROCEDURE CREATE_EMPLOYEES AS
BEGIN
FOR i IN 1..100000 LOOP
Insert into employees (employee_id,
last_name,
email,
hire_date,
job_id)
select employees_seq.nextval as employee_id,
'auto' i as last_name,
'aut' i '@gmail.com' as email,
sysdate as hire_date,
'IT_PROG' as job_id
from dual;
END LOOP;
COMMIT;
END CREATE_EMPLOYEES;
Wednesday, August 19, 2009
Af:Query bind variable workaround
http://adfbugs.blogspot.com/2009/08/afquery-bind-variable-bug.html
Steve Muench said...
Filed bug# 8809022 with your testcase, thanks.
WORKAROUND----------
Rather than using the ExecuteWithParams action as the task flow'sinitial activity, instead write a custom AM method that you publishon the AM's client interface that does the following:
public void initTaskFlowDefinition(Number deptno) {
// Set var value on VO's variable
managergetEmployeesView1().ensureVariableManager().setVariableValue("inDepId",deptno);
// Save the save of the view criteria to "remember"
// the current var values as the ones to be restored
// in the search form.
getEmployeesView1().getViewCriteriaManager().getViewCriteria("EmployeesViewCriteria").saveState();
}
Then, have the task flow's default activity invoke this AMmethod instead to accomplish the task.
So i do it according to Steve workaround, but i didnt want to use bind variables since they have other issues:
http://adfbugs.blogspot.com/2009/07/jdeveloper-11-r1-cascading-lov-bugs.html
http://adfbugs.blogspot.com/2009/07/view-criteria-with-exists-optional-bug.html
So i used the following code:
public void initialSettings(oracle.jbo.domain.Number depId) {
EmployeesViewImpl emp = (EmployeesViewImpl)this.getEmployeesView1();
ViewCriteria vc = emp.getViewCriteria("EmployeesViewCriteria");
vc.first().setAttribute("DepartmentId", depId);
emp.getViewCriteriaManager().getViewCriteria("EmployeesViewCriteria").saveState();
}
i use this method in the task flow before entering the page and it seems to work fine.
Test Case:
http://adfbugs.googlecode.com/files/TestViewCriteria.zip
Friday, August 14, 2009
Range Paging in Master Detail bug. (Fixed in 11.1.1.3)
oracle.jbo.InvalidOperException: JBO-25011: Rowset Employees_Departments1_EmpDeptFkLink_DepartmentsView_0 is forward only. at oracle.jbo.server.ViewObjectImpl.validateRangeSizeForRangePaging(ViewObjectImpl.java:13522) at oracle.jbo.server.ViewRowSetIteratorImpl.setRangeSize(ViewRowSetIteratorImpl.java:529) at oracle.jbo.server.ViewRowSetImpl.setRangeSize(ViewRowSetImpl.java:2633) at oracle.jbo.server.ViewObjectImpl.doCreateViewLinkAccessorRS(ViewObjectImpl.java:13534) at oracle.jbo.server.ViewObjectImpl.createViewLinkAccessorRS(ViewObjectImpl.java:13624) at oracle.jbo.server.AssociationDefImpl.get(AssociationDefImpl.java:405) at oracle.jbo.server.ViewAttributeDefImpl.get(ViewAttributeDefImpl.java:773) at oracle.jbo.server.ViewRowStorage.getViewLinkAccessorResult(ViewRowStorage.java:1365) at oracle.jbo.server.ViewRowStorage.getAttributeInternal(ViewRowStorage.java:1579) at oracle.jbo.server.ViewRowImpl.getAttributeValue(ViewRowImpl.java:1795) at oracle.jbo.server.ViewRowImpl.getAttributeInternal(ViewRowImpl.java:783) at model.EmployeesViewRowImpl.getMasterDepartment(EmployeesViewRowImpl.java:522)
This happens if you use a master Accessor in a detail view object.
So i reproduced in a simple test case:
I have a simple Departments Employees master detail relation.
In Employees view object i create a transient Attribute IsDepartmentManager that i want to check if the employee is the manager of the department.
To do that i need the department assecor in Employees. so i do that from the View link.
In the getter of transient attribute i get the attribute of master :
public Boolean getisDepartmentManager() {
Object depManager = this.getMasterDepartment().getAttribute("ManagerId");
return depManager != null && depManager.equals(this.getEmployeeId());
}
When i Run application, everything is working fine:
But if i set Range Paging on tuning of Departments View and run again :
Is this a bug?
Am i missing something?
Test case:
http://adfbugs.googlecode.com/files/TestRPMasterDetail.zip
Wednesday, August 12, 2009
Table Filter Bug
Sunday, August 9, 2009
Af:Query bind variable bug (Fixed in 11.1.1.3)
I reproduced this bug in a simple Departments Employees Test case:
In Employees View object i have a query criteria for DepartmentId = :inDepId. In the taskflow that opens the Employees query page i first run ExecuteWithParams for the task flow input paramter.
When i run application in the main page i select a department and then i pass DepartmentId as input value to the Employees task flow.
The first time i call Employees task flow everything works fine. The value of input parameter is set in the criteria and Employees of that department are queried:
But when i return to departments and select an other department and go to Employees again, the bind Variable in Query criteria is still the same, Even though the input parameter and the results have changed for the new department.
Isn't this realy strange?
If i change value and press reset it allways return to the first value that af:query is executed.
I tried in bindings refresh conditions and TrackQueryPerformed="Page" with no luck.
Is this a bug?
Is there a workaround?
Test case:
http://adfbugs.googlecode.com/files/TestViewCriteriaBug.zip
Saturday, August 8, 2009
Page with Region Validations bug
Thursday, August 6, 2009
Region and dialog return bug
I put Departments as a simple form in a page and Jobs as a simple form in a page fragment and task flow that i add as a Region in the first page. I also create a dummy dialog with a return button.
But when i return from dialog and try to navigate inside the region i get the following error:
java.lang.IllegalStateException: ADF_FACES-60058:Attempt to re-register component with different model. at oracle.adfinternal.view.faces.activedata.PageDataUpdateManager._registerComponent(PageDataUpdateManager.java:256) at oracle.adfinternal.view.faces.activedata.PageDataUpdateManager.registerComponentForPPR(PageDataUpdateManager.java:161) at oracle.adf.view.rich.activedata.ActiveComponentContext.popActiveComponent(ActiveComponentContext.java:371) at oracle.adf.view.rich.render.RichRenderer.encodeAll(RichRenderer.java:1191) at org.apache.myfaces.trinidad.render.CoreRenderer.encodeEnd(CoreRenderer.java:335) at org.apache.myfaces.trinidad.component.UIXComponentBase.encodeEnd(UIXComponentBase.java:751) at org.apache.myfaces.trinidad.render.CoreRenderer.encodeChild(CoreRenderer.java:415)
After that the page is no longer functional.
Is this a bug?
Test case:
http://adfbugs.googlecode.com/files/RegionAndDialogTest.zip
P.s. This bug was found by 2 female colegues (Roula and Nota) in our application. It was working befor r1 of jdev11.
Wednesday, August 5, 2009
LOV criteria bug.
java.sql.SQLException: Attempt to set a parameter name that does not occur in the SQL: vc_temp_2
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:263)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:271)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectAtName(OraclePreparedStatement.java:11158)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObjectAtName(OraclePreparedStatementWrapper.java:815)
at oracle.jbo.server.OracleSQLBuilderImpl.bindParamValue(OracleSQLBuilderImpl.java:4617)
at oracle.jbo.server.BaseSQLBuilderImpl.bindParametersForStmt(BaseSQLBuilderImpl.java:3807)
at oracle.jbo.server.ViewObjectImpl.bindParametersForCollection(ViewObjectImpl.java:18278)
at oracle.jbo.server.QueryCollection.buildResultSet(QueryCollection.java:1035)
at oracle.jbo.server.QueryCollection.executeQuery(QueryCollection.java:815)
at oracle.jbo.server.ViewObjectImpl.executeQueryForCollection(ViewObjectImpl.java:5892)
at oracle.jbo.server.ViewRowSetImpl.execute(ViewRowSetImpl.java:1021)
at oracle.jbo.server.ViewRowSetImpl.execute(ViewRowSetImpl.java:889)
…
It is not easy to reproduce but when it happens you cannot open the LOV again and you cannot set a value to the LOV field, even from diferent row or from diferent session.
I managed to reproduce it in a simple test case of Employees form with simple Department LOV.
The steps to reproduce are:
1.Select an existing department
2.open department LOV add a criterion and press search.
3.Close LOV without selecting row and type a non existing value and press Tab. LOV automatically opens and even though it doesnt have values in criteria only the previus results are visible.
4.Press cancel again and type an existing value and press Tab. Then the error apears
Tuesday, August 4, 2009
LOV view object Tuning: 'Only up to row number' bug (Fixed in 11.1.1.3)
http://adfbugs.blogspot.com/2009/07/performance-tuning-lovs-and-range.html
I try the 'Only up to row Number' option in a simple employees form with Input List of values for DepartmentId.
so when i open the LOV only 10 rows apear:
Bug1: if i try to type number 110 that is a valid value but does not exist in the range, the value just disapear without even opening the LOV.
Bug2: If i type the number 20 then since both 20 and 200 exist it opens the LOV to select 1. but if i select cancel and after that i type the number 200 the value is set back to 20 and i get a stange error:
Is this a bug?
Or we should not use Tuning: 'Only up to row number' for LOV view objects?
Test case:
http://adfbugs.googlecode.com/files/TestLimitedLov.zip
Monday, August 3, 2009
Table Validations Bug.
but again if i press submit or commit all validation errors disapear!!!?
Sunday, August 2, 2009
Returning from dialog to a page that has f:verbatim tag bug
I managed to reproduce it in a simple test case:
I create a simple page with default oracle template and a dialog page.
I click on header facet and just typed something (test)
I run application i open dialog but when i return from dialog i have exception:
INFO: unable to dispatch JSP page: The following exception occurred:.java.lang.NullPointerException at oracle.adfinternal.view.faces.taglib.region.IncludeTag$RelocatedFacet.restoreFacet(IncludeTag.java:816) at oracle.adfinternal.view.faces.taglib.region.IncludeTag.doStartTag(IncludeTag.java:192) at oracle.adfinternal.view.faces.taglib.region.DynamicIncludeTag.doStartTag(DynamicIncludeTag.java:109) at oracle.jsp.runtime.tree.OracleJspBodyTagNode.executeHandler(OracleJspBodyTagNode.java:50) at oracle.jsp.runtime.tree.OracleJspCustomTagNode.execute(OracleJspCustomTagNode.java:257) at oracle.jsp.runtime.tree.OracleJspClassicTagNode.evalBody(OracleJspClassicTagNode.java:87) at oracle.jsp.runtime.tree.OracleJspBodyTagNode.executeHandler(OracleJspBodyTagNode.java:58) at oracle.jsp.runtime.tree.OracleJspCustomTagNode.execute(OracleJspCustomTagNode.java:257) at oracle.jsp.runtime.tree.OracleJspClassicTagNode.evalBody(OracleJspClassicTagNode.java:87) at oracle.jsp.runtime.tree.OracleJspBodyTagNode.executeHandler(OracleJspBodyTagNode.java:58) at oracle.jsp.runtime.tree.OracleJspCustomTagNode.execute(OracleJspCustomTagNode.java:257) at oracle.jsp.runtime.tree.OracleJspClassicTagNode.evalBody(OracleJspClassicTagNode.java:87) at oracle.jsp.runtime.tree.OracleJspBodyTagNode.executeHandler(OracleJspBodyTagNode.java:58) at oracle.jsp.runtime.tree.OracleJspCustomTagNode.execute(OracleJspCustomTagNode.java:257) at oracle.jsp.runtime.tree.OracleJspNode.execute(OracleJspNode.java:76) at oracle.jsp.runtimev2.ShortCutServlet._jspService(ShortCutServlet.java:88) at oracle.jsp.runtime.OracleJspBase.service(OracleJspBase.java:29) at oracle.jsp.runtimev2.JspPageTable.service(JspPageTable.java:416) at oracle.jsp.runtimev2.JspServlet.internalService(JspServlet.java:722) at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:646) at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227) at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292) at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56) at oracle.adf.library.webapp.LibraryFilter.doFilter(LibraryFilter.java:159) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56) at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:500) at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:248) at com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:410) at org.apache.myfaces.trinidad.context.ExternalContextDecorator.dispatch(ExternalContextDecorator.java:44) at org.apache.myfaces.trinidad.context.ExternalContextDecorator.dispatch(ExternalContextDecorator.java:44) at org.apache.myfaces.trinidad.context.ExternalContextDecorator.dispatch(ExternalContextDecorator.java:44) at org.apache.myfaces.trinidad.context.ExternalContextDecorator.dispatch(ExternalContextDecorator.java:44) at org.apache.myfaces.trinidadinternal.context.FacesContextFactoryImpl$OverrideDispatch.dispatch(FacesContextFactoryImpl.java:267) at com.sun.faces.application.ViewHandlerImpl.executePageToBuildView(ViewHandlerImpl.java:473) at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:141) at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:189) at org.apache.myfaces.trinidadinternal.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:193) at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._renderResponse(LifecycleImpl.java:685) at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:261) at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:193) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227) at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292) at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56) at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:191) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56) at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:85) at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:420) at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:54) at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:420) at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:247) at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:157) at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56) at oracle.security.jps.wls.JpsWlsFilter$1.run(JpsWlsFilter.java:96) at java.security.AccessController.doPrivileged(Native Method) at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313) at oracle.security.jps.wls.util.JpsWlsUtil.runJaasMode(JpsWlsUtil.java:146) at oracle.security.jps.wls.JpsWlsFilter.doFilter(JpsWlsFilter.java:140) at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:70) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56) at oracle.adf.library.webapp.LibraryFilter.doFilter(LibraryFilter.java:159) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56) at oracle.dms.wls.DMSServletFilter.doFilter(DMSServletFilter.java:202) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56) at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56) at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3588) at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121) at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2200) at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2106) at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1428) at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201) at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
and the page is no longer functional.
If i remove f:verbatim tag the page and dialog work nomraly.
So is this a bug?
If we should not use f:verbatim on ADF pages, why it is set automaticaly when you type something on the page?
Test case:
http://adfbugs.googlecode.com/files/TestDialogReturn.zip
Saturday, August 1, 2009
Range Paging Last operation, bug workaround
http://adfbugs.blogspot.com/2009/07/performance-tuning-range-paging-last.html
As Steve suggested i created a method that takes you to the last row:
private Row rangePagingLast() {
int pagesCount = getEstimatedRangePageCount();
scrollToRangePage(pagesCount);
Row lastRow = getRowAtRangeIndex(getRowCountInRange()-1);
setCurrentRow(lastRow);
return lastRow;
}
This method actually gets you to the last row even though Range Paging is set on a view object
It is also much faster than scrolling down to a table component or Last operation of a view object that has Scrolling as Action Mode.
So i overide my base View Object Implementation Class and the Last operation to support Last operation even if Range Paging is set.
@Override
public Row last() {
if (getAccessMode()==ViewObjectImpl.RANGE_PAGING) return rangePagingLast();
return super.last();
}
It seems to work fine.
Test case: