Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
JEE – Java Enterprise Edition EJB – Enterprise Java Beans Credits to: Piero Fraternali, Alessandro Bozzon Politecnico di Milano Enterprise Java Beans Distributed components (at server side) that incapsulate a specific functionality Coded as Java classes Executed within an ad hoc container (called EJB container) Their code is enriched with annotations to let the container manage them Their execution follows a particular life cycle, managed by the container Positioning in the Web architecture EJB live here Role of the EJB in the Web architectures SQL request d i gi t a l HTTP request database SQL response Page templates Business logic In Web applications, the middle tier is the most complex software component Includes several functionalities Receives requests and send responses back Creates the user interface Implements the business logic and the interactions towards the data level Evolution of the standard EJB EJB EJB EJB EJB 1.0 1.1 2.0 2.1 3.0 (1998) (1999) (2001) (2003) (JSR 220 – MAJOR Release) http://java.sun.com/products/ejb/docs.html http://www.jcp.org/en/jsr/detail?id=220 EJB 3.1 (JSR 318), final release (2009-12-10) Oriented to simplification Evolution revisited Every major release is a substantial change of the standard EJB1: early release, little used EJB2: stable release, better performance but complex to program EJB3: drastic simplification, hopefully the last major change Prerequisite: Java 5 metadata JSR 175: A Metadata Facility for the JavaTM Programming Language (Final Release Sept. 2004) Provides the ability to associate additional data (aka metadata, “data about data”) alongside Java classes, interfaces, methods, and fields Annotations can be read by tools and stored in the class file and can be discovered at runtime using Java reflection A tool could use metadata to generate additional source code, or to provide additional information when debugging With metadata processing, repetitive coding steps can be reduced to a concise metadata tag Metadata: example of code checking @override built-in annotation express the intention of overriding a method of a super-class java.lang.Object A compile time tool may trap typos: public class OverrideTester { public OverrideTester() { } @Override public String toString(){ return super.toString() + " [Override Tester Implementation]"; } @Override public int hasCode() { Identifiable as return toString().hashCode(); } } a bug by javac Metadata: example of code augmentation WITHOUT METADATA public interface PingIF extends Remote { public void ping() throws RemoteException; } public class Ping implements PingIF { public void ping() { } } WITH METADATA public class Ping { public @remote void ping() { } } Metadata express concisely the machinery required for accessing a JAX-RPC service implementation Metadata: syntax Marker annotations have no variables. @MarkerAnnotation Single-value annotations provide a single piece of data @SingleValueAnnotation("my data") Full annotations have multiple data members @FullAnnotation(var1="data value 1", var2="data value 2", var3="data value 3"). Metadata: array as value of an annotation variable @TODOItems({ // Curly braces denotes an array of values @TODO( severity=TODO.CRITICAL, item=“Calculate mean function", assignedTo=“Jane Doe" ), @TODO( severity=TODO.IMPORTANT, item="Print function", assignedTo=“John Foo" ) }) Metadata and EJB Annotations are the main syntactic device for expressing the behavior of an EJB and for resolving the dependencies among the various components of the architecture Prerequisites: dependency injection Goal: making the code (especially components) more reusable Problem: components may exhibit dependencies that tie them to a specific usage context, e.g., Dependencies on other components Dependency on the execution platform Dependency on external resources Solution: dependency injection Dependency injection Idea: replacing dependencies to services (e.g., pointers to objects, code for allocating resources..) with service references Service references can be resolved at component initialization time The source code of the component need not be changed if the usage context varies HOWEVER: an external mechanism (the execution context) must known the physical dependency and INJECT it into the component (inversion of control pattern) Dependency Injection in Java 5 and JEE Service references are encoded as Java 5 annotations The external mechanism for injection is the component container Only components managed by a container can exploit dependency injection Example: resource injection The @Resource annotation @Resource javax.sql.DataSource catalogDS; public getProductsByCategory() { // get a connection and execute the query Connection conn = catalogDS.getConnection(); .. } The container injects the data source prior to the component being made available to the application The data source JNDI mapping is inferred from the field name catalogDS and the type, javax.sql.DataSource @Resource annotation @Resource has the following elements: name: The JNDI name of the resource type: The Java language type of the resource authenticationType: The authentication type to use for the resource shareable: Indicates whether the resource can be shared mappedName: A non-portable, implementationspecific name to which the resource should be mapped description: The description of the resource Syntax of injection Field-based public class SomeClass { @Resource private javax.sql.DataSource myDB; ... } Class-Based @Resource(name= "myMessageQueue", type="javax.jms.ConnectionFac tory") public class SomeMessageBean { ... } Method-Based public class SomeClass { private javax.sql.DataSource myDB; ... @Resource private void setMyDB(javax.sql.DataSour ce ds) { myDB = ds; } ... } Dependency Injection and EJB EJB make heavy use of dependency injection, for Resolving reference to components Accessing external resources (e.g., db connections, message queues) Prerequisites: naming and directories IN GENERAL Naming service: the mechanism by which names are associated with objects and objects are found based on their name Naming system (naming convention): the syntax that names must follow Binding: the association of a name with an object Reference: a pointer to an object placed inside the naming service IN JEE Context: a set of name-to-object bindings, under a given naming convention Naming system: a connected set of contexts with the same naming convention and common operations Naming service: interface of a naming system to clients Namespace: the set of names in a naming system Directory A directory service associates names with objects and also allows such objects to have attributes An attribute has an attribute identifier and a set of attribute values. A directory is a set of directory objects. A directory service is a service that provides operations for creating, adding, removing, and modifying the attributes associated with objects in a directory. Content-based searching (reverse lookup): directory object search based on attributes Naming and directory services Directories often arrange their objects in a hierarchy. For example, the LDAP arranges all directory objects in a tree, called a directory information tree (DIT). Within the DIT, an organization object, for example, might contain group objects that might in turn contain person objects. When directory objects are arranged in this way, they play the role of naming contexts in addition to that of containers of attributes (similar to folders in a file system) JNDI Java Naming and Directory Interface: API that provides naming and directory functionality to applications written in Java Consists of an API and a service provider interface (SPI) JNDI packages The JNDI is divided into five packages: javax.naming: for accessing naming services. The most common operation is lookup() javax.naming.directory: extends the javax.naming package for accessing directory services to retrieve attributes associated with objects and to search for objects using attributes javax.naming.event: event notification javax.naming.ldap: for using features that are specific to the LDAP javax.naming.spi: for developers of different naming/directory service providers EJB & JavaEE architecture Client side Presentation Server side Presentation Server side Business logic Enterprise Information System BROWSER Web Server APP Server HTML Java Servlet EJB Java Applet JSP EJB Legacy systems Other J2EE services (Java Mail, ecc) Other J2EE services (Java Mail, ecc) ERP Web tier EJB tier Desktop Java Application Other Device Java Client database EJB: basic concepts 1. EJB applications are loosely coupled 2. EJBs behavior is specified by annotated Plain Old Java Objects (POJO) and Interfaces (POJI) EJB instances are isolated and executed within a container The container simulates a single-thread execution environment Instances can be managed as pools, to increase efficiency The container, not the EJBs, handles: 3. 4. 5. 6. 1. Transactions, security, resources 7. Creation and access to EJB instances are standard 8. Application deployment is standardized 1. Loose coupling Applications are developed assembling components References between components are represented by symbolic names (not by pointers), handled in the same way as yellow pages (directory) EJB development do not depend on execution environment (application server) 2. Programming style An EJB is exposed to its clients as a Plain Old Java Interface (POJI), called “business interface” (optional in EJB 3.1) It is internally programmed as a Plain Old Java Object (POJO) The use of interfaces hides the implementation. Clients are unaware of implementation changes 3. Isolation of instances A client call is received and processed by the container BEFORE the same is redirected to the proper object There are special objects (proxy objects) created and handled by the container The container hides “true” objects and handles security issues 4. Concurrency The developer is not concerned with concurrency control The source code is written as if the execution environment is single-threaded There are a few constraints that must be met by the EJB source code to guarantee proper concurrency control 5. Object pooling The EJB container decides how many instances of an EJB are needed at a given time When the client asks the container to create a new object, the container can decide to recycle an object already instanced, available in the pool The client is unaware of this different behavior Remark: dually, object de-allocation is not as usual, since at the end of the execution objects can be returned to the pool, instead of being destroyed 6. Transactions The container supports the execution of transactions Local Distributed The way transactions are managed is specified in a declarative manner externally to the component. It can be changed without interfering with the source code of the components 6. Security The container supervises access control: Which methods are accessible and to which roles Access policy can be described: In a declarative style, externally to the component In a programming style, directly in the component’s code EJBs shall not contain code for user authentication 6. Resources EJBs never access to external resources directly (databases, legacy systems, message queues). Access is supervised and optimized by the container Resources are shared among different EJBs The developer is not concerned with resource allocation and release Resources management policies are described in a declarative style in configuration files The container is configured be the administrator, not by the developer 7. Creation and retrieval Object creation and retrieval are standardized: To access objects the client uses a yellow pages service (Java Naming and Directory Interface- JNDI) plus linguistic shorthand mechanisms, like Annotation Dependency injection Simplified Lookup The client invokes methods of the EJB component, without knowing the real instance (e.g., its physical address / pointer to it) of the EJB that execute its calls 8. Deployment EJB specifications standardize EJB application packaging Deployment descriptor See exercise/seminar sessions Usage modes Web components WS client EJB 4 3 Browser 1 Componenti Web DATA TIER EJB Standalone Application 2 1. 2. 3. 4. Web component (servlet/JSP) invokes EJB Standalone application invokes EJB EJB invokes another EJB (on same or different machine) Application invokes EJB as a Web Service endpoint EJB types The concept of EJB can be specialized in different “types”, which accomplish different tasks Session Bean: executes business methods on behalf of a single client Message Bean: executes upon receipt of a single client message, asynchronously (not treated in this lesson). Entity: represents persistent data (part of the Java Persistence API, formerly known as Entity EJB) Singleton Beans: session beans with a cache shared among different components (not treated in this lesson) EJB contracts EJB container client view contract client EJB container contract EJB interact with the clients and the container The dialog is managed by a set of interfaces, called contracts Container contract: towards the container Client View contract: towards the client Container Contract The container performs the following services for an EJB Implements the interfaces of the client view to manage the dialogue with the clients Rules the instances life cycle Manages exception handling, security, transactions Implements the callback system (for message beans) Client View Contract A Session bean exposes to the client a business interface Such interface is implemented by the bean class, which is written by the developer and extended and instantiated by the container Business interfaces can be local or remote (later on this) Naming convention Let us assume that we want to build an EJB that realizes a catalog (Catalog) Here is how the interface and the class need to be named: Enterprise Bean Name CatalogBean Business Interface Catalog Bean Class CatalogBean Session beans They are the simplest kind of EJB They are the ones normally used by the client Their life is as much as the one of the client (or shorter) The container might place them in the pool to reuse them, without the client being aware Two types: stateless & stateful The container is able to distinguish the subtype thanks to the annotation Stateless session beans Define a group of related methods and state variables (instance variables) With respect to the client: DO NOT preserve memory of the dialogue with the client from a call to the next one They can store information in data members, but not for a specific client With respect to the container: All instances are equivalent The container can use the same instance for calls of different clients, or different instances for calls of the same client Example: currency converter A stateless session bean to perform the conversion from the one currency into another one Business methods public BigDecimal dollarToYen(BigDecimal dollars); public BigDecimal yenToEuro(BigDecimal yen); Session bean: interface package com.sun.tutorial.javaee.ejb; import java.math.BigDecimal; import javax.ejb.Remote; @Remote //we will see this later public interface Converter { public BigDecimal dollarToYen(BigDecimal dollars); public BigDecimal yenToEuro(BigDecimal yen); } Session bean: bean class package com.sun.tutorial.javaee.ejb; import java.math.BigDecimal; import javax.ejb.*; @Stateless public class ConverterBean implements Converter { private BigDecimal yenRate = new BigDecimal("115.3100"); private BigDecimal euroRate = new BigDecimal("0.0071"); public BigDecimal dollarToYen(BigDecimal dollars) { BigDecimal result = dollars.multiply(yenRate); return result.setScale(2, BigDecimal.ROUND_UP); } public BigDecimal yenToEuro(BigDecimal yen) { BigDecimal result = yen.multiply(euroRate); return result.setScale(2, BigDecimal.ROUND_UP); } } Client code using injection @EJB private Converter currencyConverter; BigDecimal param = new BigDecimal ("100.00"); BigDecimal amount = currencyConverter.dollarToYen(param); The @EJB annotation is used to inject EJB references The container looks up the JNDI directory using as default name the fully qualified class name + object name It is also possible to use a specific name in @EJB: @EJB(name="ejb/stateless") Client code using lookup <%@ page import="converter.ejb.Converter, java.math.*, javax.naming.*"%> <%! private Converter converter = null; public void jspInit() {//Explicit Lookup with EJBContext API try { InitialContext ic = new InitialContext(); converter = (Converter) ic.lookup(Converter.class.getName()); } catch (Exception ex) { System.out.println("Couldn’t create converter bean."+ ex.getMessage()); } } public void jspDestroy() { converter = null; } %> Complete code 2/3 <html> <head> <title>Converter</title> </head> <body bgcolor="white"> <h1>Converter</h1><hr> <p>Enter an amount to convert:</p> <form method="get"> <input type="text" name="amount" size="25"><br> <input type="submit" value="Submit"> <input type="reset" value="Reset"> </form> Complete code 3/3 <% String amount = request.getParameter("amount"); if ( amount != null && amount.length() > 0 ) { BigDecimal d = new BigDecimal(amount); BigDecimal yenAmount = converter.dollarToYen(d); %> <p> <%= amount %> dollars are <%= yenAmount %> Yen. <p> <% BigDecimal euroAmount = converter.yenToEuro(yenAmount); %> <%= amount %> Yen are <%= euroAmount %> Euro. <% } %> </body> </html> Stateless session bean: lifecycle The client initiates the life cycle by obtaining a reference to a stateless session bean The container performs any dependency injection and Then invokes the method annotated @PostConstruct, if any. The bean is now ready to have its business methods invoked by the client. At the end of the life cycle, the EJB container calls the method annotated @PreDestroy, if any. The bean's instance is then ready for garbage collection. Life-Cycle Callback Methods Methods in the bean class may be declared as a life-cycle callback method by annotating them with: javax.annotation.PostConstruct javax.annotation.PreDestroy Life-cycle callback methods must return void and have no parameters Stateless session bean: assessment Applications: Business logic independent from the client (e.g.: currency convertion) Advantages: Load balancing made easier: all instances are equivalent Failover made easier: session state do not need to be restored With a few instances it is possible to serve several clients, exploiting the client ”idle time” ( scalability and efficiency) Disadvantages If session information must be preserved, the client must save it locally, thus complicating the source code Stateful session bean Assigned to a specific client Able to maintain information between different client calls Remark: they look like the session object in the Web tier, but they operate at the business tier, therefore also for non-Web applications Stateful session bean: lifecycle Life-Cycle Callback Methods Methods in the bean class may be declared as a life-cycle callback method by annotating them with: javax.annotation.PostConstruct javax.annotation.PreDestroy javax.ejb.PostActivate javax.ejb.PrePassivate Life-cycle callback methods must return void and have no parameters Passivation The 1:1 ratio client<–>instance makes instance management and reuse more complicated The number of instances can be high, since it depends on the number of clients, moreover the client is not always active: Think time, network disconnection, browser closing... The server can store a limited number of objects in memory To improve scalability, the container uses the “passivation” technique, e.g. after a timeout Passivate: serialize the object from main memory to mass memory to free memory space for other objects Activate: de-serialize from mass memory to main memory, e.g. to execute a method call Lifecycle 1. The client initiates the life cycle by obtaining a reference to a stateful session bean. 2. The container performs any dependency injection and then invokes the method annotated with @PostConstruct, if any. 3. The bean is now ready to have its business methods invoked by the client. Lifecycle 4. 5. 6. 7. While in the ready stage, the EJB container may decide to deactivate, or passivate, the bean by moving it from memory to secondary storage. The EJB container invokes the method annotated @PrePassivate, if any, immediately before passivating it. If a client invokes a business method on the bean while it is in the passive stage, the EJB container activates the bean, calls the method annotated @PostActivate, if any, and then moves it to the ready stage. At the end of the life cycle, the client invokes a method annotated @Remove, and the EJB container calls the method annotated @PreDestroy, if any. The bean's instance is then ready for garbage collection. Programmer’s code controls the invocation of only one lifecycle method: the method annotated @Remove. All other methods are invoked by the EJB container. Example: cart interface package com.sun.tutorial.javaee.ejb; import java.util.List; import javax.ejb.Remote; @Remote public interface Cart { public void initialize(String person) throws BookException; public void initialize(String person, String id) throws BookException; public void addBook(String title); public void removeBook(String title) throws BookException; public List<String> getContents(); public void remove(); } Bean class 1/3 import import import import java.util.ArrayList; java.util.List; javax.ejb.Remove; javax.ejb.Stateful; @Stateful public class CartBean implements Cart { String customerName; String customerId; STATEFUL CONTENT List<String> contents; public void initialize(String person) throws BookException { if (person == null) { throw new BookException("Null person not allowed."); } else { customerName = person; } customerId = "0"; contents = new ArrayList<String>(); } Bean class /continues.. public void initialize(String person, String id) throws BookException { if (person == null) { throw new BookException("Null person not allowed."); } else { customerName = person; } IdVerifier idChecker = new IdVerifier(); if (idChecker.validate(id)) { customerId = id; } else { throw new BookException("Invalid id: " + id); } contents = new ArrayList<String>(); } Bean class /continues.. public void addBook(String title) { contents.add(title); } public void removeBook(String title) throws BookException { boolean result = contents.remove(title); if (result == false) { throw new BookException(title + " not in cart."); } } public List<String> getContents() { return contents; } @Remove public void remove() { contents = null; } } Client code @EJB Cart cart; ... cart.initialize("Duke DeEarl", "123"); ... cart.addBook("Bel Canto"); ... List<String> bookList = cart.getContents(); ... cart.removeBook("Gravity’s Rainbow"); ... cart.remove(); Local vs remote usage At the beginning of the standardization effort (EJB 1.0), all objects were communicating with each other remotely, by using network protocols (RMI over IIOP) In the remote model, objects are located on different machines and/or in different virtual machines Each remote interaction requires a series of costly steps in terms of efficiency In EJB 1.0, also the objects in the same VM are forced to communicate with each other using RMI performance bottleneck EJB 2.0 introduces the concept of local interface to optimize the dialogue in the same VM EJB 3.0 supports local and remote usage, too Distributed objects The use of distributed objects implies invoking methods of an object active in a different machine. This fact requires: To send the method signature from the server to the client To export (marshall) input parameters from the client to the server, and to import (unmarshall) them from the server To export (marshall) return values from the server to the client, and to import (unmarshall) them from the client Use of service interfaces (stub & skeleton) caller Remote object Remote interface stub skeleton Distributed objects with RMI over IIOP Remote Method Invocation over Internet Inter Orb Protocol (Corba 2) Client Server caller stub servant ORB interface ORB interface skeleton adaptor Object Request Broker (ORB) Object Request Broker (ORB) IIOP IIOP Distributed EJB with RMI over IIOP Server Client stub stub initialize, remove business method Container EJB proxy EJB proxy skeleton EJB Local interfaces To alleviate the problem of lack of performance in case of communication between EJBs on the same machine, EJB 2.0 introduces the concept of local interface (distinct from the remote interface) The local interface can be invoked without resorting to RMI EJB 3.0 keeps both local and remote interfaces, but uses annotations to mark the distinction Remote clients A remote client: can run on a different machine and a different Java virtual machine can be a web component, an application client, or another enterprise bean sees the location of the enterprise bean as transparent. To create an enterprise bean that allows remote access, one must: Decorate the business interface of the enterprise bean with the @Remote annotation: @Remote public interface InterfaceName { ... } OR: Decorate the bean class with @Remote, specifying the business interface or interfaces: @Remote(InterfaceName.class) public class BeanName implements InterfaceName { ... } Local Clients A local client : must run in the same JVM as the enterprise bean can be a web component or another enterprise bean the location of the enterprise bean is not transparent By default, access is local Deciding on Remote or Local Access Relevant factors include: Tight or loose coupling of related beans: Tightly coupled beans depend on one another and are good candidates for local access, because they typically call each other often Type of client: If an enterprise bean is accessed by application clients, then it should allow remote access. If an enterprise bean's clients are web components or other enterprise beans, then the type of access depends on component distribution. Component distribution: distributing components across multiple machines improves scalability. In a distributed scenario, the enterprise beans should allow remote access. Performance: Due to factors such as network latency, remote calls may be slower than local calls. On the other hand, distributed components among different servers may improve the overall performance. References (mandatory) JSR175 (Metadata Facility): http://www.ibm.com/developerworks/java/ library/j-annotate1/index.html http://www.ibm.com/developerworks/librar y/j-annotate2.html EJB 3.0: http://www.javaworld.com/javaworld/j w-08-2004/jw-0809-ejb_p.html Other references (optional) http://en.wikipedia.org/wiki/ Dependency_injection The Java Persistence API The latest persistence technology in the Java domain Adds up to other previous proposals JDO: Java data Objects (JDO 2.0: JSR 243) JDBC: Java database connectivity (JDBC 3.0 API) Available in JEE but also in JSE Usable with / without a container JPA components An API, defined in the javax.persistence package The Java Persistence Query Language The object/relational metadata (mapping) JPA main concepts Entity: a class (JavaBean) representing a set of persistent objects mapped onto a relational table Persistence Unit: the set of all classes that are persistently mapped to one database (analogous to the notion of db schema) Persistence Context: the set of all objects of the entities defined in the persistence unit (analogous to the notion of db instance) Entity manager: the interface for interacting with a Persistence Context Entity A Java Bean (POJO Plain Old Java Object) that represents a table in a database The class represents the table The objects represent the tuples May have a life longer than that of the application Needs to be associated with the database table it represents (mapping) Inherits much of the properties & concepts of an object-relational database table Entity Properties BeanClass Obj/Rel Table Identification (primary key) Nesting Relationship Inheritance Referential integrity (foreign key) Syntax POJO public class Book { private String isbn; private String title; private int pages; } ENTITY @Entity public class Book { private String isbn; private String title; private int pages; } Entity constraints The entity class must have a no-arg constructor (public or protected) The persistent state of an entity is represented by instance variables (private, protected, or with package visibility). The state of the entity is available to clients only through the entity’s accessor methods The entity class must not be final. No methods or persistent instance variables of the entity class may be final If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface. Entity Identification In database, objects and tuples have an identity (primary key) an entity bean assumes the identity of the persistent data it is associated to Simple Primary key = persistent field of the bean used to represent its identity Composite Primary key = set of persistent fields used to represent its identity Remark: with respect to the session bean, the PK is a new concept. Session beans do not have a durable identity Entity identification syntax @Entity public class Book { @Id private String isbn; private String title; private int pages; } @Id tags a field as the simple primary key Composite primary keys are denoted using the @EmbeddedId and @IdClass annotations Mapping annotations @Entity @Table(name=”T_BOOKS”) public class Book { @Column(name=”BOOK_TITLE”, nullable=false) private String title; @Enumerated(EnumType.STRING) private CoverType coverType; @Temporal(TemporalType.DATE) private Date publicationDate; @Transient private BigDecimal discount; } Field Properties All fields of an entity are persistent, unless otherwise specified with the @transient annotation Persistent fields can be mapped by annotations onto the relational schema of the underlying database Alternatively all mapping information can be provided in one configuration file (XML descriptor) The XML descriptor is both an alternative to and an overriding mechanism for annotations (the descriptor overrides the annotations in the bean code) Property-style annotation If the entity uses persistent properties, the entity must follow the method conventions of JavaBeans components Type getProperty() void setProperty(Type type) Set<Type> getMultiValueProperty () {} void setMultiValueProperty(Set<Type>) {} Annotations can be placed on the getter method Nesting An entity may contain a nested sub-entity (embedded in the JPA terminology) @Entity public class Editor { @Embedded private EditorDetails details; } @Embeddable public class EditorDetails { ... } Relationships Entities may be associated by relationships Relationships have several properties Cardinality: 1:1, 1:N, N:1, M:N Navigability: from which side it is possible to navigate to the other side Referential Integrity: what happens when a participant is deleted or persisted N:1 (unidirectional) The owner side of the relationship contains the field mapped on the db foreign key In this case it contains the @ManyToOne annotation The editor field is a navigable reference to the associated object A mapping to the foreign key database column can be declared (@JoinColumn) @Entity public class Book { @ManyToOne @JoinColumn(name=”ID_EDITOR”) private Editor editor; } @Entity public class Editor { } 1:N (bidirectional) The relationship can be declared in both entities The non-owning side may declare the inverse relationship (mappedBy) The field supporting the N side must be multi-valued (e.g., set) The field supporting the N side can be ordered (@OrderBy) @Entity public class Book { @ManyToOne private Editor editor; } @Entity public class Editor { @OneToMany(mappedBy= ”editor”) @OrderBy(“isbn asc”) private Set<Book> books; } N:M (bidirectional) At both sides, the relationship field is multivalued The following collection interfaces may be used: java.util.Collection java.util.Set java.util.List java.util.Map @Entity public class Book { @ManyToMany private Set<Author> authors; } @Entity public class Author { @ManyToMany (mappedBy=”authors”) private Set<Book> books; } One to one Can be made bidirectional by declaring the inverse relationship with annotation mappedBy in the non-owning side (Address in this case) Owner side @Entity public class Editor { @OneToOne private Address address; } @Entity public class Address { } Referential integrity Entities that use relationships often have dependencies on the existence of the other entity in the relationship. For example, a line item is part of an order, and if the order is deleted, then the line item should also be deleted. This is called a cascade delete Cascade delete relationships are specified using the cascade=REMOVE attribute for @OneToOne and @OneToMany relationships @OneToMany(cascadeType=REMOVE, mappedBy="customer") public Set<Order> getOrders() { return orders; } Cascading persistence Relationships can be used also to automate the storage of objects to the database If an application persists an object X, also related objects Y1..Yn could be automatically persisted E.g.: create an order, create N line items, persist the order line items are also persisted This is expressed in the relationship with cascadeType= PERSIST or cascade= ALL Inheritance Inheritance can be used also for persistent objects, for factoring out data members inherited by multiple subclasses Hierarchies of entities can be defined The mapping of a hierarchy to the database can follow different strategies: Single table per hierarchy Table per class Joined Hierarchies can mix persistent entities and transient Java classes and involve abstract (i.e., non instantiable) entity classes Hierarchy: syntax @MappedSuperclass abstract class Publication { @Id private Long id; @ManyToOne private Editor editor; } @Entity public class Book extends Publication { @Temporal(TemporalType.DATE) private Date publDate; } @Entity public class Comic extends Publication { @Enumerated(EnumType.STRING) private IssuePeriod issuePeriod; } Mapped superclasses are a syntactic facility to share persistent fields and mapping information, they do not have entities Alternatively, the superclass can also be an entity or a transient Java class Single Table per Hierarchy A discriminator column must be used to distinguish the type of the object @Inheritance(strategy=SINGLE_TABLE) @DiscriminatorColumn(name=”Discr”) @MappedSuperclass abstract class Publication { . } @DiscriminatorValue(“B”) @Entity class Book extends Publication { . } @DiscriminatorValue(“C”) @Entity class Comic extends Publication { . } Joined One table per class (including superclasses) Objects reconstructed by join @Inheritance(strategy=JOINED) @MappedSuperclass abstract class Publication { . } @Entity class Book extends Publication { . } @Entity class Comic extends Publication { . } Table per Class One table per concrete class Inherited attributes cached in subclasses Population reconstructed by UNION @Inheritance(strategy=TABLE_PER_CLASS) @MappedSuperclass abstract class Publication { . } @Entity class Book extends Publication { . } @Entity class Comic extends Publication { . } How to work with entities Entities are accessed through suitable interfaces of JPA Interacts with Client Is associated with Persistence Context Entity manager handles Persistence Unit Instance of classes belonging to Persistent obj. Persistent obj. Persistent obj. Typical project structure in JEE Web tier Session Beans Entity Beans Managed and detached entities Modifications to entities must be reflected to changes to the database tuples For this to occur automatically, an entity must be in the managed stage When an entity in not in the managed state, it is detached Modifications to detached entities are not automatically reflected to the database Detached entities can be merged back to the managed state Entity lifecycle states NEW: No persistent identity MANAGED: Associated with persistence context, changes to objects automatically synch to db (NOT VICE VERSA) DETACHED: Has persistent identity but changes are NOT automatically propagated to db REMOVED: Scheduled for removal from the db DELETED: erased from db New version with callback Typical workflow with entities The client normally proceeds as follows: { \\ locate an EntityManager instance \\ find or create entity instances \\ manipulate entities and relationships \\ persist changes } transaction policy depends on the Entity Manager Locating an EntityManager From within an EJB session bean, using dependency injection @Stateless public class SessionEJB { @PersistenceUnit private EntityManagerFactory factory; @PersistenceContext private EntityManager manager; } Locating EntityManager in JSE Dependency injection not available (there is no container) Explicit creation via factory pattern EntityManagerFactory emf = Persistence.createEntityManagerFactory( "unit"); EntityManager em = emf.createEntityManager(); // ... em.close(); Finding or creating instances @Stateless public class SessionEJB { @PersistenceContext private EntityManager entityManager; public void createBook(String isbn, Long editorId, ...) { Editor editor = entityManager.find(Editor.class, editorId); Book b = new Book(isbn, editor, ...); entityManager.persist(b); } } Persisting changes entityManager.persist(b); The new book enters the persistence context and becomes managed A tuple is created automatically in the database (when this actually occurs depends on transaction management) Finding Objects by Querying Java Persistence Query Language: a language for querying, deleting and updating entities Inspired to SQL Independent of database implementation and portable Statements QL_statement ::= select_clause from_clause [where_clause] [groupby_clause] [having_clause] [orderby_clause] update_statement :: = update_clause [where_clause] delete_statement :: = delete_clause [where_clause] Select Similar to SQL Allows relationship navigation via path expressions Allows operators on set-valued expressions Navigation SELECT DISTINCT p FROM Player p, IN (p.teams) t WHERE t.league = :league The query navigates over two relationships. p.teams navigates the Player-Team relationship, t.league navigates the TeamLeague relationship SELECT DISTINCT p FROM Player p WHERE p.teams IS EMPTY P.teams designates a collection-valued relationship field Operators on set-valued expressions from Book b where b.authors.size = ? from Book b where (select count(ba.book_id) from Book_Author ba Where b.id = ba.book_id) =? Submitting queries to the EM @Stateless public class SessionEJB { @PersistenceContext private EntityManager entityManager; public List<Book> findBooksWithAuthors(int n) { String jpql = “from Book b where b.authors.size = :count”; Query q = entityManager.createQuery(jpql); query.setParameter(“count”, n); return query.getResultList(); } } Types of Entity Managers Container-Managed: the container automatically propagates the persistence context (db instance) to all components that use the EntityManager instance within a single JTA transaction Components don’t need to pass references to EntityManager instances to each other in order to make changes within a single transaction EM must be injected into the application, not explicitly created Types of Entity Manager Application-Managed: persistence context is not automatically propagated The EntityManager and its associated persistence context are created and destroyed explicitly by the application Each EntityManager creates a new, isolated persistence context Transactions The typical transaction begin transaction debit checking account credit savings account update history log commit transaction The problem is: who demarcates the transaction start & end ? Transaction management Two options: container-managed transaction demarcation: the EJB container sets the boundaries; the code in the session or message-driven bean does not include statements that begin and end the transaction; rollback via system exception or method of EJBContext interface. bean-managed transaction demarcation: the code in the session or message-driven bean explicitly marks the boundaries of the transaction Container-Managed Transactions Default if no demarcation is specified Declarative specification of transaction scope, i.e. how transactionality propagates across method calls Transaction attributes are specified via annotation @TransactionAttribute(…) in session/message beans Transaction attributes Bean Managed Transaction In CMT, a method can be associated with either a single transaction or no transaction Sometimes, finer control is needed BMT code can use either JDBC or JTA to manage transactions begin transaction ... update table-a ... if (condition-x) commit transaction else if (condition-y) update table-b commit transaction else rollback transaction begin transaction update table-c commit transaction Bibliography and references The Java EE Tutorial: Part V Persistence (mandatory) JPA annotation reference: http://www.oracle.com/technolog y/products/ias/toplink/jpa/resour ces/toplink-jpa-annotations.html