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

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.

主站蜘蛛池模板: 阿拉善盟| 凤台县| 阜南县| 肇东市| 平湖市| 平遥县| 宜春市| 洱源县| 湟源县| 利川市| 铁岭县| 云南省| 鱼台县| 正蓝旗| 呼和浩特市| 怀化市| 八宿县| 万源市| 徐水县| 出国| 扎囊县| 水城县| 休宁县| 凤翔县| 鄂托克前旗| 佛山市| 平武县| 盈江县| 读书| 崇左市| 怀仁县| 克东县| 咸宁市| 宜州市| 清水河县| 应城市| 舞钢市| 大城县| 中方县| 进贤县| 永丰县|