官术网_书友最值得收藏!

Introducing the EntityManager

We will use a remote stateless session bean for business operations on the Customer entity. We will call our session bean interface BankService. In later chapters, we will add more entities and business operations that are typically used by a banking application. At this stage our banking application deals with one entity—Customer, and business methods addCustomer() and findCustomer(), which respectively add a customer to the database and retrieve a customer entity given the customers identifier. The interface listing follows:

package ejb30.session;
import javax.ejb.Remote;
import ejb30.entity.Customer;
@Remote
public interface BankService {
void addCustomer(int custId, String firstName,
String lastName);
Customer findCustomer(int custId);
}

The code below shows the session bean implementation, BankServiceBean :

package ejb30.session;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import ejb30.entity.Customer;
import javax.persistence.PersistenceContext;
@Stateless
public class BankServiceBean implements BankService {
@PersistenceContext(unitName="BankService") private EntityManager em;
public Customer findCustomer(int custId) {
return ((Customer)
em.find(Customer.class, custId));
}
public void addCustomer(int custId, String firstName,
String lastName) {
Customer cust = new Customer();
cust.setId(custId);
cust.setFirstname(firstName);
cust.setLastname(lastName);
em.persist(cust);
}
}

The EntityManager is a service provided by the persistence engine which provides methods for persisting, finding, querying, removing, and updating entities. The set of managed entity instances is known as a persistence context. It is important to stress that a persistence context is associated with a managed set of entity instances or objects. If we have, say, 10 clients accessing the bean, we will have 10 persistence contexts. Associated with an EntityManager is a persistence unit which specifies configuration information. The statement:

@PersistenceContext(unitName="BankService")
private EntityManager em;

defines an EntityManager instance em with an associated persistence context and a persistence unit named BankService. The actual persistence unit configuration is specified in a persistence.xml file which we shall see shortly.

Actually, behind the scenes, the @PersistenceContext annotation causes the container to:

  • Use the EntityManagerFactory to create an instance of the EntityManager
  • Bind the EntityManager instance to the BankService persistence unit
  • Inject the EntityManager instance into the em field.

Now let's take a look at the addCustomer() method. First, the statement

Customer cust = new Customer();

creates, as expected, an instance of the Customer entity. However, at this stage the entity instance is not managed. The instance is not yet associated with a persistence context. Managed entity instances are also referred to as attached instances and unmanaged instances as detached instances.

The next few statements invoke the Customer setter methods in the usual way. The statement:

em.persist(cust);

invokes the EntityManager.persist() method. At this stage the entity instance is not necessarily written immediately to the database. Rather, the entity instance becomes managed or attached and associated with a persistence context. The EntityManager manages the synchronization of a persistence context with the database. There may be more setter methods in our method after the persist() statement. The EntityManager is unlikely to update, or flush, the database after each setter as database write operations are expensive in terms of performance. More likely the entity state would be kept in a cache and flushed to the database at the end of the current transaction. The latest point at which the EntityManager will flush to the database is when the transaction commits, although the EntityManager may chose to flush sooner.

By default, a transaction starts when a method is invoked, and is committed on leaving a method. We will discuss transactions further in Chapter 7.

Now let's look at the findCustomer() method. The statement:

return ((Customer) em.find(Customer.class, custId));

invokes the EntityManager.find() method. This method retrieves an entity by its primary key. The parameters of find() are the entity class and a primary key, which is an Object type, which uniquely identifies the entity. In our example we use the variable custId as the primary key (the autoboxing feature of Java SE 5 converts the supplied int type to an Object type).

The EntityManager service also provides a query language, JPQL, which we will cover in Chapter 5. Furthermore the EntityManager provides entity management methods, such as merging detached entities. At this stage the reader might think that entities should always be in an attached (managed) state, however we shall see examples in Chapter 6 where entities do exist in a detached state.

The following listing is an example of how a client might invoke the BankService methods to create and then find an entity.

package ejb30.client;
import javax.naming.Context;
import javax.naming.InitialContext;
import ejb30.session.*;
import ejb30.entity.Customer;
import javax.ejb.EJB;
public class BankClient {
@EJB
private static BankService bank;
public static void main(String[] args) {
try {
int custId = 0;
String firstName = null;
String lastName = null;
try {
custId = Integer.parseInt(args[0]);
firstName = args[1];
lastName = args[2];
} catch (Exception e) {
System.err.println(
"Invalid arguments entered, try again");
System.exit(0);
}
// add customer to database
bank.addCustomer(custId, firstName, lastName);
Customer cust = bank.findCustomer(custId);
System.out.println(cust);
} catch (Throwable ex) {
ex.printStackTrace();
}
}
}

The code is fairly straightforward. The variables custId, firstName, and lastName are initialized to parameters supplied to the main method when it is invoked. The client uses the BankService.addCustomer() method to create and add a Customer entity to the database. The BankService.findCustomer() method is then invoked to retrieve the entity just created.

We now return to the persistence unit which we referred to in the @PersistenceContext annotation that we used in the BankService session bean. The actual configuration is specified in an XML file, persistence.xml, which is shown below:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="BankService"/>
</persistence>

Again we make heavy use of defaults here. A persistence.xml file is required whenever an application makes use of EntityManager services, even if we rely entirely on defaults. In our case we have just used the name element to define the BankService persistence unit. Note the name must match the unitName used earlier in the @PersistenceContext annotation. There are a number of persistence unit elements, in particular regarding transactions and data sources. We will return to these elements later in the book.

主站蜘蛛池模板: 浦北县| 通化市| 渝北区| 福贡县| 乡宁县| 奎屯市| 吕梁市| 沁阳市| 高清| 新津县| 鄂托克前旗| 竹北市| 盘锦市| 徐汇区| 泸溪县| 喀什市| 陆河县| 衡水市| 呼图壁县| 巍山| 新丰县| 岳阳市| 胶南市| 太湖县| 达日县| 砀山县| 田东县| 米脂县| 合山市| 延津县| 通州市| 重庆市| 章丘市| 九江县| 新蔡县| 广饶县| 玛沁县| 苗栗县| 乐亭县| 南靖县| 揭阳市|