View
232
Download
2
Tags:
Embed Size (px)
Citation preview
Entities and Persistence
Entity Beans
Topics to be Covered:• Entities are POJOs• Managed/Unmanaged Entities• Persistence Unit• EntityManager• Basic Relational Mapping• The Primary Key
Entities and Persistence
Entities are POJOs
Entities and Persistence
• In Java EE 5, persistence no longer defined by EJB specification
• Java Persistence API– Abstraction on top of JDBC– Object-to-Relational Mapping (ORM)
Engine
Entities and Persistence
• javax.persistence.EntityManager– Service that performs persistence
actions•Entity Creation•Entity Update•Entity Removal•Entity Query
– Manages ORM between entity classes and underlying data source
– Tightly integrated with Java EE and EJB but not limited to this environment
POJOs
• Entities are plain old Java objects (POJOs)
•Allocated using new operator•Entities do not become persistent until they are associated with an EntityManager
POJOs
import javax.persistence.*;
@Entitypublic class Customer {private int id;private String name;
@Id @GeneratedValuepublic int getId() {
return id;}
public void setId(int id) {this.id = id;
}
POJOs
String getName() {return name;
}public void setName(String name) {
this.name = name;}
}
POJOs
• Allocated instances of the Customer class remain POJOs until you ask the EntityManager to create the entity in the database
• The following does not create a Customer instance in the database:
Customer cust = new Customer();cust.setName(“Bill”);
Entities and Persistence
Managed/Unmanaged Entities
Managed/Unmanaged Entities
• Entity is either– managed (attached) by an entity
manager• Or
– unmanaged (detached)
• Managed– EntityManager tracks state changes– Synchronizes changes to database
• Unmanaged– Any state changes are not tracked by EntityManager
Persistence Context
• Set of managed entity object instances• Managed by an entity manager
– Tracks all changes– Flushes changes to the database
• Once persistence context is closed– All managed entity object instances
becomes detached– Any state changes will not be
synchronized to the database
Persistence Context
• Transaction-scoped – Life of context as long as a transaction– Closed with a transaction completes– Application server persistence
contexts•EntityManager instances injected with the PersistenceContext annotation
@PersistenceContext(unitName=“titan”)EntityManager entityManager;
Persistence Context
• Transaction-scoped – Methods invoked within the context of
JTA transaction
@TransactionAttribute(REQUIRED)public Customer someMethod() {
Customer cust = entityManager.find(Customer.class, 1);
cust.setName(“new name”);return cust;
}
Persistence Context
• Extended – Live longer than a transaction– Maintains conversation with database
without the overhead of a transaction– Managed by application code and
stateful session beans
Persistence Context
• Extended
Customer cust = null;
trans.begin();cust = extendedEntityManager.find(
Customer.class, 1);trans.commit();
trans.begin();cust.setName(“Bill”);extendedEntityManager.flush();trans.commit();
Persistence Context
• Detached Entities – Occurs when transaction scope or
extended persistence context ends– Can be serialized and sent across the
network to a remote client– Client can make changes and send
them back to server to be merged back and synchronized with the database
– Persistent objects become value objects when they are detached from a persistent context
Entities and Persistence
Persistence Unit
Persistence Unit
• A fixed set of classes mapped by an EntityManager to a particular database
• Defined in a persistence.xml file– Required deployment descriptor for
Java Persistence specification• Set of classes may be specified or
persistence provider can scan JAR file to identify classes– Classes scanned for @Entity
annotation• Tied to only one data source
Persistence Unit
<persistence> <persistence-unit name=“titan> <jta-data-source>java:/OracleDS</jta-data-source>
<properties> <property name=“org.hibernate.hbm2ddl”>update</property> </properties>
</persistence-unit></persistence>
Entities and Persistence
EntityManager
Obtaining an EntityManager
• Java SE (and less frequently in Java EE)
– Use an EntityManagerFactory– createEntityManager() returns EntityManager instances that manage an extended persistence context
– Remember to close() the EntityManagerFactory
Obtaining an EntityManager
• Use static createEntityManagerFactory() method of javax.persistence.Persistence class
EntityManagerFactory factory =Persistence.createEntityManagerFactory (“CRM”);………factory.close();
Obtaining an EntityManager
• Now to get an EntityManager, use createEntityManager() method of EntityManagerFactory class
• Returned EntityManager represents an extended persistence context
• Must explicitly enlist EntityManager instance into JTA-enabled transactions using the joinTransaction() method
Obtaining an EntityManager
• Java EE
– Use EntityManager injection with @PersistenceContext annotation
@Statelesspublic class MySessionBean implements MySessionRemote{
@PersistenceContext(unitName=“titan”)private EntityManager entityManager; ………
}
Obtaining an EntityManager
• The unitName attribute identifies the persistence unit
• A transaction-scoped persistence context is injected by default
• Never call close() on an injected EntityManager
Interacting with an EntityManager
• Persisting Entities (INSERT)– Allocate an instance of entity– Set its properties– Wire up relationships with other
entities– Interact with EntityManager service
Customer cust = new Customer();cust.setName(“Bill”);
entityManager.persist(cust);
Interacting with an EntityManager
• Finding Entities (SELECT)– Locate by Primary Key– find() method– Returns null if entity is not found– Initializes state
Customer cust = entityManager.find(Customer.class,
2);
Interacting with an EntityManager
• Finding Entities (SELECT)– Locate by Primary Key– getReference() method– Throws EntityNotFoundException if
entity is not found– State not guaranteedCustomer cust = null;try{
cust = entityManager.getReference(Customer.class, 2);} catch(EntityNotFoundException e) {
//recovery logic}
Interacting with an EntityManager
• Finding Entities (SELECT)– Locate by Querying– EJB QL
Query query = entityManager.createQuery(“from Customer c where id=2”);
Customer cust = (Customer)query.getSingleResult();
Interacting with an EntityManager
• Updating Entities (UPDATE)– After locating an entity and prior to
closing the persistence context– Change the state of the entity– Wire up relationships with other
entities– Interact with EntityManager service
// Same active persistence contextCabin cabin =entityManager.find(Cabin.class, id);
cabin.setBedCount(newCount)
Interacting with an EntityManager
• Merging Entities– Merges state changes made to a detached entity
back into persistent storage– Scenario:
• Remote client finds an object in the database using a session bean method
• Object detached from entity manager, serialized, and returned to the remote client
• Client makes changes to detached object, and sends the object back to the server using a session bean method
• Method takes updated object and merges it into the current persistence context using merge() method
public void updateCabin(Cabin cabin) {Cabin copy = entityManager.merge(cabin);
}
Interacting with an EntityManager
• Merging Entities– If no Cabin instance with the same ID
currently being managed, a managed copy is returned by merge() method
– If Cabin instance with the same ID currently being managed, contents of parameter are copied into managed instance, and a managed instance is returned by merge() method.
– In both cases above, the parameter remains detached and unmanaged
public void updateCabin(Cabin cabin) {Cabin copy = entityManager.merge(cabin);
}
Interacting with an EntityManager
• Removing Entities (DELETE)– After locating an entity and prior to
closing the persistence context– Remove the entity– After remove() is invoked, instance
will no longer be managed (it becomes detached)
// Same active persistence contextCabin cabin =entityManager.find(Cabin.class, id);
entityManager.remove(cabin);
Interacting with an EntityManager
• refresh()– Refreshes state of entity from the
database• contains()
– Takes entity instance as a parameter– Returns true if instance is currently
being managed by the persistence context
• clear()– Detaches all managed entity
instances from the current persistence context
Interacting with an EntityManager
• flush()– Changes made when calling persist(), merge(), and remove() are not synchronized with the database until the entity manager decides to flush
– flush()forces synchronization to occur
Entities and Persistence
Basic Relational Mapping
Mapping Persistent Objects
• Entities – Model business concepts that can be
expressed as nouns– Describe both the state and behavior of
real-world objects– Represent data in the database– Provide a simple mechanism for accessing
and changing data– Provide opportunities for software reuse
• Persistence– The process of coordinating the data
represented by a bean instance with the database
– Java persistence specification provides a portable object-to-relational mapping (ORM)
Programming Model Summary
• Entities are POJOs• Interact with entity manager service to
persist, update, remove, locate, and query entities– Enrolls entity in transactions– Persists state to database
An Entity
• Must have a no-argument constructor• @javax.persistence.Entity annotation
denotes the class should be mapped to a database
• @javax.persistence.Id annotation marks which property will be used as the primary key
• All other properties map to a column of the same name and type
• Table name default to the unqualified name of the entity
An Entity Example
package edu.weber.domain;import javax.persistence.*;import java.io.*;
@Entitypublic class Customer implements Serializable{
private long id;private String firstName;private String lastName;
@Idpublic long getId() { return id; }public void setId(long id) { this.id = id; }
public String getFirstName() { return firstName; }public void setFirstName(String fn) { this.firstName = fn; }
public String getLastName() { return lastName; }public void setLastName(String ln) { this.lastName = ln; }
}
Corresponding Table Definition
create table Customer (id long primary key not null,firstName VARCHAR(255),lastName VARCHAR(255)
);
Elementary Schema Mappings
• @javax.persistence.Table• @javax.persistence.Column
• Assume a different table definition from before
create table CUSTOMER_TABLE (CUST_ID integer primary key not null,FIRST_NAME VARCHAR(20) not null,lastName VARCHAR(255) not null
);
Elementary Schema Mappings
• @javax.persistence.Table• Specifies the relational table the bean
class maps to
@Entity@Table(name=“CUSTOMER_TABLE”)public class Customer implements …………
Elementary Schema Mappings
• @javax.persistence.Column• Specifies how a particular field or
property is mapped to a column in a table@Id@Column(name=“CUST_ID”, nullable=false, columnDefinition=“integer”)public long getId() { return id; }public void setId(long id) { this.id = id; }
@Column(name=“FIRST_NAME”, length=20, nullable=false)public String getFirstName() { return firstName; }public void setFirstName(String fn) { this.firstName = fn; }
@Column(nullable=false)public String getLastName() { return lastName; }public void setLastName(String ln) { this.lastName = ln; }
Entities and Persistence
The Primary Key
Primary Key Overview
• Uniquely identifies an entity• Can be any serializable type
– Primitive type– Primitive wrappers (Integer, Double, etc.)– java.lang.String– Custom Classes composed of the above
• Single-Field (or Property) Primary Key– Map to a single persistence field
• Compound Primary Key– Custom-defined object whose instance
variables map to several persistence fields
Single-Property Primary Keys
• Map to one of the entity’s persistence fields
• @javax.persistence.Id• Identifies one (or more) properties that
make up the primary key
@Idpublic long getId() { return id; }public void setId(long id) { this.id = id; }
Autogenerated keys
• @javax.persistence.GeneratedValue
@Id@GeneratedValue(strategy=GenerationType.AUTO)public long getId() { return id; }public void setId(long id) { this.id = id; }
Compound Primary Keys
• Map to one or more of the entity’s persistence fields
• Implemented by a custom class– Must be serializable– Define equals() and hashcode()
methods– Instance fields must correspond to
entity’s persistence fields in both name and type
– Public no-argument constructor required
Compound Primary Key Examplepublic class CustomerPK
implements java.io.Serializable {private String lastName;private long ssn;
public CustomerPK() { } public CustomerPK(String lname, long ssn)
{ this.lastName = lname; this.ssn = ssn }// …getters and setters…
public boolean equals(Object obj) { if (obj == this) return true;
if (!(obj instanceof CustomerPK)) return false;CustomerPK pk = (CustomerPK)obj;
if(!lastName.equals(pk.lastName) || ssn != pk.ssn)return false;
else return true; }public int hashCode() {
return lastName.hashCode() + (int)ssn; } }
Annotating the Entity• Use @javax.persistence.IdClass
@Entity@IdClass(CustomerPK.class)
public class Customer implements Serializable{
private String firstName;private String lastName;private long ssn;
public String getFirstName() { return firstName; }public void setFirstName(String fn) { this.firstName = fn; }
@Idpublic String getLastName() { return lastName; }public void setLastName(String ln) { this.lastName = ln; }
@Idpublic long getSsn() { return ssn; }public void setSsn(long ssn) { this.ssn = ssn; }
}
Querying the Customer
CustomerPK pk = new CustomerPK(“Burke”, 012345678);Customer cust = entityManager.find(Customer.class, pk);
Entity Beans
Topics to be Covered:• Entities are POJOs• Managed/Unmanaged Entities• Persistence Unit• EntityManager• Basic Relational Mapping• The Primary Key