Skip Headers

# Reading Case 4: Using View Objects

Previous

Next

Some application operations require information from several objects rather than from just one. This can be difficult to implement, and resource-intensive. Example: No Optimization illustrates unoptimized code that reads information from several objects.

No Optimization

    /* Gather the information to report on an employee and return the summary of the
       information. In this situation, a hash table is used to hold the report
       information. Notice that this reads a lot of objects from the database, but
       uses very little of the information contained in the objects. This may take 5
       queries and read in a large number of objects */

    public Hashtable reportOnEmployee(String employeeName) {
        Vector projects, associations;
        Hashtable report = new Hashtable();
        // Retrieve employee from database
        Employee employee = session.readObject(Employee.class,
           new ExpressionBuilder.get("lastName").equal(employeeName));
        // Get all the projects affiliated with the employee
        projects = session.readAllObjects(Project.class,
          "SELECT P.* FROM PROJECT P," +
          "EMPLOYEE E WHERE P.MEMBER_ID = E.EMP_ID AND E.L_NAME = " +
          employeeName);
        // Get all the associations affiliated with the employee
        associations = session.readAllObjects(Association.class, "SELECT A.* " +
          "FROM ASSOC A, EMPLOYEE E WHERE A.MEMBER_ID = E.EMP_ID AND E.L_NAME = "
          + employeeName);
        report.put("firstName", employee.getFirstName());
        report.put("lastName", employee.getLastName());
        report.put("manager", employee.getManager());
        report.put("city", employee.getAddress().getCity());
        report.put("projects", projects);
        report.put("associations", associations);
        return report;
    }

To improve application performance in these situations, define a new read-only object to encapsulate this information, and map it to a view on the database. To set the object to be read-only, use the `addDefaultReadOnlyClass` API in the `oracle.toplink.sessions.Project` class.

Optimization Through View Object

    CREATE VIEW NAMED EMPLOYEE_VIEW AS (SELECT F_NAME = E.F_NAME, L_NAME = E.L_NAME,EMP_ID = E.EMP_ID, MANAGER_NAME = E.NAME, CITY = A.CITY, NAME = E.NAME
    FROM EMPLOYEE E, EMPLOYEE M, ADDRESS A
    WHERE E.MANAGER_ID = M.EMP_ID
    AND E.ADDRESS_ID = A.ADDRESS_ID)

Define a descriptor for the `EmployeeReport` class as follows:

- Define the descriptor as usual, but specify the `tableName` as `EMPLOYEE_VIEW`.

- Map only the attributes required for the report. In the case of the `numberOfProjects` and associations, use a transformation mapping to retrieve the required data.

You can now query the report from the database in the same way as any other object enabled by TopLink.

View the Report from Example: Optimization Through View Object

    /* Return the report for the employee */
    public EmployeeReport reportOnEmployee(String employeeName) {
        EmployeeReport report;
        report = (EmployeeReport) session.readObject(EmployeeReport.class,
          new ExpressionBuilder.get("lastName").equal(employeeName));
        return report;
    }

WARNING: Allowing an unverified SQL string to be passed into methods (for example: `readAllObjects(Class class, String sql)` and `readObject(Class class, String sql)` method) makes your application vulnerable to SQL injection attacks.