Oracle® SOA Suite Developer's Guide 10g (10.1.3.1.0) Part Number B28764-01 |
|
|
View PDF |
The entity manager is the client's gateway to entity management services offered by the EJB 3.0 persistence framework. The entity manager provides support for querying, updating, refreshing, and removing existing entity instances, and registering entity classes to create new persistent objects with identity.
The entity manager maintains a cache of instances within a transactional context called a persistence context. The persistence context allows the entity manager to track modified, created, and removed entity instances, and to reconcile entity instances with changes that were committed by external transactions concurrent with the entity manager's own transaction.
Entity instances queried through the entity manager may be freely passed to clients both inside and outside the EJB container. Clients may access and update the entity data as they would an ordinary Java object.
An EntityManager instance can be acquired both from within the EJB container (Java EE) and outside it (Java SE). This offers clients the flexibility to interact with persistent entity beans in a uniform way, without regard to whether the persistence code is running inside or outside the EE container.
Client sessions must obtain an EntityManager instance before interacting with persistent entity instances. In most cases, it's best to inject an instance of an EntityManager. However, you may need to use an EntityManagerFactory for more precise control, or use a JNDI lookup.
In Example 4-5, container injection is used to obtain an EntityManager instance bound to the persistence unit that includes the Customer entity. The EntityManager is then used to persist a new Customer instance.
Note: Example 4-5 assumes that an ID generator or other service exists to populate the primary key of the new instance. |
When container injection is not available, or when more control over the lifecycle of the EntityManager is desired, the client can obtain an EntityManager by first acquiring an EntityManagerFactory. The javax.persistence.Persistence class serves as a factory for acquiring an EntityManagerFactory. Example 4-6 shows how a Java SE service client would obtain an EntityManager. In this example, an EntityManagerFactory is created and bound to the persistence unit that includes the Customer entity. Then an EntityManager instance is created from that factory and used to persist a new Customer instance.
Example 4-6 Java Service Facade Using EntityManagerFactory
public class CustomerService { public static void main(String[] args) { final EntityManagerFactory emf = Persistence.createEntityManagerFactory("customerServiceUnit"); final EntityManager em = emf.createEntityManager(); final Customer cust = new Customer(); cust.setName("New Customer"); em.persist(cust); } }
Another option available is to look up the EntityManagerFactory, or the EntityManager itself, through JNDI. Example 4-7 shows how this is done from within a session bean.
Example 4-7 Looking up the EntityManager Through JNDOI
@Stateless @PersistenceContext(name="customerServiceUnit") public class CustomerServiceBean implements CustomerService { @Resource SessionContext ctx; public void performService() { EntityManager em = (EntityManager)ctx.lookup("customerServiceUnit"); ... } }
To create a named query, you enter the query directly in the entity class using EJB QL syntax. Use @NamedQueries to denote a group of EJB QL queries, and @NamedQuery for each EJB QL query.
In Example 4-8, three named queries are defined: findAllCustomer, findCustomerById, and findCustomerByEmail. The first find-all method is generated by default when you create the entity. The other two named queries were created by annotating the source code.
Example 4-8 Named Queries
@NamedQueries({ @NamedQuery(name="Customer.findAll", query="select object(o) from Customer o"), @NamedQuery(name="Customer.findById",query="select object(cust) from Customer cust where cust.custid = :custid"), @NamedQuery(name="Customer.findByEmail",query="select object(cust) from Customer cust where cust.email = :email and cust.password = :password") })
If you create or edit a session bean, you can choose which methods to expose through the session facade. See Section 4.4.4, "How to Update an Existing Session Bean With New Entities".
If the object returned is a list or collection, the framework determines the correct return type, but if it is a single object, you will need to specify the return type. See the following section, Section 4.5.3.1, "How to Change the Return Type of a Method That Returns a Single Value".
Changing the return type of a method is a two-step process: first change the return type in the Bean Method Details dialog, and then change the source code.
To open the Bean Method Details dialog, in the Structure pane, select the method you generated on the session facade, right-click it and choose Properties, as shown in Figure 4-7:
In the Bean Methods Details dialog, change the return type so that it returns the proper type of object. For example, in the SOA Order Booking application, the findCustomerById method returns an instance of a Customer, located in the org.soademo.customerservice.persistence package, as shown in Figure 4-8:
Tip: Entering the return type by hand can introduce errors. If you are using one of the native Java types, use the drop-down list to select the proper return type. If the return type is a class, use the Browse button on the Bean Method Details dialog to locate the proper object in your workspace. |
Once you've changed the return type of the method, you will also need to modify the source code. First, you must cast the object to the correct type, and then change getResultList() to getSingleResult(), as in Example 4-9.