WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using ...

5 downloads 107 Views 296KB Size Report
1-2. WA1718 Java EE 5 Programming with. JSF, EJB 3.0, and JPA using JBoss 5.0. (C) Web Age Solutions Inc. 2010. Objectives. ▫ At the end of this chapter, ...
WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Y Entities and Java Persistence API L N O N O I T A U L A V E

(C) Web Age Solutions Inc. 2010

1-1

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Objectives „

At the end of this chapter, participants will be able to: „ „ „

„

Y L N O N O I T A U L A V E

Understand the concept of Entities. Describe the new Java Persistence API. Understand how entities are mapped to database. Use the EntityManager interface to perform various operations on entities.

(C) Web Age Solutions Inc. 2010

1-2

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Data Persistence „

„

„

Almost all applications rely on working with data stored in a persistent storage such as databases. The persistence model in EJBs prior to EJB3 specification was based on Entity Beans. Entity beans (EJB 2.x) are persistent business objects that exist beyond the client and server processes. „ „ „ „ „

Y L N O N O I T A U L A V E

Shared and concurrently accessed by multiple clients. Persistent: saved in a database. In-memory view of a database. Can be created, found, pooled, and removed. Long-lived and survive both a crash or a deliberate shutdown of the server.

Note that the EJB3 specification is backward compatible and supports EJB 2.x Entity Beans as well.

(C) Web Age Solutions Inc. 2010

1-3

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Data Persistence „

„

„

„

Entity Beans represented a cumbersome and complex technology to persist data and work with it. The amount of code to write a single entity bean was very high. A single entity bean consisted of at least one class and two interfaces, and required a deployment descriptor. To provide a simpler persistence model to the developers a new specification known as the Java Persistence API was created. Java Persistence API is a separate specification (JSR 220) different from the core EJB specification.

(C) Web Age Solutions Inc. 2010

Y L N O N O I T A U L A V E

1-4

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Java Persistence API „ „ „

„

„

„

Supported by EJB 3.0. Can be used as a stand-alone API with Java SE also. Describes the rules to managing persistence and doing Object-Relational (O-R) mapping. In Java Persistence API, persistent objects are referred as Entities. Object-Relational (O-R) mapping refers to mapping objects to relational databases. For example, a Java class may be mapped to a database table. Several open source tools (such as Hibernate) and products are available to perform O-R mapping.

Y L N O N O I T A U L A V E

The Java Persistence API specification, which is part of the EJB 3 specification (JSR 220), can be downloaded from http://java.sun.com/products/ejb/docs.html.

In this chapter we discuss Entities. Hibernate and Object-Relationship Mapping are discussed in the next few chapters.

(C) Web Age Solutions Inc. 2010

1-5

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Entities „

„

„

„

„

Represent data (simple or complex) in a persistent storage (usually a database). Examples include account balance, list of employees, addresses of customers etc. Entities represent things or nouns in a system – for example, Customer or Order. In physical world, Entities are plain java classes (POJOs). They are not a type of EJB. Entities can be used in a stand-alone mode outside the container.

(C) Web Age Solutions Inc. 2010

Y L N O N O I T A U L A V E

1-6

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Session Beans Vs Entities Session Beans

Entities

Represent actions (verbs)

Represent physical entities (nouns)

Do not survive system failure

Survive system failure since data is stored in a persistent storage. A bean instance can be populated with the data to recreate the view.

Session Bean lifecycle is dependent on the client (application) lifecycle

Independent of application lifecycle. The data in the persistent storage may exist before the application is executed and after the application is executed.

Y L N O N O I T A U L A V E

Follow EJB specification and run Not a type of EJB. Entities are plain java within the EJB container classes. Can run outside a container. Remotely accessible

Cannot be accessed remotely

The above table provides a table with some key differences between the two.

(C) Web Age Solutions Inc. 2010

1-7

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Entities „

„

„

„

„

Entity classes are represented using the @Entity annotation. Alternatively, they can be described in an XML descriptor file. An interface cannot be designated as an Entity. Only classes can use the @Entity annotation. An Entity class cannot be final or have its methods or variables declared as final. The Entity class must implement the Serializable interface if it is used in the method signature of a remote interface of a session EJB.

(C) Web Age Solutions Inc. 2010

Y L N O N O I T A U L A V E

1-8

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Entities „

The persistent information in an Entity is accessed through the instances variables or JavaBean-style properties with getter/setter methods. „

„

„

Y L N O N O I T A U L A V E

Example: If a persistent field called phoneNumber is there in an entity class, then a getPhoneNumber and a setPhoneNumber method is defined on the class to access the phoneNumber field.

Since each instance of an Entity represents a unique row in a table, each entity has a primary key defined which represents a unique instance. Primary keys are represented using the annotation @Id.

(C) Web Age Solutions Inc. 2010

1-9

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Persisting and Retrieving Data „

„ „

Java Persistence specification expects the vendor providers to support persisting and retrieving data. „ Examples include, creating a table, adding columns and performing CRUD operations. Developers use various annotations that are interpreted by the runtime engine such as a Java EE container to perform different operations. JPA provides the API that the applications use. But it does not implement the object relational mapping. You must use a vendor specific provider that implements the actual database access layer. Common providers are: „ „ „ „

„

Y L N O N O I T A U L A V E

Open JPA. It is an Apache project and supported by IBM, BEA, and Oracle. Kodo. Hibernate. TopLink.

Application code should not directly use the provider's API. If you do so, the application will become locked into that provider.

CRUD - Create, Retrieve, Update and Delete.

(C) Web Age Solutions Inc. 2010

1-10

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Accessing Entities „

„

Entities are plain java components and cannot be accessed remotely. To access Entities, two options exists: „

„

„

Y L N O N O I T A U L A V E

Use a Java SE technology such as Swing that runs outside a container. Use Session Beans or Message Driven Beans that run inside a container.

In this chapter, we discuss the method of using Session Beans to access Entities.

Message Driven Beans will be discussed in a separate chapter.

(C) Web Age Solutions Inc. 2010

1-11

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

EntityManager & Persistence Unit „

„

„

The EntityManager is a service that manages persistent entities. The application code uses this heavily to read, update, insert or delete data. A persistence unit is a set of Java classes mapped to a particular database. JPA also provides a way to configure the database connection information for the unit in an XML file - META-INF/persistence.xml. An EntityManager manages a particular persistence unit „

Y L N O N O I T A U L A V E

An application can define multiple persistence units if required, if it needs to interact with multiple separate database.

(C) Web Age Solutions Inc. 2010

1-12

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Persistence Context „

„

„

The java objects (entity instances) in memory have to be mapped to the rows in a database. Persistence Context represents the bridge between the Entity object instances and the physical storage in the database. An EJB uses a persistence context object to interact with the database. „

Y L N O N O I T A U L A V E

Developers use various methods (such as remove, merge, persist) provided by the EntityManager to perform operations on the database.

The methods listed above are discussed next.

(C) Web Age Solutions Inc. 2010

1-13

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Entities - Example package com.entity; import java.io.Serializable; import javax.persistence.*; @Entity @Table(name="BANKACCOUNTS") public class BankAccount implements Serializable { @Id @Column(name="ID") @GeneratedValue(strategy=GenerationType.IDENTITY) int id; @Column(name="BALANCE") int balance; @Column(name="OWNERNAME") String ownerName;

Y L N O N O I T A U L A V E Continued

The above code demonstrates a banking application with various business methods. In our example we demonstrate one functionality (i.e., depositing money). Each customer's data is stored in a database. Entities allow us to persist data without writing any SQL code. This frees java developers from learning complex SQL. We now look at the annotations used in the above code snippet. @Entity: We denote the above java class as an Entity class by using the @Entity annotation. @Table(name="BANKACCOUNTS"): This annotation is used to specify the primary table for the Entity class. The Persistence Manager creates a table with the value of the name parameter and refers to a descriptor file for the schema mapping. The descriptor file is named persistence.xml (discussed next). If no name is specified, then the class name is assumed as the table name. @Id: This specifies the primary key. It can be specified at the field level or method level (getter methods). In our example, it is specified at the field level. The column "ID" is specified as the primary key. @GeneratedValue: Instead of manually generating a primary key value, developers can use this annotation to let the Persistence Manager or the database automatically generate the primary key value. @Column: This annotation tells the Persistence Manager to create a column with the name specified within this annotation. If no name is specified, the field name is used as the column name. Constraints can also be specified on a column, such Inc. as @Column(name="BALANCE", nullable=false). (C) Web Age Solutions 2010

1-14

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Entities - Example public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } Accessor Methods public int getId() { return id; } public void setId(int id) { this.id = id; } ... public void deposit(int amount) { Business this.setBalance(getBalance() + amount); Method } }

Y L N O N O I T A U L A V E

Access to entity information should be through JavaBean-style methods (accessor methods) as shown above. Finally, developers can code business logic methods in the Entity class as well.

(C) Web Age Solutions Inc. 2010

1-15

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

persistence.xml – Hibernate Provider java:jdbc/BankDS

Y L N O N O I T A U L A V E

JBoss uses Hibernate as the Persistence Manager. It is in this file that the relational schema mapping information is provided. This file resides in the META-INF folder. The key components of this file are discussed here. persistence-unit name: Entity classes, metadata information and database configuration information is logically grouped under a persistence unit. This field specifies the name of the persistence unit. This is a required field. jta-data-source: When running the entity within JBoss, this field contains the JNDI name of the datasource. Within an application server environment, if non-jta-data-source is specified then this field is ignored. The various properties fields specify vendor specific properties such as: hibernate.hbm2ddl.auto value="update": If database schema does not exist then it is created during deployment. It is also updated if it has been edited. This property is useful in generating database schema from entity beans. Additional Hibernate-specific properties are described here: http://www.hibernate.org/hib_docs/v3/reference/en/html/sessionconfiguration.html hibernate.dialect: The value for this property refers to a class name used by Hibernate to generate SQL for a particular database. In our case it is MySQL. hibernate.show_sql: This tells Hibernate to output all SQL statements to the console.

(C) Web Age Solutions Inc. 2010

1-16

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

persistence.xml – Open JPA Provider com.webage.entity.CustomerEntity

Y L N O N O I T A U L A V E

(C) Web Age Solutions Inc. 2010

1-17

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

persistence.xml - Toplink jdbc/BankDS

Y L N O N O I T A U L A V E

Toplink is the default provider in Sun Java Application Server or Glassfish.

(C) Web Age Solutions Inc. 2010

1-18

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Entity Instance Lifecycle „

„ „

„

An application code works with an entity instance to retrieve and update data. Behind the scene, the entity manager synchronizes the data to the database. The entity manager keeps track of every entity instance that has been used by the application to load, update or insert data. The manager manages the entity instances until the end of the transaction. After that point the instances become unmanaged. The insert, delete, update operations done by the application code are translated to actual SQL calls just before the transaction ends. Until that point, the entity manager simply "records" all the activity. For example, if you delete an instance, system flags it as removed. Just before the transaction is committed, system actually executes the DELETE statement for these instances. Entity instances have the following lifecycle stages: „ „

„ „

Y L N O N O I T A U L A V E

new – A fresh instance created using the Java new keyword. managed – The instance is being managed by the entity manager. If the application code updates the fields of the instance, the manager will update the underlying database. detached – The instance is no longer being managed by the entity manager. removed – The instance has been marked for removal from the database.

When an entity instance is managed by the entity manager, any updates to the persistent fields of the instance will be updated in the underlying database. A detached entity instance is like any other regular Java class instance. Updating its fields will have no impact on the database.

(C) Web Age Solutions Inc. 2010

1-19

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Creating EntityManager in Session EJB „

A session bean class that wishes to access a database using Entity objects, needs to declare a variable for the EntityManager. „

„

The EntityManager reference is obtained by using the @PersistenceContext annotation.

Example:

Y L N O N O I T A U L A V E

@PersistenceContext(unitName = "bankaccount") EntityManager em; „

The unitName attribute of the annotation refers to the persistence unit name in the persistence.xml. „

„ „

That means, the entity manager knows what data source to use to access the database.

If system fails to locate persistence.xml or the unitName is invalid, the EntityManager variable is set to null. Every entity manager opens one connection to the database using the configuration of the persistence unit as defined in persistence.xml. You should not explicitly close this connection. The EJB container is responsible for clean up.

Recall, the META-INF/persistence.xml had to be created to define a persistence unit. There, we had specified the JNDI name of the data source where the Entity objects will be persisted. When we obtain a reference to the EntityManager object, we need to specify the name of that persistence unit. This is done using the unitName attribute of the @PersistenceContext annotation. The @PersistenceContext annotation is available from the javax.persistence package.

(C) Web Age Solutions Inc. 2010

1-20

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Creating EntityManager in a Plain Java Class „

„

The @PersistenceContext annotation will not work in a plain Java class. You must write code to create the manager. First create the factory object:

Y L N O N O I T A U L A V E

EntityManagerFactory emf = Persistence .createEntityManagerFactory("bankaccount"); „

Then create the manager:

EntityManager em = emf.createEntityManager(); „

A database connection is opened for each entity manager. You must close it by calling em.close(). You should also call close() for the factory.

(C) Web Age Solutions Inc. 2010

1-21

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Working With the EntityManager Interface „

The session bean needs to call these methods of the EntityManager to interact with the database. „

Object find(Class entityClass, Object pk) – Given a primary key value returns the entity object. „ „

„

„

„ „

Y L N O N O I T A U L A V E

void persist(Object entity) – If the entity instance is currently undetached, inserts data in the underlying database and makes the instance managed. If the instance is already managed, this method does nothing. „

„

Returns null if no row with the given primary key value exists. For more complex queries, you will need to use JPA QL which is described later.

Throws javax.persistence.EntityExistsException if there is a primary key collision.

Object merge(Object entity) – Make a detached entity instance managed (discussed later). void refresh(Object entity) - Updates the state of the entity with the data in the underlying database. void remove(Object entity) – Remove data from the underlying database. void flush() – Cause all pending changes to the database to take effect immediately.

Example:

Let us say that we have an Entity called Customer that is backed by a CUSTOMER table. In that case, data resides in two places: 1. Physically in the database in the CUSTOMER table. 2. In memory as a Customer object instance. A Customer object instance may exist standalone without any reference to data in the database. This happens, for example, when a new customer is about to be created. When the persist() method is called, system creates an association between the in-memory instance and the data in the database. Essentially, this is done by issuing an INSERT statement. A call to merge() synchronizes the physical storage with the data from the object instance. This is done using the UPDATE SQL statement. Similarly, remove() is used to cause a DELETE SQL statement to be issued. The INSERT, UPDATE and DELETE SQL statements may not take place immediately after the corresponding EntityManager methods are called. They can happen at some undetermined time before the transaction is committed. In some cases, you want to have the changes take place in the database immediately. To do so, call the flush() method.

(C) Web Age Solutions Inc. 2010

1-22

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Transaction Basics „

„

„

Database transaction is controlled using the entity manager. Before we learn more about entity instance lifecycle, we will take a brief look at how transaction is managed in JPA. If a session bean creates the entity manager, the manager inherits the JTA transaction from the EJB container. In that case, the session bean should use EJB or JTA API to control transaction (for example SessionContext.setRollbackOnly() will rollback the transaction). If an entity manager is created outside of an EJB container, the application code gets the transaction object from the manager by calling getTransaction(). Then you can call the begin(), commit() and rollback() to start and stop a transaction.

(C) Web Age Solutions Inc. 2010

Y L N O N O I T A U L A V E

1-23

WA1718 Java EE 5 Programming with JSF, EJB 3.0, and JPA using JBoss 5.0

Summary „

„

„

„

„

Java Persistence API describes the rules to managing persistence and Object-Relational (O-R) mapping. Entities represent data (simple or complex) in a persistent storage (usually a database). Persistence Context represents the bridge between the instances and the data in the database. Java Persistence specification provides an API called EntityManager to manipulate Persistence Context. The EntityManager API provides various methods to manage entity lifecycle, synchronize data with the database, and perform entity lookups.

(C) Web Age Solutions Inc. 2010

Y L N O N O I T A U L A V E

1-24