Thursday, September 5, 2013

Pass parameters to a database view

Sometimes you will find that it's better to write a database view instead of a select statement.
Why? For ease of maintenance and reusability.
After develop you application and a requirement came from customer to make a requirement change.
This modification may leads to modify a select statement at all views that use this select.
It will be difficult to go to each view and make the change to the select statement requirement change,
and if the requirement change came after deploy the application you will need to redeploy the application which wast a lot of time.
So it's better to write your queries inside the database as function or procedure or as a database view.
A view may needs to have a parameter such as:

 CREATE OR REPLACE FORCE VIEW EMPLOYEESVIEW  
 AS  
  SELECT ID,NAME FROM EMP WHERE SALARY > 20000;  

20000 can be a variable that needs to be passed to the view.

Views doesn't accept parameters so as a workaround we will use the database session to store that variable. The database view sql  will be:

 CREATE OR REPLACE FORCE VIEW EMPLOYEESVIEW  
 AS  
  SELECT ID,NAME FROM EMP WHERE SALARY > SYS_CONTEXT ('Emp_CTX', 'Salary_Session');  

We need to create a context with name 'Emp_CTX' to set the Salary value,
So I created a procedure called from a package:

 CREATE OR REPLACE  
 PACKAGE Emp_Session_CTX_PKG  
 IS  
  PROCEDURE SET_CONTEXT(  
    IN_NAME VARCHAR2,  
    IN_VALUE VARCHAR2);  
 END Emp_Session_CTX_PKG;  
 create or replace   
 PACKAGE BODY Emp_Session_CTX_PKG  
 IS  
  GC$SESSION_ID VARCHAR2 (100);  
 PROCEDURE SET_CONTEXT(  
   IN_NAME VARCHAR2,  
   IN_VALUE VARCHAR2)  
 AS  
 BEGIN  
  SELECT SYS_CONTEXT('USERENV', 'SESSIONID') INTO GC$SESSION_ID FROM dual;  
   DBMS_SESSION.SET_IDENTIFIER (GC$SESSION_ID);  
  DBMS_SESSION.SET_CONTEXT ('Emp_CTX', IN_NAME, IN_VALUE, USER, GC$SESSION_ID);  
 END;  

Next, call the procedure to set the Salary_Session value :

 Emp_Session_CTX_PKG.set_context('Salary_Session', '20000') ;  
Know you can make a select on the view after setting the parameter ( Salary_Session) :
 SELECT * FROM EMPLOYEESVIEW;  

Sunday, May 26, 2013

Add new department into lookup during adding an employee

While adding a new employee you can select a department for that employee from a List Of Value ( LOV ).
The case is that, the LOV displays all existed departments, But you may want to add a new department not existed in the list for the employee.
a: At the model layer :
1- Create DepartmentsView , EmployeesView then add them at application module.
2- Go to DepartmentsView and write a default expression for the DepartmentId primary key to get a positive number directly when creating a new Department:

The written expression is:
 (new oracle.jbo.server.SequenceImpl("DEPARTMENTS_SEQ",adf.object.getDBTransaction())).getSequenceNumber()  
3- Go to EmployeesView creating a new View Accessor to DepartmentView at EMPLOYEE table.








4- Go to application module to create a method and add it to the client interface by
                                                 Create the Java Class AppModuleImpl:

then write a method that define a single formal parameter           
                                             
      The written code is :
   public void RefreshAndSelect(Number Id){  
     if(Id!=null){  
       EmployeesViewImpl employeesViewImpl= getEmployees1();  
       EmployeesViewRowImpl employeesViewRowImpl = (EmployeesViewRowImpl)employeesViewImpl.getCurrentRow();  
       RowSet rowSetDep= employeesViewRowImpl.getDepartmentsView1();  
       employeesViewRowImpl.getDepartmentsView1().executeQuery();        
       employeesViewRowImpl.setDepartmentId(Id);  
     }  

  Add the created method  RefreshAndSelect  to the application module Client Interface


b: At the ViewController Layer 
We will need to make two Task Flows:
1 - ManageEmployees-Task
2 - Department-Task.
  • We will need two task flows to have the ability to commit each task separately,
Which means that if we created a new employee (Inside ManageEmployees-Task ) then created a new Department inside ( Department-Task ) and click a save button at Department-Task, it will save only the department not the employee and vice versa.

1- First Task Flow (ManageEmployees-Task) :

This task contains a default activity Fragment Page called  EmployeesFrag , this fragment page shows all employees as a table and has a button AddEmp  to add a new Employee.
AddEmp  button has ( CreateInsert ) as ( ActionListener ) and ( addEmp ) as ( Action ) to navigate to the ( EmployeesFormFrag ).


The  ( EmloyeesFormFrag ) contains a form represent employee:  
EmloyeesFormFrag has a button ( AddDept ) that only has Action  ( addDept ) to  navigate to the Department-Task

The Department-Task has a default activity CreateInsert to  create a new record then goes to DepartmentFrag 

DepartmentFrag  contains a form and two buttons that have SetActionListener to set a sesionScope parameter,

OK button set the Id of the new created Department  to a sessionScope parameter (DeptId)

 Cancel button set  the DeptId to null 


Pressing OK will goes to taskFlowReturn1 to Commit the transaction . .

 Pressing Cancel will goes to taskFlowReturn2 to Rollback the transaction.

What makes taskFlowReturn1 commit only the department is the selection of " Always Begin New Transaction " and unchecking of " Share data controls with calling task flow ":



The method RefreshAndSelect will be called if the Ok button is pressed because it sets the the sessionScope parameter to non null value:


The RefreshAndSelect method will be executed with parameter equal to the sessionScope Parameter:


Notes:
  1.  At application module don't make a relation between DepartmentView and EmployeesView.            If you related the EmployeesView with DepartmentsView,  the Employees Page which contain employees table will show the employees of the first department only.
  2. If you used pageflowScope instead of sessionScope the return value would be null.
Download the sample application from here


Saturday, April 27, 2013

ADF Entity Inheritance

Inheritance is a powerful feature of object-oriented development that can simplify development and maintenance when used appropriately.

Your application's database schema might contain tables where different logical kinds of business information are stored in rows of the same table, These tables will typically have one column whose value determines the kind of information stored in each row.

Example1:
Table Persons contains PERSON_TYPE_CODE column whose value are STAFF, CUST, or SUPP  that column determines what kind of PERSON the row represents.

Example2:
Table Departments contains DEPT_TYPE column whose value are Small or Big,  that column determines the size of each department.

To implement Example2 you need to have table Departments in your DB, then at Oracle JDeveloper
Create three entities following by a view for each and put them in your Application Module:

1- Departments - The master entity.


After creating the entity select Discriminator Property checkbox at the DeptType Entity Attribute,


2- BigDepartments - The Child Entity:
                   Click The Button Browse at "Extends Entity" to select the master created Entity Departments,
then click the "next" button

  Click the button "override"
Choose to override the DeptType attribute at the BigDepartments Entity,
then click "Ok" then "Next" button
Make sure that the "Discriminator" Checkbox for DeptType is cheked and readonly,
and type the value for the discriminator for this entity,let it be big,
then click Next till end

3- Small Departments - The second child Entity
    Follow the same steps as BigDepartments Entity


Result:
Record that has value of  DeptType attribute equal to big will exist at the BigDepartmentsView.
                             

Note: 
  • Leaving the discriminator value (at the parent entity) empty means that the view object "DepartmentsView" will bring records that has DeptType value equals to null,

  • If you want to bring all records at the "DepartmentsView" you need to select other views as subtype to the Departmentsview.


You can download my sample application from this link
The Application contains a method Print() at Department Entity Implementation Class and each child entity overrides it and you can put different business code for each type.


java - fill distinct objects in ArrayList

If you have a list that contains some objects that it is considered as duplication when two or three fields of these objects are equal. How ...