The solution

Reading data from a service-layer API (developed using the Persistence Infrastructure) involves writing code using two interfaces, which will be introduced by example:
Coding the solution involves these steps:

Create a class variable to hold the DAO

Firstly, you need to create a class member variable for the entity's DAO, and annotate it with @Inject:

Figure 1. Creating an injected member variable for a DAO
public class MyFacade {
  // ...

  @Inject
   private SomeEntityDAO someEntityDAO;

(The @Inject annotation is provided by Guice, a dependency injector. At runtime, Guice will initialize the someEntityDAO variable to use the configured implementation of SomeEntityDAO. You don't really need to worry about any of this.)

The someEntityDAO object "knows" how to create instances of the entity interface. In this scenario, you'll use the DAO to retrieve the instance of the entity from the database.

Create a constructor to request Guice to inject class variables

Because instances of your class are created outside of Guice's control, you must code an explicit constructor which requests Guice to "inject" class variables (in particular the someEntityDAO variable you created in the previous step):

Figure 2. Creating a public constructor to inject member variables
public MyFacade() {
    GuiceWrapper.getInjector().injectMembers(this);
  }

If you fail to do this step, then when your application runs you will likely see a NullPointerException when your application attempts to access the someEntityDAO variable.

Use the DAO to retrieve the instance of the entity

In your façade method, code a variable to hold an instance of the entity interface, and set its value by calling.get() on the DAO, passing the key of the database row:

Figure 3. Calling a DAO to get an instance of an entity based on its key
// retrieve the instance of the entity
  final SomeEntity someEntity = someEntityDAO.get(key.someEntityID);
Here, the DAO instance has "dished up" the required instance of the entity interface. someEntity now holds an object which "knows" how to:
  • get at data (via "getter" methods); and also
  • "do things" with that data (via other methods).

Access the entity instance to map field values to the client struct

Now code calls to the entity "getters" to map fields values to your return struct:

Figure 4. Calling getter methods on an entity interface
// map the details from the entity instance
    someEntityDetails.details.someEntityID = someEntity.getID();
    someEntityDetails.details.name = someEntity.getName();
    someEntityDetails.details.versionNo = someEntity.getVersionNo();

    final DateRange dateRange = someEntity.getDateRange();
    someEntityDetails.details.startDate = dateRange.start();
    someEntityDetails.details.endDate = dateRange.end();
    // ...more mappings
Points to note:
  • Every entity API has a.getID() method, which returns its primary key. There will not be a specific getter for the entity's primary key field, e.g. there is no someEntity.getSomeEntityID() method.
  • The API for any entity which supports optimistic locking has a.getVersionNo() method.
  • Some getters do not return primitive types, but instead return objects, e.g. there are no someEntity.getStartDate() or.getEndDate() methods, only a.getDateRange() method which returns a DateRange object which contains a start and end date, but is also capable of date-range processing such as validation and comparison.

You must code a mapping for each field that you need to return to the client. Code-completion in IDEs like Eclipse will help!

Putting it all together

Here's the complete code for this scenario solution:

Figure 5. Complete listing for a façade "view" method
public class MyFacade {
  // ...

  @Inject
  private SomeEntityDAO someEntityDAO;

  public MyFacade() {
    GuiceWrapper.getInjector().injectMembers(this);
  }

  public SomeEntityDetails viewSomeEntityDetails(
      final SomeEntityKey key) throws AppException,
      InformationalException {

    // create an instance of the return struct
    final SomeEntityDetails someEntityDetails =
        new SomeEntityDetails();

    // retrieve the instance of the entity
    final SomeEntity someEntity =
        someEntityDAO.get(key.someEntityID);

    // map the details from the entity instance
    someEntityDetails.details.someEntityID = someEntity.getID();
    someEntityDetails.details.name = someEntity.getName();
    someEntityDetails.details.versionNo = someEntity.getVersionNo();

    final DateRange dateRange = someEntity.getDateRange();
    someEntityDetails.details.startDate = dateRange.start();
    someEntityDetails.details.endDate = dateRange.end();
    // ...more mappings

    // return to the client
    return someEntityDetails;
  }

  // ...
}

For this first scenario only, here's a side-by-side look at the classic approach vs. the service-layer API approach:

Figure 6. Comparison of a façade view calling a "classic" service layer vs. calling a service layer developed using the Persistence Infrastructure
  1. The object which knows how to retrieve instances of the entity. Using the persistence package, the object is called a Data Access Object ("DAO") and is a class member variable initialized by Guice using @Inject. The class constructor requests Guice to initialize this (and any other) class variable(s).
  2. The retrieval of the entity from the database uses the DAO.
  3. The data held on the entity is mapped to the client struct.
Note that when using service-layer APIs, in general:
  • Code to retrieve instances of these APIs is more terse than when using classic Cúram; but
  • Code to map entity data to client structs is more verbose (but this is after all one of the main purposes of façade logic).