UI-Component Sets

Apache MyFaces Orchestra

Introduction

Orchestra is a small library that can be used in web applications to provide the following features:

  • A conversation (aka dialog) scope for beans.

  • Conversation-scope persistence contexts. This fixes the dreaded LazyInitializationException or NonUniqueObjectException problems when working with persistent objects.

  • Declarative transaction annotations (java1.5 only).

  • A "dynaForm" JSF component that helps create forms for editing persistent data.

Together these features ease development of applications that perform a lot of persistence (ie are strongly coupled with a database). In particular, the dynaForm component (which requires the other parts of Orchestra) makes it easy to write the "data entry" type applications that Oracle Forms or Microsoft Access specialise in.

Orchestra currently supports JSF1.1, JSF1.2 and JSF2.0, but support should be possible for other web presentation frameworks in future.

Apache MyFaces Orchestra is a relatively new member of the Apache MyFaces project family, but has already been used in several real world projects. Check-out our demo-application if you want to see more on how it works in practice.

Since version 1.4, orchestra is JDK 1.5 compatible, because JDK 1.4 has reached its End of Life. For use in JDK 1.4 please use 1.3.1 artifacts.

Dependencies

Orchestra requires that Spring 2.x be used to declare managed beans that will be stored in conversation context.

There are no other significant dependencies or structural requirements for code that uses Orchestra (in particular, no requirement to use EJBs).

Structure

The Apache MyFaces Orchestra project contains several modules:

  • core: The core module is compatible with Java 1.5 and JSF 1.1

  • core12: The core module is compatible with Java 1.5 and JSF 1.2

  • core20: The core module is compatible with Java 1.5 and JSF 2.0

  • core15: Ok, we admit, we couldn't resist, so this package contains Java 5.0 enhancements to the core so that you get cool new annotation based stuff as well. This code was merged in core module since 1.4 version.

  • sandbox: An area for components that are not yet API-stable, or which depend on unreleased components of other projects.

  • examples: Demo apps (currently only one) showing off many of Orchestra's features.

Follow the links to these modules for further documentation.

Highlights

  • It works with a Java 1.5-compliant syntax, and you can optionally use annotations

  • It utilizes the powerful Spring bean configuration mechanism instead of JSF's managed-bean facility. The release of Spring 2.0 made it possible to define custom bean scopes in Spring. If a JSF Managed bean is declared in Spring using the Orchestra "conversation" scope, then when that bean is referenced from a JSF EL expression it is automatically created within that conversation scope. It is not necessary for non-conversation-scoped managed beans to be declared via Spring, although we do recommend it: request and session scopes are also supported and you benefit from having one common syntax for defining the beans of your application, from the AOP features Spring provides, and from Spring's other advanced features.

  • A plus for integrating Orchestra into existing applications: If you configure your application to use Orchestra, whenever the conversational context is opened, Spring configured DAOs and BOs automatically use the new context and gain from the conversational features of Orchestra. Minimal effort for maximal results!

  • MyFaces Orchestra is know to be compatible to persistence frameworks such as Toplink and Hibernate (and generally any JPA-implementation). However, any persistence framework can be plugged into Orchestra.

  • The Orchestra API can be adapted to use other web frameworks than JSF.

  • Orchestra sports a very easy to use API - maximum 3 method calls, and you're ready to go.

Limitations

Orchestra persistence features presume the presentation tier has access to the database, i.e. that the presentation and database-access tiers are combined. This is often the case in small-to-medium web applications. Large or security-sensitive applications which separate database access out into an isolated tier (eg use a "full EB stack") cannot use the Orchestra persistence facilities, although they can still make use of the regular conversational support for beans in the presentation layer.

Orchestra does not currently support Portlets. It should not be a lot of work to get this working, but it hasn't yet been done. Patches are welcome.

Orchestra does not support "distributed sessions", ie setups where http sessions are serialized and sent to other machines in a cluster. Progress is being made on this, but there is still some work to be done. Patches are welcome.

A small JSF example

For the impatient, here's a quick demonstration of Orchestra's main features.

First, you need to configure a conversation-scoped bean - do that in standard Spring-syntax. Define the name of the scope by setting the scope-attribute.

<bean
  name="ballotTopic"
  class="org.apache.myfaces.examples.ballot.backings.BallotTopic"
  scope="conversation.access"/>

The bean named "ballotTopic" can now be used from the JSF-view. It defines properties, methods and event-listeners as usual managed-beans do.

Then, there is the action-method - you define this method as requiring a transaction with the @Transactional annotation (with this, a commit will be executed at the end of the method). Now do whatever you want to do with your beans - save business objects, update them, play around and have fun. When the conversation needs to be closed again, close it by calling the invalidate method on the current conversational instance (the action-method needs to be defined in the conversational bean itself).

@Transactional
public String saveAction()
{
  topic.setOwner(getVoterDao().getByKey(getBallotState().getVoterId()));
  topicDao.save(topic);

  Conversation.getCurrentInstance().invalidate();

  return "success";
}               
The developer keeps on defining DAO's as she is used to do - here a simple example using the JPA-syntax with an injected EntityManager.
public class VoterDao
{
  @PersistenceContext
  private EntityManager entityManager;

  public Voter getByKey(Long id)
  {
    return entityManager.find(Voter.class, id);
  }
}