Your SlideShare is downloading. ×
0
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Java Persistence API
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Java Persistence API

11,394

Published on

Java Persistence API

Java Persistence API

Published in: Technology
1 Comment
47 Likes
Statistics
Notes
No Downloads
Views
Total Views
11,394
On Slideshare
0
From Embeds
0
Number of Embeds
17
Actions
Shares
0
Downloads
1,707
Comments
1
Likes
47
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Transcript

    • 1. Enterprise JavaBean 3.0 & Java Persistence APIs: Simplifying Persistence Carol McDonald Java Architect Sun Microsystems
    • 2. Speaker’s Qualifications <ul><li>Carol cDonald: </li></ul><ul><ul><li>Java Architect at Sun Microsystems </li></ul></ul><ul><ul><li>Before Sun, worked on software development of: </li></ul></ul><ul><ul><ul><li>Application to manage car Loans for Toyota (>10 million loans) </li></ul></ul></ul><ul><ul><ul><li>Pharmaceutical Intranet ( Roche Switzerland) </li></ul></ul></ul><ul><ul><ul><li>Telecom Network Mgmt ( Digital France) </li></ul></ul></ul><ul><ul><ul><li>X.400 Email Server ( IBM Germany) </li></ul></ul></ul>
    • 3. JPA: Simplifying/Unifying/Standardizing Persistence <ul><li>Simpler, easier and smarter </li></ul><ul><ul><li>Easy to develop </li></ul></ul><ul><li>POJO based programming/persistence model </li></ul><ul><ul><li>Simple Java classes – not EJB components , only 1 file instead of 3 </li></ul></ul><ul><ul><li>Entities usable outside the container </li></ul></ul><ul><ul><ul><li>No need for D ata T ransfer O bjects </li></ul></ul></ul><ul><ul><ul><li>Facilitates testability </li></ul></ul></ul><ul><li>Most configuration is defaulted – configure by exception only (configure only to override default) </li></ul>
    • 4. Simplifying/Unifying Persistence cont. <ul><li>Standardized o bject/ r elational m apping </li></ul><ul><ul><li>Standardized annotations @ and XML configuration files </li></ul></ul><ul><ul><ul><li>xml for mapping is optional </li></ul></ul></ul><ul><li>Support for pluggable 3 rd party Persistence provider s </li></ul><ul><li>Usable in Java EE , Enterprise JavaBeans 3.0 and Java SE environments </li></ul>
    • 5. Entities <ul><li>P lain O ld J ava O bjects (not an EJB) </li></ul><ul><ul><li>Created by means of new </li></ul></ul><ul><ul><li>No required interfaces (home, ejb, callback..) </li></ul></ul><ul><ul><li>Have persistent identity </li></ul></ul><ul><ul><li>May have both persistent and non-persistent state </li></ul></ul><ul><ul><ul><li>Simple types (e.g., primitives, wrappers, enums, serializables) </li></ul></ul></ul><ul><ul><ul><li>Composite dependent object types (e.g., Address) </li></ul></ul></ul><ul><ul><ul><li>Non-persistent state ( transient or @Transient) </li></ul></ul></ul><ul><ul><li>Can extend other Entity and non-Entity classes </li></ul></ul><ul><ul><li>Serializable; usable as detached objects in other tiers </li></ul></ul><ul><ul><ul><li>No need for d ata t ransfer o bjects </li></ul></ul></ul>
    • 6. Entity Annotated as “Entity” @Id denotes primary key @Entity public class Customer implements Serializable { @Id protected Long id; protected String name; public Customer() {} public Long getId() {return id;} public String getName() {return name;} public void setName(String name) {this.name = name;} … }
    • 7. Data Model and O-R Mapping <ul><ul><li>Basic and Relationship </li></ul></ul><ul><ul><li>Entity Inheritance </li></ul></ul><ul><ul><li>Entity Identity </li></ul></ul>
    • 8. An Example Data Model Maps entity states to data store Maps relationship to other entities Customer int id String name int c_rating Image photo Set<Order> orders Collection<Phone> phones ... Order int id Customer cust ... Phone int id Collection<Customer> custs ... 1 M M N
    • 9. Simple Mapping Mapping defaults to matching column name . Only configure if entity field and table column names are different public class Customer { int id; String name; int c_rating; Image photo; } @Entity(access=FIELD) @Column(name=“CREDIT”) @Id @Lob CUSTOMER ID NAME CREDIT PHOTO
    • 10. Entity Annotated as “Entity” @Id denotes primary key @Entity public class Customer implements Serializable { @Id protected Long id; protected String name; @Transient protected int reservationCount; public Customer() {} public Long getId() {return id;} public String getName() {return name;} public void setName(String name) {this.name = name;} … }
    • 11. Entity Class for Customer @Entity(access=FIELD) @Table(name = “customer”) public class Customer { @Id public int id; ... public String name; @Column(name=”CREDIT”) public int c_rating; @LOB public Image photo; ... } Annotated as “Entity” Data are accessed as fields @Id denotes primary key Maps to “customer” table Specify the table column to map to
    • 12. Relationships
    • 13. Entity Relationships <ul><li>One-to-one, one-to-many, many-to-many, many-to-one, relationships among entities </li></ul><ul><ul><li>bi-directional or uni-directional </li></ul></ul><ul><ul><li>Support for Collection, Set, List and Map </li></ul></ul><ul><li>Need to specify owning side in relationships </li></ul><ul><ul><li>Owning side table has the foreign key </li></ul></ul><ul><ul><li>OneToOne relationship – the side with the foreign key </li></ul></ul><ul><ul><li>OneTo Many , Many ToOne – many side </li></ul></ul>
    • 14. Relationship Mappings – OneToMany Bidirectional public class Order { int id; ... Customer cust ; } public class Customer { int id; ... Set<Order> orders; } @Entity(access=FIELD) @Entity(access=FIELD) @ManyToOne @OneToMany(mappedBy=“ cust ”) @Id @Id 1 n has to say where the foreign key is using mappedBy CUSTOMER ID . . . ORDER CUST_ID ID . . .
    • 15. Example ManyToOne bi-directional Order is the owner must call order.setCustomer (cust) whenever order added to customer. <ul><li>@Entity public class Order { </li></ul><ul><li>@Id protected Long id; </li></ul><ul><li>… </li></ul><ul><li>@ManyToOne protected Customer cust; </li></ul><ul><li>… </li></ul><ul><li>public Customer getCustomer() {return cust;} </li></ul><ul><li>public void setCustomer (Customer cust) { </li></ul><ul><li>this.cust = cust; </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>@Entity public class Customer { </li></ul><ul><li>@Id protected Long id; </li></ul><ul><li>… </li></ul><ul><li>@OneToMany(mappedBy=“cust”) </li></ul><ul><li>protected Set<Order> orders = new HashSet(); </li></ul><ul><li>… </li></ul><ul><ul><li>public void addOrder (Order order) { </li></ul></ul><ul><ul><li>this.orders.add (order); </li></ul></ul><ul><ul><li>order.setCustomer (this); } </li></ul></ul><ul><li>} </li></ul>
    • 16. Relationship Mappings – ManyToOne Automatically creates a ADDR_ID field for mapping. Can be overridden via @ManyToOne annotation public class Customer { int id; Address addr ; } CUSTOMER ADDR_ID ID ADDRESS . . . ID @Entity(access=FIELD) @ManyToOne @Id ADDR_ID
    • 17. Relationship Mappings – ManyToMany public class Customer { int id; ... Collection<Phone> phones ; } @Entity(access=FIELD) @Entity(access=FIELD) @Id @Id @ManyToMany @ManyToMany(mappedBy=“phones”) public class Phone { int id; ... Collection<Customer> custs ; } Join table name is made up of the 2 entities. Field name is the name of the entity plus the name of the PK field PHONES _ID CUSTS _ID CUSTOMER ID . . . PHONE ID . . . CUSTOMER_PHONE ID
    • 18. Relationship Mappings – ManyToMany Can override the default column names PHONES_ID CUST_ID CUSTOMER ID . . . PHONE ID . . . CUST_PHONE @Entity(access=FIELD) public class Customer { ... @ManyToMany @ JoinTable (table=@Table(name=“CUST_PHONE”), joinColumns =@JoinColumn(name=“CUST_ID”), inverseJoinColumns =@JoinColumn(name=“PHONES_ID”)) Collection<Phone> phones; }
    • 19. Example ManyToMany bi-directional customer is the owning side: must add/remove the phone from the customer's phones property. <ul><li>@Entity public class Phone { </li></ul><ul><li>@Id protected Long id; </li></ul><ul><li>… </li></ul><ul><li>@ManyToMany(mappedBy=“phones”) </li></ul><ul><li>protected Set<Customer> customers = new HashSet(); </li></ul><ul><li>… </li></ul><ul><li>} </li></ul><ul><li>@Entity public class Customer { </li></ul><ul><li>@Id protected Long id; </li></ul><ul><li>… </li></ul><ul><li>@ManyToMany </li></ul><ul><li>protected Set<Phone> phones = new HashSet(); </li></ul><ul><li>… </li></ul><ul><li>private Set<Phone> getPhones() {return phones;} </li></ul><ul><ul><li>public void addPhone (Phone phone) { </li></ul></ul><ul><ul><li>this .getPhones(). add (phone); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public void removePhone (Phone phone) { </li></ul></ul><ul><ul><li>this .getPhones(). remove (phone); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>
    • 20. Mapping of Embedded Objects @Entity(access=FIELD) @Embedded @Id @Embeddable(access=FIELD) public class CustomerInfo { String name; int credit; @Lob Image photo; } public class Customer { int id ; CustomerInfo info; } Embedded objects have no identity of their own . Takes on the identity of the container object CUSTOMER ID NAME CREDIT PHOTO
    • 21. Entity Inheritance: 3 possibilities: <ul><li>Concrete/Abstract entity class </li></ul><ul><ul><ul><li>Annotated with @Entity </li></ul></ul></ul><ul><ul><ul><li>Behaves like an entity </li></ul></ul></ul><ul><li>Mapped superclass </li></ul><ul><li>Non entity class </li></ul><ul><ul><li>Entity can extend </li></ul></ul>
    • 22. Entity Inheritance – (Abstract) Entity Class @Entity public abstract class Person { @Id protected Long id; protected String name; @Embedded protected Address address; } @Entity public class Customer extends Person { @Transient protected int orderCount; @OneToMany protected Set<Order> orders = new HashSet(); } @Entity public class Employee extends Person { @ManyToOne protected Department dept; }
    • 23. Entity Inheritance <ul><li>Concrete/Abstract entity class </li></ul><ul><li>Mapped superclass </li></ul><ul><ul><li>Contains common fields for all entities </li></ul></ul><ul><ul><ul><li>Provides common entity state </li></ul></ul></ul><ul><ul><li>Mapped superclass is NOT an entity </li></ul></ul><ul><ul><li>Annotated with @MappedSuperclass </li></ul></ul><ul><li>Non entity class </li></ul><ul><ul><li>Entity can extend: </li></ul></ul>
    • 24. Entity Inheritance – Mapped Superclass @MappedSuperclass public class Person { @Id protected Long id; protected String name; @Embedded protected Address address; } @Entity public class Customer extends Person { @Transient protected int orderCount; @OneToMany protected Set<Order> orders = new HashSet(); } @Entity public class Employee extends Person { @ManyToOne protected Department dept; }
    • 25. Entity Inheritance <ul><li>Concrete/Abstract entity class </li></ul><ul><li>Mapped superclass </li></ul><ul><li>Non entity class </li></ul><ul><ul><li>State of non entity super class is not persisted </li></ul></ul><ul><ul><li>Can not contain O/R mapping annotations </li></ul></ul><ul><ul><li>Entity can extend </li></ul></ul>
    • 26. Entity Inheritance – Non Entity Class public class Person { protected String name; } @Entity public class Customer extends Person { //Inherits name but not persisted @Id public int id; @Transient protected int orderCount; @OneToMany protected Set<Order> orders = new HashSet(); } @Entity public class Employee extends Person { //Inherits name but not persisted @Id public int id; @ManyToOne protected Department dept; }
    • 27. Mapping Entity Inheritance to DB Table <ul><li>Inheritance mapping strategies: </li></ul><ul><ul><li>Single table </li></ul></ul><ul><ul><li>Joined subclass </li></ul></ul><ul><ul><li>Table per class </li></ul></ul>
    • 28. Inheritance mapping strategies Object Model AirAnimal wingSpan: int LandAnimal legCount: int Animal id: int name: String
    • 29. Inheritance mapping strategies Data Models <ul><li>Single table: </li></ul>each class is stored in a separate table each concrete class is stored in a separate table all classes stored in the same table ANIMAL ID NAME LAND_ANML ID LEG_COUNT AIR_ANML ID WING_SPAN <ul><li>Joined Subclass: </li></ul><ul><li>Table per Class: </li></ul>LAND_ANML ID LEG_COUNT AIR_ANML ID WING_SPAN NAME NAME ANIMAL LEG_CNT ID DISC NAME WING_SPAN
    • 30. Discriminator Column and Value for Single Table @Entity @Table(name=&quot;ANIMAL&quot;) @Inheritance(strategy=SINGLE_TABLE) @DiscriminatorColumnName(name=”DISC”) @DiscriminatorValue(“ANIMAL”) public class Animal { @Id protected int id; protected String name; ... } @Entity @DiscriminatorValue(&quot;LANDANIMAL&quot;) public class LandAnimal extends Animal { @Column(name=”LEG_CNT”) protected int legCount; ... ANIMAL LEG_CNT ID DISC NAME WING_SPAN
    • 31. Discriminator Value for SingleTable
    • 32. Identity <ul><li>Every entity has a persistence identity </li></ul><ul><ul><li>Uniquely identifies that entity </li></ul></ul><ul><ul><li>Maps to primary key in the database </li></ul></ul><ul><li>Identity can be application or database generated </li></ul><ul><li>Must be defined on the ROOT of entity hierarchy or mapped superclass </li></ul>
    • 33. Types of Identity <ul><li>Simple </li></ul><ul><ul><li>@Id – single field/property in entity class </li></ul></ul><ul><ul><li>@GeneratedValue </li></ul></ul><ul><li>User defined: </li></ul><ul><ul><li>@EmbeddedId – single field/property in entity class </li></ul></ul><ul><ul><li>@IdClass – corresponds to multiple id field in entity class </li></ul></ul>@Id @GeneratedValue(strategy=SEQUENCE) private int id; @EmbeddedId private EmployeePK pk; @Entity @IdClass (EmployeePK.class) public class Employee { @Id private String empName; @Id private int dept; Class must be @Embeddable
    • 34. Using orm.xml for Mapping <ul><li>Can put some or all the mapping metadata in XML mapping files </li></ul><ul><ul><li>orm.xml located in META-INF directory of JAR </li></ul></ul><ul><ul><li>Can use orm.xml to specify entity mappings </li></ul></ul><ul><ul><li>Annotations not required </li></ul></ul><ul><li>At runtime, orm.xml override annotations </li></ul>
    • 35. Example of orm.xml File <entity-mappings> <entity class=”Customer”> <id name=”id”> <generated-value/> </id> <basic name=”c_rating”> <column name=”ratings”/> </basic> ... <one-to-many name=”orders” mapped-by=”cust”/> </entity> ... </entity-mappings> Overriding the default annotations in source
    • 36. Persistence <ul><ul><li>EntityManager </li></ul></ul><ul><ul><li>Persistence Unit </li></ul></ul><ul><ul><li>Persistence Context </li></ul></ul><ul><ul><li>Entity Lifecycle </li></ul></ul><ul><ul><li>Application Managed Persistence </li></ul></ul><ul><ul><li>Transactions </li></ul></ul>
    • 37. Persistence – Key Concepts <ul><li>Persistence unit </li></ul><ul><li>Entity manager </li></ul><ul><li>Persistence context </li></ul><ul><li>Transactions </li></ul>
    • 38. Persistence Unit Persistence Context Persistence Context Primary interface to interact with underlying persistence engine A set of entities associated with a particular transaction Configuration for entities mapped to a single data store Persistence Unit MyApp Employee e = new Employee(); e.setName(“Lucas”); em.persist(e); persistence.xml
    • 39. Persistence Unit <ul><li>Persistence Unit </li></ul><ul><ul><li>Configuration to map Entity classes in an application to a relational database </li></ul></ul><ul><li>persistence.xml defines one or more persistence units </li></ul><ul><ul><li>the JAR file that contains persistence.xml will be scanned for any classes annotated with @Entity </li></ul></ul>< persistence version=&quot;1.0&quot; xmlns =&quot; http://java.sun.com/xml/ns/persistence &quot;> < persistence-unit name=&quot; OrderPU &quot; transaction-type=&quot;JTA&quot;> < provider > org.hibernate.HibernatePersistence </provider> < jta-data-source > jdbc/order </jta-data-source> < jar-file >../lib/order.jar</jar-file> < class >com.acme.Order</class> </persistence-unit> </persistence> Optional to define entity classes
    • 40. Persistence – Key Concepts <ul><li>Persistence unit </li></ul><ul><li>Entity manager </li></ul><ul><ul><li>Primary interface to interact with underlying persistence engine </li></ul></ul><ul><li>Persistence context </li></ul><ul><ul><li>A set of entities managed by Entity Manager </li></ul></ul><ul><li>Transactions </li></ul>
    • 41. EntityManager Persistence Context Persistence Context Primary interface to interact with underlying persistence engine A set of managed entities associated with a particular transaction Configuration for entities mapped to a single data store Persistence Unit MyApp Employee e = new Employee(); e.setName(“Lucas”); em.persist(e); persistence.xml
    • 42. Persistence Context and EntityManager <ul><li>EntityManager </li></ul><ul><ul><li>API to manage the entity instance lifecycle </li></ul></ul><ul><ul><li>Allows your program to interact with underlying persistence engine </li></ul></ul><ul><ul><li>Provides the following functionalities </li></ul></ul><ul><ul><ul><li>Lifecycle operations – persist(), remove(), refresh(), merge() </li></ul></ul></ul><ul><ul><ul><li>Finder – find(), getReference() </li></ul></ul></ul><ul><ul><ul><li>Factory for query objects – createNamedQuery(), createQuery(), createNativeQuery() </li></ul></ul></ul><ul><ul><ul><li>Managing persistence context – flush(), clear(), close(), getTransaction(), ... </li></ul></ul></ul><ul><li>Persistence Context </li></ul><ul><ul><li>Set of managed entities , belonging to a single persistence unit </li></ul></ul>
    • 43. Persistence Context and EntityManager Persistence Context EntityManager persist() remove() refresh() merge() find() createQuery() createNamedQuery() contains() flush() SessionBean JavaBean Servlet
    • 44. Persistence – Key Concepts creates creates Configured by Manages
    • 45. EntityManager Example @Stateless public ShoppingCartBean implements ShoppingCart { @PersistenceContext EntityManager entityManager; public OrderLine createOrderLine(Product product , Order order) { OrderLine orderLine = new OrderLine(order, product); entityManager.persist (orderLine) ; return (orderLine); } public OrderLine updateOrderLine(OrderLine orderLine) { return ( entityManager.merge ( orderLine ) ); } } Dependency injection
    • 46. EJB 3.0: Dependency Injection <ul><li>Dependency Injection </li></ul><ul><li>Bean specifies what it needs through @ </li></ul><ul><li>References to resources are injected when instance is constructed: </li></ul><ul><ul><li>@Resource : for connection factories, EJBContext, UserTransaction , etc. </li></ul></ul><ul><ul><li>@EJB : For EJB References </li></ul></ul><ul><ul><li>@PersistenceContext : For container-managed EntityManager </li></ul></ul><ul><ul><li>@PersistenceUnit : For EntityManagerFactory </li></ul></ul>
    • 47. Entity Lifecycle State Diagram <ul><ul><ul><li>New entity instance is created </li></ul></ul></ul><ul><ul><ul><li>Entity is not yet managed or persistent </li></ul></ul></ul><ul><ul><ul><li>Entity becomes managed </li></ul></ul></ul><ul><ul><ul><li>Entity becomes persistent in database on transaction commit </li></ul></ul></ul>new() <ul><ul><ul><li>Entity is removed </li></ul></ul></ul><ul><ul><ul><li>Entity is deleted from database on transaction commit </li></ul></ul></ul><ul><ul><ul><li>State of detached entity is merged back into managed entity </li></ul></ul></ul>no longer associated with persistence context New Detached Removed Managed persist() merge () remove () Updates PC ends
    • 48. Entity Lifecycle Illustrated – The Code @Stateless public ShoppingCartBean implements ShoppingCart { @PersistenceContext EntityManager entityManager; public OrderLine createOrderLine(Product product , Order order) { OrderLine orderLine = new OrderLine(order, product); entityManager.persist(orderLine); return (orderLine); } public OrderLine updateOrderLine(OrderLine orderLine) { OrderLine newOL= entityManager.merge(orderLine) return ( newOL ) ); } } New entity Managed entity Detached entity
    • 49. Entity Manager Persist: <ul><li>Insert a new instance of the entity into the database (when transaction commits) </li></ul><ul><li>The entity instance becomes “managed” in the persistance context </li></ul><ul><li>Persist operation optionally cascades to related objects </li></ul><ul><li>public Customer createCustomer(intid, String name) { </li></ul><ul><ul><li>Customer cust= new Customer(id, name); </li></ul></ul><ul><ul><li>entityManager.persist(cust); </li></ul></ul><ul><ul><li>return cust; </li></ul></ul><ul><li>} </li></ul>
    • 50. Cascading Persist example: ManyToOne public class Order { int id; ... Customer cust ; } public class Customer { int id; ... Set<Order> orders; } @Entity(access=FIELD) @Entity(access=FIELD) @ManyToOne @OneToMany(mappedBy=“cust”) @Id @Id CUSTOMER ID . . . ORDER CUST_ID ID . . .
    • 51. Persist OneToMany bi-directional Not Cascading em.persist to persist the order @Stateless public class OrderManagementBean implements OrderManagement { … @PersistenceContext EntityManager em; … public Order addNewOrder (Long id,Product product){ Customer cust = em.find (Customer.class, id); Order order = new Order(product); customer.getOrders().add(order); order.setCustomer(cust); em.persist(order); return order; } }
    • 52. Cascading Persist cascade=Persist Order persisted automatically, when added to Customer @Entity public class Customer { @Id protected Long id; … @OneToMany(cascade=PERSIST) protected Set<Order> orders = new HashSet(); } … public Order addNewOrder(Customer customer, Product product) { Order order = new Order(product); customer.getOrders().add(order); order.setCustomer(cust); return order; }
    • 53. Entity Manager Find, Remove: <ul><li>Find </li></ul><ul><ul><li>Get a managed entity instance with a given persistent identity </li></ul></ul><ul><ul><li>Return null if not found </li></ul></ul><ul><li>Remove </li></ul><ul><ul><li>Delete entity with the given persistent identity from the database (deleted when transaction commits) </li></ul></ul><ul><ul><li>Optionally cascades to related objects </li></ul></ul><ul><li>public void removeCustomer(Long custId) { </li></ul><ul><ul><li>Customer cust= </li></ul></ul><ul><ul><li>entityManager.find (Customer.class, custId); </li></ul></ul><ul><ul><li>entityManager.remove (cust); </li></ul></ul><ul><li>} </li></ul>
    • 54. Remove When order is removed, the lineItems are removed with it @Entity public class Order { @Id protected Long orderId; … @OneToMany(cascade={PERSIST,REMOVE}) protected Set<LineItem> lineItems = new HashSet(); } … @PersistenceContext EntityManager em; … public void deleteOrder(Long orderId) { Order order = em.find(Order.class, orderId); em.remove(order); }
    • 55. Merge: <ul><li>State of detached entity gets merged into a managed copy of entity </li></ul><ul><li>Managed entity is returned </li></ul><ul><li>Merge operation optionally cascades to related objects </li></ul>public Customer storeUpdatedCustomer(Customer cust) { Customer customer =entityManager.merge( cust ); return customer; } Managed Not managed
    • 56. Merge When order is merged, the lineItems are merged with it @Entity public class Order { @Id protected Long orderId; … @OneToMany(cascade={PERSIST, REMOVE, MERGE}) protected Set<LineItem> lineItems = new HashSet(); } … @PersistenceContext EntityManager em; … public Order updateOrder(Order changedOrder) { return em.merge(changedOrder); }
    • 57. Detached Objects as DTOs <ul><ul><li>public OrderLine updateOrderLine( </li></ul></ul><ul><ul><li>OrderLine orderLine) { </li></ul></ul><ul><ul><li>OrderLine newOL = em.merge(orderLine) </li></ul></ul><ul><ul><li> return(newOL ); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>Entity beans may be passed by value as detached objects </li></ul><ul><li>Must implement Serializable interface if detached object is to be sent across the wire </li></ul>Returned to caller as Detached Detached Managed Detached after return
    • 58. Types of Persistence Context and Entity Managers Persistence Context Entity Manager Persistence Context Entity Manager Data source same entity
    • 59. Entity Manager & Persistence Context Types <ul><li>Two types of EntityManagers: </li></ul><ul><ul><li>Container-managed EntityManager – intended for Java EE </li></ul></ul><ul><ul><li>Application-managed EntityManager – intended for Java SE/EE </li></ul></ul><ul><li>Two types of persistence context: </li></ul><ul><ul><li>transaction-scoped persistence context </li></ul></ul><ul><ul><li>extended persistence context </li></ul></ul>
    • 60. Container Managed Entity Manager <ul><li>Container-managed entity manager </li></ul><ul><ul><li>EntityManager Lifecycle managed by the Java EE container </li></ul></ul><ul><ul><li>EntityManager obtained via resource injection or JNDI lookup: </li></ul></ul><ul><ul><ul><li>@PersistenceContext EntityManager entityManager; </li></ul></ul></ul>
    • 61. Types of Persistence Context <ul><li>Persistence Context 2 Types: </li></ul><ul><ul><li>lifetime maybe transaction-scoped or extended </li></ul></ul><ul><li>Transaction-scoped persistence context </li></ul><ul><ul><li>bound to a JTA transaction— starts and ends at transaction boundaries </li></ul></ul><ul><ul><li>Propagated across EJB components within JTA transactions </li></ul></ul><ul><ul><li>entities are detached from the persistence context when transaction ends </li></ul></ul>
    • 62. Java™ Transaction Service Application Server Transaction Service Application UserTransaction interface Resource Manager XAResource interface Transactional operation TransactionManager Interface Resource EJB Transaction context
    • 63. Transactions with Container Managed EntityManager <ul><li>JTA </li></ul><ul><ul><li>Transactions are controlled through JTA </li></ul></ul><ul><ul><li>Container-managed entity manager always JTA transactions </li></ul></ul>
    • 64. EJB & Container-Managed Entity Manager & Transaction-scoped Persistence Context @Stateless public ShoppingCartBean implements ShoppingCart { @PersistenceContext(unitName=”orderPU”) EntityManager entityManager; public OrderLine createOrderLine (Product product , Order order) { OrderLine orderLine = new OrderLine(order, product); entityManager.persist(orderLine); return (orderLine); } public OrderLine updateOrderLine(OrderLine orderLine) { return ( entityManager.merge(orderLine) ); } } Persistence context
    • 65. Spring 2.0 & JPA @Repository @Transactional public class CatalogDAO implements CatalogService { @PersistenceContext (unitName=&quot;PetCatalogPu&quot;) private EntityManager em; public List<Item> getItems (int firstItem,int batchSize) { Query q = em. createQuery(&quot;select object(o) from Item as o&quot;); q.setMaxResults(batchSize); q.setFirstResult(firstItem); List<Item> items= q.getResultList(); return items; }
    • 66. Java EE JTA Transactions <ul><li>Session Bean: Container-managed transaction is default </li></ul><ul><ul><li>Specify declaratively </li></ul></ul><ul><ul><li>Annotation: @TransactionAttribute </li></ul></ul><ul><ul><li>Values: REQUIRED (default) , REQUIRES_NEW, MANDATORY, NEVER, NOT_SUPPORTED, SUPPORTS </li></ul></ul><ul><ul><li>On method or class </li></ul></ul><ul><li>Session Bean: Bean-managed transactions </li></ul><ul><ul><li>@Resource UserTransaction to get UserTransaction API </li></ul></ul><ul><li>Servlet: uses @Resource UserTransaction to get JTA UserTransaction API </li></ul>
    • 67. Stateless Session Bean in Java EE 5.0 <ul><li>@Stateless </li></ul><ul><li>public class AirlineReservationBean implements AirlineReservation { </li></ul><ul><li>. . . </li></ul><ul><li>@TransactionAttribute(MANDATORY) </li></ul><ul><li>public boolean book (int passId, int flightId) { </li></ul><ul><ul><li>Flight flight = em.find(Flight.class, flightId); </li></ul></ul><ul><ul><li>Passenger pgr = em.find(Passenger.class, passId); </li></ul></ul><ul><ul><li>return flight.addPassenger(pgr); </li></ul></ul><ul><li>} </li></ul><ul><li>.. </li></ul><ul><li>} </li></ul>NEW! Java EE 5 <ul><ul><li>Container Managed Transaction </li></ul></ul>Container Managed Transaction
    • 68. Declarative Transaction Management Example TX_REQUIRED TX_REQUIRED TX_REQUIRED PC PC PC Session Facade Inventory Service Order Service Check Out 1. Update Inventory New Persistence Context Persistence Context Propagated Transaction Attributes 2. Create Order and send JMS message to Warehouse Application
    • 69. Persistence Context Propagation <ul><li>@Stateless public class ControllerBean implements ControllerService { </li></ul><ul><li>@EJB InventoryService inv ; </li></ul><ul><li>@EJB OrderService ord ; </li></ul><ul><ul><li>public void manageOrderInventory(Item i, Product p) { </li></ul></ul><ul><ul><ul><li>inv.createOrder (item); </li></ul></ul></ul><ul><ul><ul><li>ord.updateInventory (Product p) </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>
    • 70. Persistence Context Propagation <ul><li>@Stateless public class OrderServiceBean implements OrderService { </li></ul><ul><li>@PersistenceContext EntityManager em1; </li></ul><ul><ul><li>public void createOrder (Item item) { </li></ul></ul><ul><ul><ul><li>em1.persist (new Order(item)); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>@Stateless public class InventoryServiceBean implements InventoryService { </li></ul><ul><li>@PersistenceContext EntityManager em2; </li></ul><ul><ul><li>public void updateInventory (Product p) { </li></ul></ul><ul><ul><ul><li>Product product = em2.merge (p); </li></ul></ul></ul><ul><ul><ul><li>. . . </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>
    • 71. Transaction Example Application Server Transaction Manager Transaction context DataBase Server and JMS Provider Resource Client Controller Inventory Order 1) Check Out TX_REQUIRED TX_REQUIRED BEGIN 4) Update Inventory 7) createOrder 11) Check context x to see if updates will work 12) Commit or rollback Start Prepare 10) END
    • 72. Web & Container-Managed EM <ul><li>Servlet Resource injection and Thread safety : </li></ul><ul><li>EntityManager instance is not thread safe </li></ul><ul><li>Servlets are multi-threaded </li></ul><ul><li>Entity Manager Can be obtained using JNDI </li></ul><ul><li>Lifecyle managed by the container </li></ul><ul><ul><li>So still less code than application managed </li></ul></ul>
    • 73. Beware of Injected Objects public class ShoppingCartServlet extends HttpServlet { @PersistenceContext EntityManager em ; protected void doPost(HttpServlet req, ...) { Order order order = ...; em.persist(order) ; } public class ShoppingCartServlet extends HttpServlet { @PersistenceUnit (name=&quot; PetstorePu &quot;) protected void doPost(HttpServlet req, ...) { EntityManager em = (EntityManager) new InitialContext().lookup(&quot;java:comp/env/PetstorePu&quot;); Order order order = ...; em.persist(order); } WRONG CORRECT <ul><ul><li>EntityManager instance is not thread safe, Servlets are multi-threaded </li></ul></ul>
    • 74. Web and JTA <ul><li>Transactions must be managed by the developer </li></ul><ul><ul><ul><li>Unlike with EJBs where they can be managed by the container </li></ul></ul></ul><ul><ul><ul><li>Use </li></ul></ul></ul><ul><ul><ul><ul><li>@Resource UserTransaction utx ; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Begin(), Commit (), rollback () </li></ul></ul></ul></ul>
    • 75. Web JTA Transaction and Container EM protected void buyBook(String book, int custId, String creditCard) throws … { utx.begin(); Customer customer = new CustomerHelper (). getCustomer (custId); Order order = new OrderHelper (). create (book, creditCard, customer); utx.commit(); } JTA
    • 76. Web JTA Transaction and Container EM EM public Order create (String book, String creditCard, Customer customer) { EntityManager em = (EntityManager) new InitialContext() .lookup(“java:comp/env/persistence/bookStore”); Order order = new Order(customer); order.setCreditCard(creditCard); order.setBook(book); em.persist (order); } //CustomerHelper public Customer getCustomer (int id) { EntityManager em = (EntityManager) new InitialContext().lookup( “ java:comp/env/persistence/bookStore”); return em.find (Customer.class, id); } // OrderHelper
    • 77. Recommendation: Stateless Session Beans <ul><li>In our business logic bean, we had to deal with transactions explicitly </li></ul><ul><ul><li>Consider using a stateless session bean (EJB) </li></ul></ul><ul><ul><ul><li>Transactions managed by the container </li></ul></ul></ul><ul><ul><ul><li>EM injected by container </li></ul></ul></ul><ul><ul><li>Also get other benefits: </li></ul></ul><ul><ul><ul><li>No more thread safety concerns </li></ul></ul></ul><ul><ul><ul><li>Scalability (across server instances) </li></ul></ul></ul><ul><ul><ul><li>Participate in cross-resource transactions </li></ul></ul></ul>
    • 78. Web component using Stateless Session <ul><li>@EJB CustomerMgr customerMgr ; </li></ul><ul><li>@EJB OrderMgr orderMgr ; </li></ul><ul><li>protected void buyBook(String book, int custId, String creditCard) throws … { </li></ul><ul><ul><li>Customer customer = customerMgr .getCustomer(custId); </li></ul></ul><ul><ul><li>Order order = orderMgr .create(book, </li></ul></ul><ul><ul><ul><li>creditCard, customer); </li></ul></ul></ul><ul><li>} </li></ul>No need for Transaction Management
    • 79. Stateless Session and Container EM No need for JNDI lookup of EM No need for Transaction Management @Stateless public class OrderMgrBean implements OrderMgr { @PersistenceContext EntityManager em; create(String book, String creditCard, Customer cust) { Order order = new Order(cust); order.setCreditCard(creditCard); order.setBook(book); em.persist(order); } } @Stateless public class CustomerMgrBean implements CustomerMgr { @PersistenceContext EntityManager em; public Customer getCustomer(int id) { return em.find(Customer.class, id); } }
    • 80. Types of Persistence Context <ul><li>Persistence Context </li></ul><ul><ul><li>lifetime maybe transaction-scoped or extended </li></ul></ul><ul><li>Transaction-scoped persistence context </li></ul><ul><li>Extended persistence context </li></ul><ul><ul><li>spans multiple transactions </li></ul></ul><ul><ul><li>exists from the time the EntityManager instance is created until it is closed </li></ul></ul><ul><ul><li>Defined when the EntityManager instance is created </li></ul></ul>
    • 81. Extended Persistence Context @Stateful public class ShoppingCart { //Specify that we want an EXTENDED @PersistenceContext (type=PersistenceContextType.EXTENDED) EntityManager em ; //Cached order private Order order ; //Find and cache order public void lookupOrder(String id) { //order remains managed for the lifetime of the bean order = em.find(Order.class, id); }
    • 82. Persistence Context- Transactional vs. Extended @Stateless public class OrderSessionStateless implements OrderService { @PersistenceContext(unitName=”java_one”) EntityManager em; public void addLineItem (OrderLineItem li){ // First, look up the order. Order order = em.find(Order.class, orderID); order.lineItems.add(li); } @Stateful public class OrderSessionStateful implements OrderService { @PersistenceContext(type = PersistenceContextType. EXTENDED )) EntityManager em; // Order is a member variable Loaded from the db in lookupOrder Order order public void addLineItem (OrderLineItem li){ // No em.find invoked for the order object order.lineItems.add(li); }
    • 83. Extended Persistence Context – When? <ul><li>to keep and reuse managed entities that are the subject of the conversation workflow </li></ul><ul><ul><li>HTTPSession, stateful session bean </li></ul></ul><ul><li>Entities remain managed and cached over multiple transactions </li></ul><ul><ul><li>Become detached when EntityManager is closed or when Stateful session bean is removed </li></ul></ul>
    • 84. Conversation @Stateful public class OrderBean { @PersistenceContext(type=EXTENDED) EntityManager em ; public void add(String itemCode, int qty) { ... } public void confirmOrder() { ... } ... } ________________________________________________________________ protected void doPost(HttpServletRequest req, ...) throws ... { String cmd = req.getParameter(“cmd”); if (cmd.equals(“NEW”)) { //Create stateful session bean, hold in HttpSession req.getSession().setAttribute(“order”, orderBean); } else if (cmd.equals(“ADD_ITEM”)) { //Add item to order bean orderBean.add(...); } else if (cmd.equals(“CONFIRM”)) { orderBean.confirmOrder(); order.remove(); req.getSession().removeAttribute(“order”); }
    • 85. Persistence Context Source: Internal benchmarks Does it affect performance? Micro benchmark with lots of lookups
    • 86. Entity Manager 2 Types <ul><li>Container-managed entity manager </li></ul><ul><li>Application-managed entity manager </li></ul><ul><ul><li>Created by EntityManagerFactory : </li></ul></ul><ul><ul><ul><li>EntityManager em = emf.createEntityManager(); </li></ul></ul></ul><ul><ul><li>Life cycle managed by the application </li></ul></ul><ul><ul><li>Also available in Java SE environments </li></ul></ul><ul><ul><li>Must use extended persistence context </li></ul></ul><ul><ul><li>May use JTA (Web) or RESOURCE_LOCAL (Java SE) transaction type </li></ul></ul>
    • 87. Transaction Demarcation <ul><li>Appication managed entity manager Transactions </li></ul><ul><ul><li>Web are either JTA or Resource local </li></ul></ul><ul><ul><li>JavaSE are always resource local </li></ul></ul><ul><li>JTA transaction </li></ul><ul><ul><li>UserTransaction API is injected </li></ul></ul>
    • 88. Data Base Transaction Management Transaction Manager EJB Container Resource Manager Data Base JTA A S EJB Local Servlet JDBC Transactions JTA Transactions servlet Resource Manager EJB servlet servlet servlet Java SE
    • 89. Application managed Entity Manager and JTA Transaction ( Web ) @Resource UserTransaction utx; @PersistenceUnit EntityManagerFactory factory; public void createDistributor(String n) { //Begin transaction utx.begin(); EntityManager em = emf.createEntityManager() ; //Create entity Distributor dist = new Distributor(); dist.setName(n); //Save it em.persist( dist ) ; //Commit transaction and close EntityManager utx.commit(); em.close() ; }
    • 90. Application Managed EM Extended Persistence Context Helper public class ExtendedPersistenceContextServlet extends HttpServlet { @PersistenceUnit EntityManagerFactory emf; public EntityManager getEntityManager (HttpSession s) { EntityManager em = s.getAttribute(“entityManager”); if (em==null) { em = emf.createEntityManager(); s.setAttribute(“entityManager”, em); } em.joinTransaction(); return em; } public void endConversation (HttpSession s) { getEntityManager().close(); s.removeAttribute(“entityManager”); }
    • 91. EntityManager in JavaSE <ul><li>Application must use javax.persistence.Persistence class to obtain an instance of EntityManagerFactory </li></ul><ul><li>No propagation of persistence context </li></ul>
    • 92. Transaction Demarcation <ul><li>Appication managed entity manager Transactions </li></ul><ul><ul><li>JavaSE are always resource local </li></ul></ul><ul><li>Resource local transactions </li></ul><ul><ul><li>Use EntityTransaction from EntityManager </li></ul></ul>
    • 93. Example EntityManager in JavaSE <ul><li>public class SalaryChanger { </li></ul><ul><li>public static void main(String[] args) { </li></ul><ul><li>EntityManagerFactory emf = Persistence </li></ul><ul><li>.createEntityManagerFactory(“HRSystem”); </li></ul><ul><li>EntityManager em = emf.createEntityManager(); </li></ul><ul><li>try { </li></ul><ul><li>EntityTransaction tx = em.getTransaction(); </li></ul><ul><li>Employee empl = em.find (Employee.class, new Integer(args[0])); </li></ul><ul><li>empl.setSalary(new Integer(args[1])); </li></ul><ul><li>tx.commit(); </li></ul><ul><ul><li>} finally { </li></ul></ul><ul><li>em.close(); </li></ul><ul><li>emf.close(); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
    • 94. RESOURCE_LOCAL Transaction Java SE // Create EntityManagerFactory for a persistence unit // called manager1 EntityManagerFactory emf = Persistence.createEntityManagerFactory(&quot;manager1&quot;); EntityManager em = emf.createEntityManager(); // Get a transaction instance and start the transaction EntityTransaction tx = em.getTransaction(); // Create a new customer,persist and commit it. tx.begin(); Distributor dist = new Distributor(); dist.setName(&quot;Joe Smith&quot;); em.persist(dist); tx.commit(); em.close(); emf.close();
    • 95. Summary EntityManager Types <ul><li>Container managed Entity Manager </li></ul><ul><ul><li>Obtained by Injection or JNDI lookup, don't need to close </li></ul></ul><ul><ul><li>Always JTA </li></ul></ul><ul><ul><li>Persistence Context Transaction Scoped </li></ul></ul><ul><ul><ul><li>Entities detached at end of transaction </li></ul></ul></ul><ul><ul><li>Or Extended Persistence Context </li></ul></ul><ul><ul><ul><li>Entities stay managed beyond transaction only for Stateful Session Bea n </li></ul></ul></ul><ul><li>Application managed Entity Manager </li></ul><ul><ul><ul><li>Created using EntityManagerFactory , must close </li></ul></ul></ul><ul><ul><ul><li>May be either JTA or RESOURCE_LOCAL </li></ul></ul></ul><ul><ul><ul><li>Must use extended persistence context : created when the entity manager is created and kept until the entity manager is closed </li></ul></ul></ul><ul><ul><ul><li>No propagation of persistence context </li></ul></ul></ul>
    • 96. Queries <ul><ul><li>EJB Query Syntax </li></ul></ul><ul><ul><li>Named, Dynamic, Native Queries </li></ul></ul><ul><ul><li>Polymorphic Queries </li></ul></ul>
    • 97. Java Persistence Query Language <ul><li>SQL-like query language </li></ul><ul><li>Queries expressed in terms of Entities </li></ul><ul><li>Provides functionality like select, update and delete </li></ul><ul><li>Portable across databases </li></ul>
    • 98. Projection <ul><li>SELECT e.name, d.name </li></ul><ul><li>FROM Employee e JOIN e.department d </li></ul><ul><li>WHERE e.status = ‘FULLTIME’ </li></ul><ul><li>SELECT new com.example.EmployeeInfo (e.id, e.name, e.salary, e.status, d.name) </li></ul><ul><li>FROM Employee e JOIN e.department d </li></ul><ul><li>WHERE e.address.state = ‘CA’ </li></ul>
    • 99. Subqueries <ul><li>SELECT DISTINCT emp </li></ul><ul><li>FROM Employee emp </li></ul><ul><li>WHERE EXISTS ( </li></ul><ul><ul><li>SELECT mgr </li></ul></ul><ul><ul><li>FROM Manager mgr </li></ul></ul><ul><ul><li>WHERE emp.manager = mgr </li></ul></ul><ul><ul><li>AND emp.salary > mgr.salary) </li></ul></ul>
    • 100. Joins <ul><li>SELECT DISTINCT o </li></ul><ul><li>FROM Order o JOIN o.lineItems l JOIN l.product p </li></ul><ul><li>WHERE p.productType = ‘shoes’ </li></ul><ul><li>SELECT DISTINCT c </li></ul><ul><li>FROM Customer c LEFT JOIN FETCH c.orders </li></ul><ul><li>WHERE c.address.city = ‘San Francisco’ </li></ul>
    • 101. Queries <ul><li>Dynamic queries </li></ul><ul><ul><li>Query string is specified at runtime </li></ul></ul><ul><li>EntityManager is factory for Query objects </li></ul><ul><ul><li>createQuery </li></ul></ul>
    • 102. Dynamic Queries public List findWithName (String name) { Query query = em.createQuery ( “ SELECT c FROM Customer c” + “ WHERE c.name LIKE :custName ”) query.setParameter(“ custName ”, name); query.setMaxResults(10); return (query.getResultList()); }
    • 103. Queries <ul><li>Static queries </li></ul><ul><ul><li>Defined with Java language metadata or XML </li></ul></ul><ul><ul><ul><li>Annotations: @NamedQuery , @NamedNativeQuery </li></ul></ul></ul><ul><li>EntityManager is factory for Query objects </li></ul><ul><ul><li>createNamedQuery </li></ul></ul>
    • 104. Static NamedQuery <ul><li>@NamedQuery ( </li></ul><ul><li>name=“findCustomersByName”, </li></ul><ul><li>queryString= </li></ul><ul><li>“ SELECT c FROM Customer c” </li></ul><ul><li>+ “WHERE c.name LIKE :custName ” </li></ul><ul><li>) </li></ul><ul><li>@PersistenceContext public EntityManager em; </li></ul><ul><li>Query query = </li></ul><ul><li>em.createNamedQuery (“findCustomersByName”); </li></ul><ul><li>query.setParameter(“ custName ”, “smith”) </li></ul><ul><li>List customers = query.getResultList(); </li></ul>
    • 105. Native SQL vs JPQL <ul><li>Native SQL </li></ul><ul><ul><li>Returns raw data – field values for the entity </li></ul></ul><ul><ul><li>Complex SQL for navigating relationships </li></ul></ul><ul><li>Java Persistence Query Language </li></ul><ul><ul><li>Returns entities </li></ul></ul><ul><ul><li>Relationships can be navigated using a “.” </li></ul></ul><ul><ul><li>Similar to SQL - small learning curve </li></ul></ul>
    • 106. Queries <ul><li>Query methods for controlling max results, pagination, flush mode </li></ul>
    • 107. Advance Query API <ul><li>Scrolling through result set </li></ul><ul><li>Query hints </li></ul>Query q = em.createQuery(“select e from Employee e”, Employee.class); //Set cursor to the 6 th record q. setFirstResult (5); //Retrieve only 100 employess q. setMaxResult (100); Collection<Employee> emps = q.getResultList(); q. setHint (“ toplink.cache-usage ”, &quot;DoNotCheckCache&quot; );
    • 108. Stateful Session Scroller @Stateful public class ResultPagerBean implements ResultPager { @PersistenceContext (unitName=&quot;QueryPaging&quot;) private EntityManager em ; private String reportQueryName; private int currentPage, maxResults,pageSize ; public void init (int pageSize, String countQueryName, String reportQueryName) { currentPage = 0; this.pageSize = pageSize; this.reportQueryName = reportQueryName; maxResults = (Long) em.createNamedQuery ( countQueryName ) .getSingleResult(); maxResults = resultCount.longValue(); } public List getCurrentResults () { return em.createNamedQuery(reportQueryName) . setFirstResult ( currentPage * pageSize ) . setMaxResults ( pageSize ) .getResultList(); } public void next() { currentPage++; }
    • 109. Polymorphic Queries <ul><li>All Queries are polymorphic by default </li></ul><ul><ul><li>That is to say that the FROM clause of a query designates not only instances of the specific entity class(es) to which it explicitly refers but of subclasses as well </li></ul></ul>select avg(e.salary) from Employee e where e.salary > 80000 This example returns average salaries of all employees, including subtypes of Employee, such as Manager .
    • 110. Best Practices and Gotchas
    • 111. <ul><li>EJB 3.0 specification assumes </li></ul><ul><ul><li>Optimistic locking based on version consistency </li></ul></ul><ul><li>All relationships with @Version included in check </li></ul><ul><ul><li>Not used by application </li></ul></ul><ul><li>@Entity class Order { </li></ul><ul><ul><li>@Version public TimeStamp version; </li></ul></ul><ul><li>In highly concurrent environment, pessimistic locking may be a better option </li></ul><ul><ul><li>Optimistic locking may result in lots of rollbacks </li></ul></ul><ul><ul><li>Vendor specific </li></ul></ul><ul><li>@QueryHint(name=TopLinkQueryHints.PESSIMISTIC_LOCK, value=PessimisticLock.LockNoWait); </li></ul>Locking
    • 112. Transactions <ul><li>May not want a transaction when browsing data </li></ul><ul><ul><li>For Session Bean use @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) </li></ul></ul>
    • 113. Executing a Query Outside of a Transaction @Stateless public class QueryServiceBean implements QueryService { @PersistenceContext(unitName=&quot;EmployeeService&quot;) EntityManager em; @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public List findAllDepartmentsDetached() { return em.createQuery(&quot;SELECT d FROM Department d&quot;) .getResultList(); } // ... }
    • 114. Transactions <ul><li>Propagation of EntityManagers between components </li></ul><ul><ul><li>Create EntityManager in JTA transaction </li></ul></ul><ul><ul><li>If EntityManager created outside of JTA transaction, use joinTransaction() </li></ul></ul>EntityManager em = factory.createEntityManager() ; utx.begin() ; em.joinTransaction() ; Join this transaction
    • 115. Fetch Types <ul><li>Data fetching strategy </li></ul><ul><ul><li>EAGER – load data all together immediately </li></ul></ul><ul><ul><li>LAZY – load data only when accessed </li></ul></ul><ul><ul><ul><li>Hint when FetchType is LAZY </li></ul></ul></ul><ul><li>FetchType LAZY benefits large objects and relationships with deep hierarchies </li></ul><ul><ul><li>Use when field or relationship may not be used </li></ul></ul><ul><li>Default is EAGER except for 1:m and m:n relationships </li></ul><ul><li>EAGER required if accessing properties outside a txn </li></ul><ul><ul><li>Accessing unloaded properties on Detached Entity throws an exception </li></ul></ul>
    • 116. Example Lazy <ul><li>// Order Entity has a 1:M relationship with OrderLineItem. </li></ul><ul><li>@Entity </li></ul><ul><li>public class Order { </li></ul><ul><ul><li>@OneToMany(fetchType= FetchType.LAZY , ...) </li></ul></ul><ul><ul><li>public Collection<OrderLineItem> getLineItems(){ </li></ul></ul><ul><ul><ul><li>return lineItems; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>// Stateless Session Bean </li></ul><ul><li>@Stateless </li></ul><ul><li>public class OrderSessionStateless { </li></ul><ul><ul><li>@PersistenceContext private EntityManager em; </li></ul></ul><ul><ul><li>public Order loadOrder(String orderID){ </li></ul></ul><ul><li>em.find(orderID); </li></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>
    • 117. Entity benchmark FetchType—Relationship Source: Internal benchmarks
    • 118. Join Fetch to load relationship <ul><li>SELECT DISTINCT c </li></ul><ul><li>FROM Customer c LEFT JOIN FETCH c.orders </li></ul><ul><li>WHERE c.address.city = ‘San Francisco’ </li></ul>
    • 119. Navigating Relationships Options… <ul><li>EAGER—Too many joins? SELECT d.id, ..., e.id, ... FROM Department d left join fetch Employee e on e.deptid = d.id </li></ul><ul><ul><li>What will it look like if you need to join more than two tables? </li></ul></ul><ul><li>LAZY—N +1 problem SELECT d.id, ... FROM Department d // 1 time SELECT e.id, ... FROM Employee e WHERE e.deptId = ? // N times </li></ul><ul><ul><li>How many trips to the database will it be if there are more relationships? </li></ul></ul>
    • 120. Navigating Relationships <ul><ul><li>Solution is in the Query string </li></ul></ul><ul><li>Query q = em.createQuery( </li></ul><ul><li>“ select d from Department d </li></ul><ul><li>LEFT JOIN FETCH d.employees”); </li></ul><ul><ul><li>Using FETCH JOIN </li></ul></ul><ul><ul><ul><li>Puts you in charge </li></ul></ul></ul><ul><ul><ul><li>Needs careful consideration when to use </li></ul></ul></ul><ul><ul><li>No similar solution for non-relationship fields or properties (BLOB, CLOB) </li></ul></ul>The solution
    • 121. And detached entities… Navigating Relationships <ul><li>Accessing a LAZY relationship from a detached entity : </li></ul><ul><ul><li>Can get an exception </li></ul></ul><ul><ul><li>Can get null </li></ul></ul><ul><ul><li>Can get a previously cached value—another problem </li></ul></ul><ul><li>Is there a portable solution? </li></ul><ul><ul><li>Use JOIN FETCH for queries or fetch type EAGER </li></ul></ul><ul><ul><li>Access the collection before the entity is detached </li></ul></ul><ul><li>d.getEmployees().size(); </li></ul><ul><ul><ul><li>Not flexible </li></ul></ul></ul><ul><ul><ul><li>Can return too many instances </li></ul></ul></ul>
    • 122. Parallel Updates to Same Object <ul><li>tx1.begin(); //Joe's employee id is 5 e1 = findPartTimeEmp(5); //Joe's current rate is $9 e1.raiseByTwoDollar(); tx1.commit(); //Joe's rate will be $11 </li></ul><ul><li>tx2.begin(); //Joe's employee id is 5 e1 = findPartTimeEmp(5); ... </li></ul><ul><li>... </li></ul><ul><li>//Joe's current rate is $9 if(e1.getRate() < 10) e1.raiseByFiveDollar(); ... tx2.commit(); //Joe's rate will be $14 </li></ul>No parallel updates expected or detected
    • 123. How to Guard Against Parallel Updates? <ul><li>Use Optimistic concurrency </li></ul><ul><ul><li>Introduce Version attribute to Employee public class Employee { @ID int id; ... @Version int version; ... } </li></ul></ul><ul><li>Results in following SQL “ UPDATE Employee SET ..., version = version + 1 WHERE id = ? AND version = readVersion ” </li></ul><ul><li>OptimisticLockException if mismatch </li></ul>
    • 124. Parallel Updates to Same Object <ul><li>tx1.begin(); //Joe's employee id is 5 //e1.version == 1 e1 = findPartTimeEmp(5); e1.raiseByTwoDollar(); tx1.commit(); //e1.version == 2 in db </li></ul><ul><li>tx2.begin(); //Joe's employee id is 5 //e1.version == 1 e1 = findPartTimeEmp(5); ... </li></ul><ul><li>... </li></ul><ul><li>//Joe's current rate is $9 if(e1.getRate() < 10) e1.raiseByFiveDollar(); ... //e1.version == 1 in db? tx2.commit(); //Joe's rate will be $14 //OptimisticLockException </li></ul><ul><ul><li>@Version attribute enables detection of parallel updates </li></ul></ul>
    • 125. Using Stale Data for Computation <ul><li>tx1.begin(); d1 = findDepartment(dId); //d1's original name is //”Engrg” d1.setName(“MarketEngrg”); tx1.commit(); </li></ul><ul><li>tx2.begin(); e1 = findEmp(eId); d1 = e1.getDepartment(); em.lock(d1, READ); if(d1's name is “Engrg”) e1.raiseByTenPercent(); //Check d1.version in db tx2.commit(); //e1 gets the raise he does //not deserve //Transaction rolls back </li></ul><ul><ul><li>Read lock ensures non-stable data at commit </li></ul></ul>
    • 126. <ul><ul><li>Write lock prevents parallel updates </li></ul></ul>Using Stale Data for Computation <ul><li>tx1.begin(); e1 = findDepartment(dId); //d1's original name is //”Engrg” d1.setName(“MarketEngrg”); tx1.commit(); //tx rolls back </li></ul><ul><li>tx2.begin(); e1 = findEmp(eId); d1 = e1.getDepartment(); em.lock(d1, WRITE); em.flush(); //version++ for d1 if(d1's name is “Engrg”) e1.raiseByTenPercent(); tx2.commit(); </li></ul>
    • 127. Optimistic versus Pessimistic Concurrency <ul><li>Pessimistic Concurrency </li></ul><ul><ul><li>Lock the row when data is read in </li></ul></ul><ul><ul><ul><li>Issue “SELECT ... FOR UPDATE” SQL to read data </li></ul></ul></ul><ul><ul><ul><li>Use different connection isolation level </li></ul></ul></ul><ul><ul><li>Pros—Simpler application code </li></ul></ul><ul><ul><li>Cons—Database locks </li></ul></ul><ul><ul><ul><li>No portable support in this version of spec </li></ul></ul></ul><ul><ul><li>Suitable when application has many parallel updates </li></ul></ul><ul><li>Optimistic Concurrency </li></ul><ul><ul><li>Pros—No database locks held </li></ul></ul><ul><ul><li>Cons—Requires a version attribute in schema Databases are not optimized for rollback Retries complicate application logic </li></ul></ul><ul><ul><li>Suitable when application has few parallel updates </li></ul></ul>
    • 128. Cascade Type <ul><li>Specifies operations cascaded to associated entities </li></ul><ul><li>Used for relationships </li></ul><ul><ul><li>ALL, PERSIST, MERGE, REMOVE, REFRESH </li></ul></ul><ul><ul><li>Default is none </li></ul></ul><ul><li>If possible avoid MERGE in relationships with deep hierarchies </li></ul><ul><ul><li>Do it manually </li></ul></ul><ul><ul><li>Limit the scope of MERGE </li></ul></ul>@Entity public class Order { @OneToMany( cascade=PERSIST , fetch=LAZY ) Collection<LineItems> lineItems;
    • 129. Entity merge Don't @Entity public class Order { @OneToMany(cascade=CascadeType.ALL, ...) public Collection<OrderLineItem> getLineItems(){ return lineItems; } } @Stateless public class OrderSessionStateless { @PersistenceContext private EntityManager em; public void applyDiscount( Collection<OrderLineItem> lis){ applyDiscount(lis); em.merge(order); } }
    • 130. Entity merge DO @Entity public class Order { @OneToMany(cascade=CascadeType.ALL, ...) public Collection<OrderLineItem> getLineItems(){ return lineItems; } } @Stateless public class OrderSessionStateless { @PersistenceContext private EntityManager em; public void applyDiscount( Collection<OrderLineItem> lis){ for(OrderLineItem li : lis) { applyDiscount(li); em.merge(li); } } }
    • 131. EJB 3.0 Persistence Summary <ul><li>All new Entities </li></ul><ul><ul><li>Simplifies persistence model </li></ul></ul><ul><ul><li>Supports Light-weight persistence model </li></ul></ul><ul><ul><li>Support both J2SE and J2EE environments </li></ul></ul><ul><ul><li>Extensive querying capabilities </li></ul></ul>
    • 132. Enterprise JavaBean 3.0 and Java Persistence APIs: Simplifying Persistence Carol McDonald [email_address] Sun Microsystems

    ×