Thursday Dec 29, 2011

Business Rules Editor for View Objects in JDeveloper

JDeveloper has a new tab in the View Objects Editor - Business Rules.
This easily tend to make people misunderstand that this Editor can be used for adding validation rules for the attributes in the View Object. However, it is not true.

Lets check out what this editor is all about. As the online help for this page states
Use to create and maintain business rules based on Groovy Language expressions and declarative validation rules for this view object including:

  • Validators for transient attributes
  • Bind variable default value expressions for SQL queries
  • Bind variable value mappings for view accessors
  • Transient attribute value expressions
  • Transient attribute value expression recalculation conditions
  • Attribute default value expressions

We'll see how we can use this editor to edit different types :

Transient Attributes : 

We can use this editor for a. adding validation rules, b. edit default value expression

a. As like the Entity Attributes, we can add many validation rules for the transient attributes in VO as well.


In the above image, EmpType is a transient attribute on Emp VO.We can see there are two rules added. First one is a validation rule (List Validator), restricting the user to enter either one of the value specified for the attribute. Second one is the default value expression for the attribute. Upon selecting the node, the default value groovy expression would become editable in the Script Expression field below, wherein we can modify it and test the syntax as well.

Note : We can add the validation rule only for the transient attributes which are Updatable. Also, we can edit only the default values which are script expressions only. Not the literal values.

Bind Variables :

Similar to the transient attributes, we can use this editor for modifying and testing the default value expression for the Bind Variables of the VO as well.

Ex :

In the above example image, we can see a Bind Variable (Bind_Hiredate) added to the Query, which has the default value expression as adf.currentDate.

Using this editor, we can modify this expression and test the syntax.

View Accessor :

If we have a bind variable to the VO and use it as List Data Source for any of the attributes in the VO, we can use this editor to change the value of the bind variable in the View Accessor.

Ex :

In the above example image, we have couple of Bind Variables in the View Accessors (they are used as Lists and Dependent Lists for this View Object). Using this editor, we can edit the values of those bind variables.

We can also use this editor for modifying and testing the default value expression on the VO attributes and the re-calculation conditions.

Thursday Jul 28, 2011

Custom Table Pagination Using EJB Native Query

Let us take scenario where the table has more records. Here employees table has more number of records, if the entire records are displayed in single ADF table, It will be difficult for user to navigate or traverse to the exact record. This can be achieved by implementing pagination, Pagination is an important aspect when displaying large number of records. This blog would be of help if you are building applications that render large number of records in a table. With pagination, the number of records displayed can be controlled into several manageable chunks, thus making it easy to locate the records of interest.

Model Diagram:

Here in the above model diagram, Employees table schema.

Let us consider the above Employees table has more number of records, User will not be able to see all the records at the same time on web page.
For ex:- Employees Details Page

Employee More Record.png

We use the af:iterator tag to implement the custom table with pagination. This tag renders a collection in the same fashion as the af:table tag does. Same as af:table tag, af:iterator can be based on table binding available in page definition. It iterates over data collection and renders data rows.

First, create entities based on  Employees, then create a stateless session bean and data control for the session bean. Add the below code to the session bean and expose the method in local/remote interface and generate a data control for that.

Note:- Here in the below code "em" is a EntityManager.

  * Returns list of employee list starting at the given first index with the given max row count.
  * @return list of  employee list starting at the given first index with the given max row count.
   public List<Employees> employeesByLimit(int firstRow, int maxRow) {
        String queryString = "select * from Employees order by employee_id ASC";
        return em.createNativeQuery(queryString,

  * Returns total amount of rows in table.
  * @return Total amount of rows in table.
   public int employeesTotalRows() {
        String queryString = "select * from Employees order by employee_id ASC";
        Query query = em.createNativeQuery(queryString);
        List results = query.getResultList();
        return results.size();

In the ViewController create a file CustomPagination.jspx page, right click and "Go to Page Definition", CustomPaginationPageDef.xml file will be created. 

Create a CustomPagination managed bean with scope as "sessionScope" add the below code:

    private int firstRow = 0;
    private int rowsPerPage = 10;
    private int totalRows;
    private int totalPages;
    private int currentPage = 1;

    public CustomPagination() {

    public void loadList() {
         * Returns total amount of rows in table.
         * @return Total amount of rows in table.
        BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();
        AttributeBinding attr = (AttributeBinding)bindings.getControlBinding("EmployeesTotalRowCount");
        String val = attr.getInputValue().toString();
        int rows = Integer.parseInt(val);

        double val1 = ((double)this.getTotalRows() / this.getRowsPerPage());
        int totalPagesCal = (int)Math.ceil(val1);
        this.setTotalPages((totalPagesCal != 0) ? totalPagesCal : 1);


    public void firstActionListener(ActionEvent actionEvent) {

    public void previousActionListener(ActionEvent actionEvent) {
        this.setCurrentPage(this.getCurrentPage() - 1);
        this.setFirstRow(this.getFirstRow() - this.getRowsPerPage());

    public void nextActionListener(ActionEvent actionEvent) {
        this.setCurrentPage(this.getCurrentPage() + 1);
        this.setFirstRow(this.getFirstRow() + this.getRowsPerPage());


    public void lastActionListener(ActionEvent actionEvent) {
        this.setFirstRow(this.getTotalRows() -
                         ((this.getTotalRows() % this.getRowsPerPage() != 0) ? this.getTotalRows() %
                          this.getRowsPerPage() : this.getRowsPerPage()));

    public boolean isBeforeDisabled() {
        return this.getFirstRow() == 0;

    public boolean isAfterDisabled() {
        return this.getFirstRow() >= this.getTotalRows() - this.getRowsPerPage();

    public void setFirstRow(int firstRow) {
        this.firstRow = firstRow;

    public int getFirstRow() {
        return firstRow;

    public void setRowsPerPage(int rowsPerPage) {
        this.rowsPerPage = rowsPerPage;

    public int getRowsPerPage() {
        return rowsPerPage;

    public void setTotalRows(int totalRows) {
        this.totalRows = totalRows;

    public int getTotalRows() {
        return totalRows;

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;

    public int getTotalPages() {
        return totalPages;

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;

    public int getCurrentPage() {
        return currentPage;

Open CustomPagination.jspx, click on Binding tab and and click on Create control binding and select methodAction for employeesTotalRows as shown in below image.


Open CustomPaginationPageDef.xml and add the below code snippet inside "variableIterator" tag.

<variable Type="int" Name="employeesTotalRows_Return" IsQueriable="false" IsUpdateable="0" DefaultValue="${bindings.employeesTotalRows.result}"/>
Open CustomPagination.jspx,  click on Binding tab and click on Create control binding and select attributeValues and create attribute binding for employeesTotalRows_Return and in Property Inspector change the id to "EmployeesTotalRowCount"


Click on Create control binding and select methodAction for employeesByLimit as shown in below image


Create Tree binding for control of Employees result set.


Click on Create Executable binding and select Invoke action and follow as shown in below image.


Edit TotalRows invoke actiion and set the Refresh to prepareModel, so when ever page loads employeesTotalRows method will get executed.


Go to CustomPagination.jspx Source tab and copy the below code snippet. As mentioned above af:iterator tag to implement the custom table with pagination.

<af:group id="g1">
	<af:panelGroupLayout id="pgl1" layout="scroll">
		<af:spacer width="10" height="10" id="s16"/>
		<af:panelGroupLayout id="pgl9" layout="horizontal">
			<af:spacer width="10" height="10" id="s9"/>
			<af:panelGroupLayout id="pgl10" inlineStyle="width:75px;" layout="horizontal">
				<af:outputText value="Employeed Id" id="ot1" inlineStyle="font-weight:bold;"/>
			<af:spacer width="10" height="10" id="s7"/>
			<af:panelGroupLayout id="pgl7" inlineStyle="width:75px;" layout="horizontal">
				<af:outputText value="First Name" id="ot6" inlineStyle="font-weight:bold;"/>
			<af:spacer width="10" height="10" id="s10"/>
			<af:panelGroupLayout id="pgl11" inlineStyle="width:75px;" layout="horizontal">
				<af:outputText value="Last Name" id="ot4" inlineStyle="font-weight:bold;"/>
			<af:spacer width="10" height="10" id="s11"/>
			<af:panelGroupLayout id="pgl12" inlineStyle="width:75px;" layout="horizontal">
				<af:outputText value="Email" id="ot7" inlineStyle="font-weight:bold;"/>
			<af:spacer width="10" height="10" id="s12"/>
			<af:panelGroupLayout id="pgl15" inlineStyle="width:75px;" layout="horizontal">
				<af:outputText value="Salary" id="ot10" inlineStyle="font-weight:bold;"/>
		<af:separator id="s15"/>
		<af:spacer width="10" height="10" id="s2"/>
		<af:iterator id="i1" value="#{bindings.result.collectionModel}" var="row">
			<af:panelGroupLayout id="pgl2" layout="horizontal">
				<af:spacer width="10" height="10" id="s3"/>
				<af:panelGroupLayout id="pgl3" layout="horizontal" inlineStyle="width:75px;">
					<af:outputText value="#{row.employeeId}" id="ot8"/>
				<af:spacer width="10" height="10" id="s13"/>
				<af:panelGroupLayout id="pgl13" layout="horizontal" inlineStyle="width:75px;">
					<af:outputText value="#{row.firstName}" id="ot11"/>
				<af:spacer width="10" height="10" id="s4"/>
				<af:panelGroupLayout id="pgl4" layout="horizontal" inlineStyle="width:75px;">
					<af:outputText value="#{row.lastName}" id="ot9"/>
				<af:spacer width="10" height="10" id="s6"/>
				<af:panelGroupLayout id="pgl5" layout="horizontal" inlineStyle="width:75px;">
					<af:outputText value="#{}" id="ot2"/>
				<af:spacer width="10" height="10" id="s8"/>
				<af:panelGroupLayout id="pgl8" inlineStyle="width:75px;" layout="horizontal">
					<af:outputText value="#{row.salary}" id="ot3"/>
			<af:spacer width="10" height="10" id="s1"/>
		<af:panelGroupLayout id="pgl6">
			<af:commandButton text="First" id="cb1"
							  partialTriggers="i1" disabled="#{CustomPagination.beforeDisabled}"/>
			<af:commandButton text="Prev" id="cb2"
							  partialTriggers="i1" disabled="#{CustomPagination.beforeDisabled}"/>
			<af:commandButton text="Next" id="cb3"
							  partialTriggers="i1" disabled="#{CustomPagination.afterDisabled}"/>
			<af:commandButton text="Last" id="cb4"
							  partialTriggers="i1" disabled="#{CustomPagination.afterDisabled}"/>
			<af:spacer width="10" height="10" id="s5"/>
			<af:outputText value="Page #{CustomPagination.currentPage} / #{CustomPagination.totalPages}"

Run the CustomPagination.jspx, Now It always displays 10 rows (configurable) in the page. The page provides buttons to navigate between pages and shows current page number. If user is moves to second or third page, navigation buttons for

previous page will be enabled, If we navigate to the last page, navigation buttons for next navigation become disabled and If we navigate to the first page, First and Prev buttons should be disabled.


Friday May 20, 2011

How to call a method defined in AppmoduleImpl using groovy expression?

Usecase Description:

Suppose we have a Transient attribute that stores the value returned by an Appmodule method,then the easy way to call this method in transient attribute would be using Groovy expression.

Consider a simple method in AppmoduleImpl java class that returns the Department name of the selected row of Emp table:

 public String getDeptName(Number dno)

        if (dno == null)
            return null;
        else {
            ViewObject vo = findViewObject("DeptView1");

            try {
                Row row =
                    vo.findByKey(new Key(new Object[] { new oracle.jbo.domain.Number(dno) }),

                if (row != null) {
                    Object name = row.getAttribute("Dname");
                    if (name != null)
                        return name.toString();
                        return null;
                } else
                    return "Specified dept does not exists";
            } catch (Exception e) {
                return null;

Create an Updatable Transient attribute in EmpView Object.Edit its value & provide a groovy expression "adf.object.applicationModule.getDeptName(Deptno)" to call the above method

Run the AppModule & note that the transient attribute returns the Department name corresponding to the selected row of Emp table.


Tips and Tricks from Oracle's JDeveloper & ADF QA


« June 2016