Putting a Custom UI on Naked Objects: Part 2, Interacting with Pojos

In the previous post we saw how to bootstrap Naked Objects, and open a PersistenceSession. In this post let’s see how to actually get hold of and interact with a domain object.

First thing we usually do is to get hold of the registered services (as per nakedobjects.services key in nakedobjects.properties configuration file). These will typically be repositories allowing us to locate existing domain objects, like Customers or Orders. For example, in the claims example app, we have an EmployeeRepository example:

public class EmployeeRepositoryInMemory
        extends AbstractFactoryAndRepository
        implements EmployeeRepository {

    public String id() { return "claimants"; }

    public List allEmployees() {
        return allInstances(Employee.class);
    }

    public List findEmployees(@Named("Name") String name) {
        return allMatches(Employee.class, name);
    }
}

We can get hold of the service using its id, in this case (slightly inconsistently) “claimants”:

NakedObject employeeRepositoryNO =
    NakedObjectsContext.getPersistenceSession().getService("claimants");

As we can see, every service/repository is wrapped in a NakedObject instance. This does the following things:

  • wraps the underlying pojo; getObject() returns the pojo
  • provides access to the metamodel; getSpecification() returns an instance of NakedObjectSpecification.
  • provides an object identifier, or Oid; effectively a serializable URN for the domain object. getOid() returns this Oid.

We can therefore obtain the EmployeeRepository to find the Employees:

EmployeeRepository employeeRepository =
    (EmployeeRepository)employeeRepositoryNO.getObject();
List<Employee> employees = employeeRepository.allEmployees();

We can then interact with the pojos in the usual way, for example:

for (Employee employee : allEmployees) {
    String name = employee.getName();
    System.out.println(name);
    employee.setName(name + "Changed");
}

Try running this little app using the XML object store, so that any changes are persisted. To configure this, just add:

nakedobjects.persistor=xml

to the nakedobjects.properties config file.

Now, when you run successive times, you’ll see the changes are indeed being persisted.

Let’s take this a little further. Although we aren’t interacting with the pojos using the Naked Objects API, they are still known to Naked Objects framework, and are enlisted into its transaction management. Since we haven’t mentioned transactions anywhere in our code, each of those setName() calls is being run in a separate transaction – ie similar to ANSI unchained mode.

But we could also put all the changes into a single transaction:

NakedObjectsContext.getTransactionManager().startTransaction();

for (Employee employee : allEmployees) {
    String name = employee.getName();
    System.out.println(name);
    employee.setName(name + "Changed");
}

NakedObjectsContext.getTransactionManager().endTransaction();

Now these changes are all perfomed in a single transaction. To confirm this, we can use the UpdateNotifier, a component that keeps track of the objects dirtied within a transaction. Naked Objects’ own generic viewers use this to determine which objects to repaint, but you can use it for whatever you need:

List<NakedObject> changedObjects = updateNotifier.getChangedObjects();
for (NakedObject nakedObject : changedObjects) {
    Object pojo = nakedObject.getObject();
    Oid oid = nakedObject.getOid();
    System.out.println("changed: " + pojo + "; oid=" + oid);
}

Note that the pojos are also wrapped in NakedObject instances, just as the service/repository was earlier.

As an alternative to all this, we can interact with the domain objects through the Naked Objects API. We’ll be looking at this in the next post.

Posted on December 1, 2009, in apache isis. Bookmark the permalink. 4 Comments.

  1. Ilya Izhovkin

    If I create new instance of pojo through repository, must UpdateNotifier return repository in changed objects list?
    In my application I have container, which lists all instances of my entity class, it uses repository to get listing. After creating new instance, I need to update list. I want to use UpdateNotifier to determine, if container needs to be updated.

    • Hi Ilya,
      No, UpdateNotifier only deals with entities, not with repositories. So it won’t get added (and you can’t add it) to the UpdateNotifier list.
      I’m not quite sure from your question which “list” you want updating? The only one I can think of is if you have an allInstances() action, which you’ve invoked, and then you want to be updated automatically when a new instance is created? If so, then I’m you can’t – results of actions are not tied back in any way to the object that created them.
      If this is what you want to do, then I’d suggest you create an entity to wrap the repository.
      For example, suppose that the repository you have is AuctionRepository, and it has an allInstances() method to return Auctions. This list of Auctions is what you want to be live. In which case, introduce an AuctionHouse, which has a collection of Auctions. Arrange it so that there is only ever one AuctionHouse, and create new Auctions through the AuctionHouse object.
      HTH
      Dan

  1. Pingback: Putting a Custom UI on Naked Objects: Part 1, Bootstrapping | Domain Driven Design using Naked Objects

  2. Pingback: Putting a Custom UI on Naked Objects: Part 3, The MetaModel API | Domain Driven Design using Naked Objects

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 126 other followers