Showing posts with label JPA. Show all posts
Showing posts with label JPA. Show all posts

Sunday, May 19, 2013

ADF Mobile With EJB Restful Web Service

This article is the continuation of my previous article on Configuring EJB with Restful Web Service in ADF. Here will see how to integrate EJB Restful Web Service with ADF mobile.

Application screen looks like below when it is deployed and run on the Android Device/Emulator. In the below screen Department list will be displayed.


Clicking on any department will take you to the selected Department details page, edit the details and click on the Save button to submit the data. Clicking on delete button will delete the current department.


From Department List screen, click on add button to add the new record. Enter the details and click on Save button to submit the data.


After the below actions, updated department result page will be displayed as shown below.


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

Implementation Steps

Create an ADF Mobile Application, the application consists of two projects. Application Controller project of Application LifeCycle, Listeners, Device Features DataControl and ViewController project contains mobile features content like AMX Files, Task Flows and DataControl.

In Application Controller project, create a Departments.java file and add the below code.
public class Departments {
    private BigDecimal departmentId;
    private String departmentName;
    private BigDecimal locationId;
    private BigDecimal managerId;

    public Departments() {
        super();
    }

    public Departments(BigDecimal departmentId, String departmentName, BigDecimal locationId, BigDecimal managerId) {
        this.departmentId = departmentId;
        this.departmentName = departmentName;
        this.locationId = locationId;
        this.managerId = managerId;
    }

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

    public BigDecimal getDepartmentId() {
        return departmentId;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    public String getDepartmentName() {
        return departmentName;
    }

    public void setLocationId(BigDecimal locationId) {
        this.locationId = locationId;
    }

    public BigDecimal getLocationId() {
        return locationId;
    }

    public void setManagerId(BigDecimal managerId) {
        this.managerId = managerId;
    }

    public BigDecimal getManagerId() {
        return managerId;
    }
}
Create DepartmentsDC.java file and add the below code, create DataControl based on DepartmentsDC file
public class DepartmentsDC {
    public DepartmentsDC() {
        super();
    }

    public Departments ediDepartment(BigDecimal departmentId, String departmentName, BigDecimal locationId,
                                     BigDecimal managerId) {
        return new Departments(departmentId, departmentName, locationId, managerId);
    }

    public Departments addDepartment() {
        BigDecimal defaultVal = new BigDecimal("0");
        return new Departments(defaultVal, "", defaultVal, defaultVal);
    }
}
In the New Gallery expand the General - XML nodes and select XML Schema and click OK, enter Departments.xsd in File Name field and the following attributes as shown in below image.


In the New Gallery expand the General - Connection nodes and select URL Connection and click OK, enter the URL Endpoint details, You can download Configuring EJB with Restful Web Service in ADF from my previous article.


Note: - Next create a URL Service Data Control from - http://IpAddress:7101/EJBRestService/jersey/EJBRESTService api with HTTP Methods: GET, PUT, POST, DELETE.

In the New Gallery expand the General - Data Control nodes and select URL Service Data Control and click OK and enter the details to create the GET method


In the New Gallery expand the General - Data Control nodes and select URL Service Data Control and click OK and enter the details to create the POST method.


In Create URL Service Data Control wizard - step 3 of 5, specify the XSD url which we created earlier.


In the New Gallery expand the General - Data Control nodes and select URL Service Data Control and click OK and enter the details to create the PUT method.


In Create URL Service Data Control wizard - step 3 of 5, specify the XSD url which we created earlier.


In the New Gallery expand the General - Data Control nodes and select URL Service Data Control and click OK and enter the details to create the DELETE method.


In Create URL Service Data Control wizard - step 3 of 5, enter the departmentId value as 0.


Next open the DataControls.dcx file and change the Definition id values to looks like below.


In ViewController project. Locate and expand the Application Sources folder, then expand the META-INF folder. You will see the adfmf-feature.xml file, click on the adfmf-feature.xml file to launch the Feature editor. Add a new feature by clicking the green plus sign on the Features table near top of the editor this will launch the new Create ADF Mobile Feature dialog, modify the values as shown below.


In the Features table, select the newly created feature Departments. Under the Features table, click the Content tab, and locate the Content table. Notice that the content item Departments.1 is created by default. Next add a new file by clicking the green plus sign and select taskflow option, this will launch the new Create ADF Mobile Task Flow dialog, modify the value as shown below.


Click on the DepartmentsTaskflow.xml to open the file in taskflow editor and follow the below steps.
  • Create three views and name them as deptList, deptAdd and deptEdit respectively
  • Draw the control flow case from deptList to addDept and Outcome as "add"
  • Draw the control flow case from deptList to editDept and Outcome as "edit" 
  • From DataControl palette drag and drop getDepartmentsFindAll and drop as method-call
  • Draw the control flow case from getDepartmentsFindAll method-call to deptList and Outcome as "getDepartmentsFindAll"
  • Draw the control flow case from addDept to getDepartmentsFindAll method-call and Outcome as "list"
  • Draw the control flow case from editDept to getDepartmentsFindAll method-call and Outcome as "list"
DepartmentsTaskflow.xml will looks as shown below diagram.


Double click on deptList view will launch Create ADF Mobile AMX Page dialog, in page facets select Header and Secondary Action. Go to source tab and follow the below steps:
  • In Header facet, amx:outputText set the value as "Dept List"
  • In Secondary Action facet, for amx:commandButton modify the values text: Add, action: add
  • From DC palette drag and drop EJBService->getDepartmentsFindAll()->Return->departmentss->departments->ADF Mobile List View and select the default options
  • In amx:Item, set the action as "edit"
  • Inside amx:Item set the setPropertyListener as shown below

Note:- Created the DataControl DepartmentsDC with addDepartment and editDepartment methods, so that the type casting the ADF form values to departments object will be easy.

Double click on deptAdd view will launch Create ADF Mobile AMX Page dialog, in page facets select Header, Primary Action. Go to source tab and follow the below steps:
  • In Header facet, amx:outputText set the value as "Add Dept"
  • In Primary Action facet, for amx:commandButton modify the values text: Back, action: __back
  • From DC palette drag and drop DepartmentsDC->addDepartment->Departments->Form as ADF Mobile Form.
  • Go to bindings and add the following attributesValues, departmentId, departmentName, locationId, managerId as shown below.
  • From DC palette drag and drop postDepartments->Method as ADF Mobile Button, set name as "Save", action as "list" and set the setPropertyListener as shown below 

Double click on deptAdd view will launch Create ADF Mobile AMX Page dialog, in page facets select Header, Primary, Secondary Action. Go to source tab and follow the below steps:
  • In Header facet, amx:outputText set the value as "Edit Dept"
  • In Primary Action facet, for amx:commandButton modify the values text: Back, action: __back
  • In Secondary Action facet,  from DC palette drag and drop EJBService->deleteDepartments->Method as ADF Mobile Button, set action as "list". In Edit Action Binding wizard mention the parameter for departmentId as #{pageFlowScope.departmentId}
  • From DC palette drag and drop DepartmentsDC->editDepartment->Departments->Form as ADF Mobile Form and in edit action binding wizard mention the parameters as shown below
  • Go to bindings and add the following attributesValues, departmentId, departmentName, locationId, managerId as shown below.
  • From DC palette drag and drop putDepartments->Method as ADF Mobile Button, set name as "Save", action as "list" and set the setPropertyListener as shown below.

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.

Monday, June 25, 2012

Simulate JPA Dynamic Query Using View Criteria

Recently I'm working in an application where JPA entity has a named query with parameters passed to that query and exposed as EJB data control, here parameter is passed dynamically at run time. Now same data control is dropped as ADF table, where user can add new rows to the table and perform merge/persist operations.

JPA API provides an alternative way for defining JPA queries, which is mainly useful for building dynamic queries whose exact structure is only known at run time. Building a dynamic query based on fields that a user fills at run time in a form that contains many optional fields. 


In this article, I'm trying to Simulate JPA Dynamic Query Using View Criteria to filter ADF Table and perform merge/persist operations on ADF Table. Below solution is the workaround to achieve the above scenario using EJB data control.

In EJB data control doesn't create any application module or neither have access to application module Api's directly. When the ViewObject is accessed based on the Iterator a dummy object is created using DCDataVo Api.  DCDataVo provides little leverage to access certain model layer functionality, so that all Adapter Data Control can use the DCDataVo api to extend to build custom features.

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 with entities based on Emplo, then create a session bean and data control for the session bean.

In the ViewController create index.jspx page and create a IndexBean.java as backing bean, follow the below steps:
  • From data control palette drag and drop EmployeesFindAll()->Table as ADF Table.
  • Drop  EmployeesFindAll()->Operations->Create as ADF Button, name as "Commit".
  • Drop the persistEmployees as ADF button and bind the value to "#{bindings.employeesFindAllIterator.currentRow.dataProvider}"
  • From component palette drop Input Text and label as "Department Id"
  • Drop Button, name as "Search" and ActionListener method as "executeSearch"
Open the IndexBean.java and copy the below method code.

/**
 * This method will get the View Object based on Iterator
 * Creates the view crietria at the runtime,
 * Set the Operator type and pass the paramater 
 * Execute the View Object, print results to the web screen.
 * @param actionEvent
 */
public void executeSearch(ActionEvent actionEvent) {
 DCBindingContainer dcBindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
 DCIteratorBinding deptIter = dcBindings.findIteratorBinding("employeesFindAllIterator");
 // Getting the dummy ViewObject based on Iterator
 ViewObject vo = deptIter.getViewObject();
 // Create the viewCriteria at runtime
 ViewCriteria vc = vo.createViewCriteria();
 ViewCriteriaRow vcRow = vc.createViewCriteriaRow();
 // ViewCriteriaRow attribute value requires operator and value.
 // Note also single-quotes around string value.
 ViewCriteriaItem vcRowItem = vcRow.ensureCriteriaItem("departmentId");
 vcRowItem.setOperator("=");
 vcRowItem.getValues().get(0).setValue(this.getDeptId().getValue());
 vc.addElement(vcRow);
 vo.applyViewCriteria(vc);
 // Execute the query
 vo.executeQuery();
}

Run the index.jspx page and result page looks like below.


Now enter department Id in input text field and click on search button, Employees table will be filtered by department id. Now click on create button to add new rows to the particular searched department, notice a new row is created in the table. Enter the field values and save the record, here if you want to generate employee id as auto generated one then configure @Table Generator for employee id. 

Saturday, May 19, 2012

EJB DataControl - Configuring Sequential ids using JPA @TableGenerator

In this article I'm trying to explain how JPA feature used to generate and assign the unique sequence numbers to JPA entity using @TableGenerator.

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 with entities based on Departments, then create a session bean and data control for the session bean.

First create the table required for @TableGenerator, download the required sql script.

Steps to configure @TableGenerator
  1. Right click on the Connection  and select New -> Offline Database Objects -> Offline Database Objects from Source Database, select Sequence table and click on Finish.
  2. Open persistence.xml in flat editor.
  3. Navigate to Departments Entity from persistence.xml and open departmentId field.
  4. Go to Primary Key Generation Tab select Table Generator section.
  5. Make the configuration as shown in below image.

Above Primary key section will have the configuration details of the table generator to be used Column field specifies the Sequence name column, the name of the Table Generator set in Name field should match the Sequence name present in the table and Value column field specifies the Sequence count column.

Now select Use Generated Value check box and set the Strategy as Table and Generator as DeptNoGenerator as shown below.


In View Controller project, create the index.jspx page and drop the departmentsFindAll->Table as ADF Table and drop the Create operation from departmentsFindAll->Operations as ADF Button.
From Data Control Palette drop persistDepartments as ADF Button and bind parameter as shown below.


Run the index.jspx page and click on create button and enter the filed details, don't enter for departmentId field and save the record. Now the departmentId will be added as 101 since we have started sequence number from 100.