Thursday Apr 19, 2012

Display Lookup values from related ejb entities using JOIN FETCH

JOIN FETCH - The purpose of JOIN FETCH is to fetch the related objects from the database in a single query. So in this article, I'm trying to explain how can we use jpql JOIN FETCH and expose those attributes to EJB data control layer.

Take a scenario, where we need to build ADF tree based on departments,employees and location tables. While displaying the tree, root node should display departmentName along with city attribute which is stored in related object Location table.

Model Diagram:

EJBJFA-Model.png


In BC4J, this scenario can be implemented using Entity Objects facility provided in View Object layer. These entity objects are used by the view object for accessing the related objects attributes and will be exposed in data control layer automatically.

Same behavior can be implemented in EJB using JOIN FETCH. Using this query improves the efficiency of iteration over the result Departments objects because it eliminates the need for retrieving the associated Location objects separately.So in single query related objects attributes is also fetched from the database.

You can download the sample workspace from here
[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2) + HR Schema]

Implementation Steps

Create Java EE Web Application with entities based on Departments, Employees and Location table, then create a session bean and data control for the session bean.

Open the departments entity and alter the named query as below.

@NamedQuery(name = "Departments.findAll",
                             query = "select o from Departments o join fetch o.locations")

Note:- The query above returns Departments instances and guarantees that the locations attributes will already be fetched in the returned instances.

Now we need to expose the location attribute values to data control, create a Transient variable called "city" and add the below code in department entity.

@Transient
 private String city;
	
public String getCity() {
  return this.locations.getCity();
}

Note: Can create sample java client to check whether the city attribute value is coming in departments instance before proceeding to data control.

In the ViewController create index.jspx page, from data control palette drop departmentsFindAll->Tree as ADF Tree and in edit tree bindings select the attributes as shown in below image.

EJBJFA-DeptBinding.png


Run the index.jspx page. Now notice root node will display departmentName along with city attribute value also.

EJBJFA-output.png

Thursday Sep 15, 2011

AutoSuggest behavior In ADF Using EJB

AutoSuggest feature somewhat expected feature, nowadays that most of the top sites have implemented this functionality. This feature makes your site as user friendly and easy to navigate in inputText feature.

AutoSuggest behavior in ADF adds a pull-down menu of suggested values to a text field. The user can either click directly on a suggestion to enter it into the field, or navigate the list using the up and down arrow keys, selecting a value using the enter key.

Lets create a Java EE Web Application with Entities based on Departments, edit the Departments.java entity and add the below code.

@NamedQuery(name = "Departments.filteredValues",
            query = "select o from Departments o where o.departmentName like CONCAT(:deptName,'%')

Create a Stateless Session Bean and data control for the Stateless 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.

/** select o from Departments o where o.departmentName like CONCAT(:deptName,'%') */
public List<String> getDepartmentsFilteredValues(String deptName) {
   //To store the resultset
   List<String> deptNameResultset = new ArrayList<String>();
   Query query = em.createNamedQuery("Departments.filteredValues").setParameter("deptName", deptName);
   Vector result = (Vector)query.getResultList();
   int resultSize = result.size();
   for (int i = 0; i > resultSize; i++) {
      Departments dept = (Departments)result.get(i);
      deptNameResultset.add(dept.getDepartmentName());
   }
   return deptNameResultset;
}
In the ViewController create a file AutoSuggest.jspx page, from component palette drag and drop <af:inputText/> and in PI palette change the label to Dept Name. Add the autoSuggestBehavior tag to the inputText. Click on the autoSuggestBehavior, in  PI palette click on Edit property for Suggested Items and create a "AutoSuggest" managed bean with scope as "request" as shown in below Image.

AutoSuggestBean.png


Create new method as deptNameResultList and click ok.

AutoSuggestBeanMethod.png


In AutoSuggest.jspx page, go to binding tab and click create binding by selecting methodAction and click ok with parameter blank as shown in below image

FilteredValuesBinding.png


Open AutoSuggest.java managed bean and paste the below code.

public List deptNameResultList(String paramValue) {
  //Store the deptName result set
  List<SelectItem> deptResultList = new ArrayList<SelectItem>();
  //Filter the values using Items List
  List<SelectItem> items = new ArrayList<SelectItem>();
        
  BindingContainer bindings = getBindings();
  //Execute the Method
  OperationBinding operationBinding = bindings.getOperationBinding("getDepartmentsFilteredValues");
  //Populate the deptName parameter 
  operationBinding.getParamsMap().put("deptName", paramValue);
  operationBinding.execute();
  if (operationBinding.getResult() != null) {
      operationBinding.getResult();
      ArrayList result = (ArrayList)operationBinding.getResult();
      int resultSize = result.size();
      for (int i = 0; i < resultSize; i++) {
         deptResultList.add(new SelectItem(result.get(i)));
      }
   }
   for (SelectItem item : deptResultList) {
     if (item.getLabel().startsWith(paramValue)) {
          items.add(item);
     }
   }
  return items;
}

public BindingContainer getBindings() {
   return BindingContext.getCurrent().getCurrentBindingsEntry();
}
Run AutoSuggest.jspx, Dept Name text field will be displayed. As soon as the user has typed a character, a filtered list of suggested values is presented( for ex: C), Now traverse the list by using up and down arrow and select a suggested value from the list and thus applying that value to the inputText component.
 
AutoSuggestResult.png

Wednesday Aug 03, 2011

Passing parameter to EJB Method in taskflow

This article describes on passing parameter to EJB Method in taskflow.

Use Case Description

Suppose we have a table displaying Dept records.Table also has column link & clicking on this link displays a region in popup.This region accepts deptno parameter,executes EJB Method & displays respective Emp details in a popup.

Implementation steps

Let us suppose that we have created Java EE Web Application with Entities from Emp & Dept table .Also add 'ADF Faces Components 11' under ViewController->project properties-> JSP Tag Libraries.

Edit Emp.java & create a custom named query that returns Emp Object for the respective deptno :


 @NamedQuery(name = "findEmpByDeptno", query = "select o from Emp o
 where o.dept.deptno = :deptNo")
Let us create Stateful Session Bean and expose the Named Query through the Session Facade.Our use case deals with passing parameters to EJB method in taskflow.So we will define simple EJB method that just accepts deptno parameter & stores its value in private variable:
   
 public void passDeptno(BigDecimal deptNo) 
 {
 this.setDepartNo(deptNo);
 }

Now that we have separate method to accept parameter we will modify findEmpByDeptno namedQuery as below:

 public List<Emp> findEmpByDeptno() 
{
 
 return em.createNamedQuery("findEmpByDeptno").setParameter
 ("deptNo", this.getDepartNo()).getResultList();
}

Generate Data control for the above Session Bean & expose the above method through the Session Facade.

Create a ADF taskflow with page Fragments & create an inputParameter 'inputParameter1' in its overview parameters tab:

adf_taskflow.JPG










taskflow_param.JPG
Drop passDeptno(BigDecimal) as Method Call activity with value as
#{pageFlowScope.inputParameter1}.Drop findEmpByDeptno()->Operations->execute operation as Method Call activity & then drop  emp view activity on the taskflow.Define all control flows.

taskflow2.jpeg
Create emp.jsff page fragment & drop findEmpByDeptno()->Emp as ADF Table with single row selection

emp_tab.JPG


Now we will create main.jspx page & drop deptFindAll as ADF table with single row selection on this.We will also create deptno attribute bindings in page definition file:

attribute.JPG
Insert a new column inside the table that displays Emp Details.Drop the above created taskflow as region inside the column.Pass '#{sessionScope.deptno}' value for inputParameter1 & set the taskflow's ifNedded property to 'Refresh'.Here we are using setPropertyListener to pass parameter to taskflow method:

<af:column id="c4" headerText="Emp details">
<af:commandLink text="Emp details" id="cl1">
<af:showPopupBehavior popupId="p1"/>
</af:commandLink>
<af:popup id="p1" contentDelivery="lazyUncached">
<af:dialog id="d2" title="Emp Details" type="none">
<af:region
 value="#{bindings.taskflowdefinition1.regionModel}"
id="r1"/>
</af:dialog>
<af:setPropertyListener type="popupFetch"
from="#{bindings.deptno.inputValue}"
to="#{sessionScope.deptno}"/>
</af:popup>
</af:column>

Run the page,it shows Dept records.Select any dept record & click on 'Emp Details' link.It shows popup with its respective Emp records


About

Tips and Tricks from Oracle's JDeveloper & ADF QA

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today