Tuesday, September 25, 2012

Oracle ADF Essentials - Faster and Simpler Java-based Application Development - Now Free

Oracle ADF Essentials is an end-to-end Java EE framework that simplifies application development by providing out-of-the-box infrastructure services and a visual and declarative development experience. Oracle ADF Essentials is free to develop and deploy.

More detail go through the link.

Thursday, September 20, 2012

Deploy BC4J/EJB application to GlassFish Server

Now deploying the ADF Faces application to the Glassfish server has become easy, users can directly  deploy the application from JDeveloper itself. Deploying the ADF Faces application to the Glassfish server directly runs with Oracle JDeveloper 11.1.2.3.0 onwards.

Note:- If application has model part then first configure JNDI DataSource, In my previous article I have explained how to "Configure JNDI DataSource for OracleDB in GlassFish Server". 

Implementation Steps for BC4J Application:-
  1. Create a fusion web application.
  2. Goto the ViewController project, right click and select project properties. In Project properties wizard select Deployment and edit the WAR deployment profile.
  3. In Platform selection choose Default Platform as "Glassfish 3.1".
  4. Next go to Application, right click and select project properties. In Project properties wizard select Deployment and edit the EAR deployment profile and in Platform selection choose Default Platform as "Glassfish 3.1".
  5. Open AppModule.xml file and select Configurations tab.
  6. Edit AppModuleLocal and modify the DataSource Name from "java:comp/env/jdbc/OracleDS" to "jdbc/OracleDS"
  7. Create Application Server Connection to Glassfish server.
  8. Select application, deploy the EAR file directly to the Glassfish server.
Note: - Above Default Platform determines the platform-specific behavior when packaging the archive for deployment to an Application Server.

Implementation Steps for EJB/JPA Application:-
  1. Create a fusion web application.
  2. Goto the Model project, right click and select project properties. In Project properties wizard select Deployment and edit the JAR deployment profile and in Platform selection choose Default Platform as "Glassfish 3.1".
  3. Goto the ViewController project, right click and select project properties. In Project properties wizard select Deployment and edit the WAR deployment profile and in Platform selection choose Default Platform as "Glassfish 3.1".
  4. Next go to Application, right click and select project properties. In Project properties wizard select Deployment and edit the EAR deployment profile and in Platform selection choose Default Platform as "Glassfish 3.1".
  5. Open persistence.xml file and select Model->Persistence Unit->Connection tab.
  6. In General selection, in JTA DataSource modify "java:/app/jdbc/jdbc/OracleDS" to "jdbc/OracleDS"
  7. In JTA Properties selection, in JTA DataSource Property modify "java:/app/jdbc/jdbc/OracleDS" to "jdbc/OracleDS"
  8. Application like EJB which requires jndi lookup's, we have to change the initial context factory class name. Open the DataControls.dcx file, In ejb-definition tag modify the initial-context-factory class name from "weblogic.jndi.WLInitialContextFactory" to "com.sun.enterprise.naming.SerialInitContextFactory"
  9. Create Application Server Connection to Glassfish server.
  10. Select application, deploy the EAR file directly to the Glassfish server.

Tuesday, September 4, 2012

EJB DataControl - JPA Single Table Inheritance

JPA supports three types of inheritance, In this article will try "single table inheritance using EJB datacontrol". For more information on JPA inheritance go through the link.

In single table inheritance, a single table is used to store all of the instances of the entire inheritance hierarchy. The table will have a column for every attribute of every class in the hierarchy. A discriminator column is used to determine which class the particular row belongs to, each class in the hierarchy defines its own unique discriminator value.

Table Structure: -


Model Diagram:-


In the above example the discriminator column (SEX) is added to the table to distinguish between the Men and Women instances.

You can download the sample workspace from here
[Runs with Oracle JDeveloper 11.1.2.2.0 + HR Schema]
Note: - You can find the sql file in application JPASingleTableApp/etc/ folder

Implementation Steps:-

Lets create a Fusion Web Application with Entities based on Person, edit the Person.java entity and remove the menAttr, womenAttr attributes.  Add the below annotation in Person entity.

@Table(name="PERSON")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="SEX", discriminatorType=DiscriminatorType.STRING,length=1)

Create an entity Men by extending the Person and add the below code.
@Entity
@Table(name = "PERSON")
@DiscriminatorValue("M")
@NamedQueries( { @NamedQuery(name = "Men.findAll", query = "select o from Men o") })
public class Men extends Person implements Serializable {
    @Column(name = "MEN_ATTR")
    private String menAttr;

    public Men() {
    }

    public String getMenAttr() {
        return menAttr;
    }

    public void setMenAttr(String menAttr) {
        this.menAttr = menAttr;
    }
}

Create an entity Women by extending the Person and add the below code.
@Entity
@Table(name = "PERSON")
@DiscriminatorValue("W")
@NamedQueries( { @NamedQuery(name = "Women.findAll", query = "select o from Women o") })
public class Women extends Person implements Serializable {
    @Column(name = "WOMEN_ATTR")
    private String womenAttr;

    public Women() {
    }

    public String getWomenAttr() {
        return womenAttr;
    }

    public void setWomenAttr(String womenAttr) {
        this.womenAttr = womenAttr;
    }
}

Next create a Session Bean and data control for the Session Bean and in ViewController project create a jspx page and drop menFindAll, womenFindAll as separate Table->ADF Read only Table. Run the jspx page and web page will be displayed as shown in below image, table bound to menFindAll should display only men records and table bound to womenFindAll should display only women records.

Thursday, August 30, 2012

Configure JNDI DataSource for OracleDB in GlassFish Server

In this article will see how to "Configure JNDI DataSource for Oracle in GlassFish 3.2 Server".

Login to Glassfish admin console in browser window, Once its open, in the left-hand side panel under Resources, click on JDBC and then JDBC Connection Pools. In the right hand-side click on new button will open the "New JDBC Connection Pool" window, enter the details as shown in below image.


Note: To store, organize, and retrieve data, most applications use relational databases. Java EE applications access relational databases through the JDBC API. Before an application can access a database, it must get a connection. JDBC resources provide applications with a means to connect to a database.

Clicking on Next button will display as shown in below image.


In same "New JDBC Connection Pool" window, in Additional Property section add the properties details as shown in below image.


Click on ping to test if the pool is created successfully. If not successful, check all the properties again.


Now under Resources, click on JDBC and then JDBC Resources. In the right hand-side click on new button will open the "New JDBC Resource" window, enter the details as shown in below image.

Tuesday, August 7, 2012

How many rows Modified/Added in ADF Table

I was reading through OTN Discussion Forums where I found one topic "How many rows were Modified/Added in ADF Table by the user". Jobinesh has written article on "Displaying Transaction Log When User Commits a Transaction" which explains how to get the entity status, above example overrides EntityImpl::doDML(int operation, TransactionEvent e) method to track the status of entities.

I was trying to get Modified/Added rows in EJB DataControl but above suggested solution can't be implemented, because application module in not supported in EJB. So in this article I'm trying to get the entity status in backing bean using BC4J, in my next article I will try to explain on how to achieve the same scenario using EJB.

Results page looks like below.


You can download the sample workspace from here
[Runs with Oracle JDeveloper 11.1.2.2.0 + HR Schema]

Implementation Steps:

Create Fusion Web Application with business components from tables based Employees table, open Employees.xml and select Java tab. Generate EmployeesImpl and add the below code in create method to generate sequence number for employee id using SequenceImpl class.
/**
 * Add attribute defaulting logic in this method.
 * @param attributeList list of attribute names/values to initialize the row
 */
protected void create(AttributeList attributeList) {
	super.create(attributeList);
	SequenceImpl seq = new SequenceImpl("EMPLOYEES_SEQ", getDBTransaction());
	Number seqNextval = seq.getSequenceNumber();
	setEmployeeId(seqNextval);
}
Open the EmployeesView and select Java tab, generate EmployeesViewImpl class.

In ViewController project, create index.jspx page and backingbean as "IndexBean" with scope as "ViewScope". Open the IndexBean and copy the below method code.
private RichTable empTable;
private List selectedEmpArray = new ArrayList();
private int modifiedRows = 0;
private int newRows = 0;

public IndexBean() {
}

public void setEmpTable(RichTable empTable) {
	this.empTable = empTable;
}

public RichTable getEmpTable() {
	return empTable;
}

public void setModifiedRows(int modifiedRows) {
	this.modifiedRows = modifiedRows;
}

public int getModifiedRows() {
	return modifiedRows;
}

public void setNewRows(int newRows) {
	this.newRows = newRows;
}

public int getNewRows() {
	return newRows;
}

/**
 * Get the selected rowKey
 * Add the rowKey to selectedEmpArray arrayList
 * @param selectionEvent
 */
public void empSelectionEvent(SelectionEvent selectionEvent) {
	RowKeySet empRKS = selectionEvent.getAddedSet();
	if (empRKS.size() > 0) {
		Iterator empRKSIterator = empRKS.iterator();
		while (empRKSIterator.hasNext()) {
			Key key = (Key)((List)empRKSIterator.next()).get(0);
                        //Add the key if not existed in selectedEmpArray
			if (!selectedEmpArray.contains(key)) {
				selectedEmpArray.add(key);
			}
		}
	}
}

public BindingContainer getBindings() {
	return BindingContext.getCurrent().getCurrentBindingsEntry();
}

/**
 * While loop the selectedEmpArray
 * Get the entity status for the rowKeys
 * @param actionEvent
 */
public void fetchModifiedRows(ActionEvent actionEvent) {
	if (selectedEmpArray.size() > 0) {
		//Resetting the row counts
		this.setModifiedRows(0);
		this.setNewRows(0);

		DCBindingContainer dcBindings = (DCBindingContainer)getBindings();
		DCIteratorBinding EmpsDCIterBinding = dcBindings.findIteratorBinding("EmployeesView1Iterator");
		RowSetIterator EmpsRSIter = EmpsDCIterBinding.getRowSetIterator();
		ViewObject vo = EmpsDCIterBinding.getViewObject();

		Iterator selectedEmpsIter = selectedEmpArray.iterator();
		while (selectedEmpsIter.hasNext()) {
			Row currentRow = EmpsRSIter.getRow((Key)selectedEmpsIter.next());
			EmpsRSIter.setCurrentRow(currentRow);

			ViewRowImpl myRow = (ViewRowImpl)vo.getCurrentRow();
			EntityImpl entityImpl = (EntityImpl)myRow.getEntity(0);
			if (EntityImpl.STATUS_MODIFIED == entityImpl.getEntityState()) {
				this.setModifiedRows((this.getModifiedRows() + 1));
			} else if (EntityImpl.STATUS_NEW == entityImpl.getEntityState()) {
				this.setNewRows((this.getNewRows() + 1));
			}
		}
	}
	//Commit the transaction
	commitAction();
}

public String commitAction() {
	BindingContainer bindings = getBindings();
	OperationBinding operationBinding = bindings.getOperationBinding("Commit");
	Object result = operationBinding.execute();
	if (!operationBinding.getErrors().isEmpty()) {
		return null;
	}
	return null;
}

/**
 * CreateInsert new row and get rowKey for the added row
 * Add the rowKey to the selectedEmpArray arrayList
 * @param actionEvent
 */
public void createNewRow(ActionEvent actionEvent) {
	BindingContainer bindings = getBindings();
	OperationBinding oper = bindings.getOperationBinding("CreateInsert");
	oper.execute();

	DCBindingContainer dcBindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
	DCIteratorBinding EmpsIter = dcBindings.findIteratorBinding("EmployeesView1Iterator");
	EmployeesViewImpl eImpl = (EmployeesViewImpl)EmpsIter.getViewObject();
        //Add the key if not existed in selectedEmpArray
	if (!selectedEmpArray.contains(eImpl.getCurrentRow().getKey())) {
		selectedEmpArray.add(eImpl.getCurrentRow().getKey());
	}
}
Note:- Here createInsert is model driven component, when user clicks on the Create button the selectionListener will not be executed for the first time. So in the above createNewRow method,  the rowKey value will be added to selectedEmpArray.

Open index.jspx page.
  • From datacontrol palette drag and drop EmployeesView1->Table as ADF Table with rowSelection as multiple.
  • Surround the table with panel collection and add toolbar in that.
  • Bind the empolyees table as binding="#{viewScope.IndexBean.empTable}"
  • Set the SelectionListener as "#{viewScope.IndexBean.empSelectionEvent}"
  • Go to Bindings tab and Create Action Binding, Data Collection as EmployeesView1 and Operation as CreateInsert.
  • From component palette drop af:commandButton and set actionListener as "#{viewScope.IndexBean.createNewRow}".
  • Go to Bindings tab and Create Action Binding, Data Collection as AppModuleDataControl and Operation as Commit.
  • From component palette drop af:commandButton and set actionListener as #{viewScope.IndexBean.fetchModifiedRows}, disabled as "#{!bindings.Commit.enabled}", partialSubmit as "true".
  • Add af:outputLabel and value as "No of Rows Modified -  #{viewScope.IndexBean.modifiedRows}", partialTriggers to commit button.
  • Add af:outputLabel and value as "No of Rows Newly added - #{viewScope.IndexBean.newRows}",  partialTriggers to commit button.

Thursday, July 12, 2012

Bean Data Control - Create Simple Search Form

In Oracle ADF, search form can be created with BC4J/EJB model using "View Criteria/Named Criteria" by dropping "af:query" component in view layer. Here in this article, I'm trying to build simple search form based on bean data control.

The Results page look like below.


Enter the Department Id in search form and click search button will filter results.


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

Implementation Steps

Create Fusion Web application, in model project create Employees java class. Open Employees.java and add the below code.
public class Employees {
    private Integer employeeId;
    private String firstName;
    private String lastName;
    private String email;
    private String phoneNo;
    private Date hireDate;
    private String jobId;
    private Integer salary;
    private Integer departmentId;

    public Employees() {
        super();
    }

    public Employees(int employeeId, String firstName, String lastName, String email, String phoneNo, Date hireDate,
                     String jobId, int salary, int departmentId) {
        this.setEmployeeId(employeeId);
        this.setFirstName(firstName);
        this.setLastName(lastName);
        this.setEmail(email);
        this.setPhoneNo(phoneNo);
        this.setHireDate(hireDate);
        this.setJobId(jobId);
        this.setSalary(salary);
        this.setDepartmentId(departmentId);
    }

    public void setEmployeeId(Integer employeeId) {
        this.employeeId = employeeId;
    }

    public Integer getEmployeeId() {
        return employeeId;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }

    public void setPhoneNo(String phoneNo) {
        this.phoneNo = phoneNo;
    }

    public String getPhoneNo() {
        return phoneNo;
    }

    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }

    public Date getHireDate() {
        return hireDate;
    }

    public void setJobId(String jobId) {
        this.jobId = jobId;
    }

    public String getJobId() {
        return jobId;
    }

    public void setSalary(Integer salary) {
        this.salary = salary;
    }

    public Integer getSalary() {
        return salary;
    }

    public void setDepartmentId(Integer departmentId) {
        this.departmentId = departmentId;
    }

    public Integer getDepartmentId() {
        return departmentId;
    }
}
Create PopulateData java class, open PopulateData.java and add the below code.
public class PopulateData {
    private static List allEmployees;
    static {
        allEmployees = new ArrayList();
        allEmployees.add(new Employees(100, "Steven", "King", "SKING", "515.123.4567", new Date(), "AD_PRES", 24000,
                                       20));
        allEmployees.add(new Employees(101, "Neena ", "Kochhar", "NKOCHHAR", "515.123.4568", new Date(), "AD_VP",
                                       17000, 90));
        allEmployees.add(new Employees(102, "Lex", "De Haan", "AHUNOLD", "515.423.4567", new Date(), "IT_PROG", 15000,
                                       90));
        allEmployees.add(new Employees(103, "Alexander", "Hunold", "AHUNOLD", "515.423.4567", new Date(), "IT_PROG",
                                       10000, 20));
        allEmployees.add(new Employees(104, "Bruce", "Ernst", "BERNST", "515.423.4568", new Date(), "IT_PROG", 5000,
                                       50));
        allEmployees.add(new Employees(105, "David", "Austin", "DAUSTIN", "515.423.4569", new Date(), "IT_PROG", 7000,
                                       30));
        allEmployees.add(new Employees(106, "Valli", "Pataballa", "VPATABAL", "515.423.4560", new Date(), "IT_PROG",
                                       8000, 50));
        allEmployees.add(new Employees(107, "Diana", "Lorentz", "DLORENTZ", "515.423.5567", new Date(), "IT_PROG",
                                       9000, 50));
        allEmployees.add(new Employees(108, "Nancy", "Greenberg", "NGREENBE", "515.124.4569", new Date(), "FI_MGR",
                                       10000, 100));
        allEmployees.add(new Employees(109, "Daniel", "Faviet", "DFAVIET", "515.124.4169", new Date(), "FI_ACCOUNT",
                                       13000, 100));
        allEmployees.add(new Employees(110, "John", "Chen", "JCHEN", "515.124.4269", new Date(), "FI_ACCOUNT", 14000,
                                       100));
        allEmployees.add(new Employees(111, "Ismael", "Sciarra", "ISCIARRA", "515.124.4369 ", new Date(), "FI_ACCOUNT",
                                       12000, 60));
        allEmployees.add(new Employees(112, "Jose Manuel", "Urman", "JMURMAN", "515.124.4469", new Date(),
                                       "FI_ACCOUNT", 4000, 60));
        allEmployees.add(new Employees(112, "Jose Manuel", "Urman", "JMURMAN", "515.124.4469", new Date(),
                                       "FI_ACCOUNT", 7800, 60));
        allEmployees.add(new Employees(113, "Luis", "Popp", "LPOPP", "515.124.4567", new Date(), "FI_ACCOUNT", 6900,
                                       70));
        allEmployees.add(new Employees(114, "Den", "Raphaely", "DRAPHEAL", "515.127.4561", new Date(), "PU_MAN", 11000,
                                       90));
    }

    public PopulateData() {
        super();
    }

    public static List getAllEmployees() {
        return allEmployees;
    }
}
Create EmployeeServicejava class, open EmployeeService.java and add the below code. Create data control from EmployeeService Bean class.
public List filterByDeptId(Integer departmentId) {
        try {
            List allEmployees = PopulateData.getAllEmployees();
            if (departmentId != null) {
                List filteredEmployees = new ArrayList();
                for (Employees e : allEmployees) {
                    if (e.getDepartmentId() == departmentId) {
                        filteredEmployees.add(e);
                    }
                }
                return filteredEmployees;
            } else {
                return allEmployees;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
}

public List getAllEmployees() {
    return PopulateData.getAllEmployees();
}
In ViewController project, create jspx page and from data control palette
  1. Drop filterByDeptId as ADF Method Parameter
  2. Drop filterByDeptId->Employees->Table as ADF Read-only Table

Monday, July 2, 2012

How to add a new row at the end of the ADF Table

I was reading through OTN Discussion Forums where I found one topic "How to add a new row at the end of the ADF Table", I found couple of articles which explains how to insert new rows to the end of ADF Table. Here is the list below.

Here is one more way to insert new rows to the end of ADF table by overriding the view object's(ViewImpl) insertRow() method.
/**
 * This method will overrides the view object's insertRow()
 * First create a new row
 * Removes the row from the collection and then retain it for insertion into another location.
 * Navigates to the last row in the row set.
 * Navigates to next row
 * Inserts the same row to the row set
 * @param row
 */
@Override
public void insertRow(Row row) {
 super.insertRow(row);
 row.removeAndRetain();
 last();
 next();
 getDefaultRowSet().insertRow(row);
}

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

Run the index.jspx page and navigate the departments records, now click on Create button. Notice in employee table new row is added to end of the ADF Table.