Why JPA? * JPA is standardized specification and part of EJB3 specification * Many free ORM frameworks are available with can be used to develop applications of any size * Application developed in JPA is portable across many servers and persistence products (ORM frameworks). * Can be used with both JEE and JSE applications * JSE 5 features such as annotations can be used * Both annotations and xml based configuration support
Entity Entity is the persistence (POJO) objects that represent one record in the table. The Entity is simple annotated POJO class, which is easy to develop. Here are the characteristics of an Entity: Entity can be persisted to the relational database. Entity is identified by persistence identity (the primary key of the table)
Persistence Context To be very precise, a persistent context manages a set of entities which in turn is managed by the EntityManager. A persistent context keeps track of the state (or the changes) that an entity object may undergo. And the EntityManager takes the support of this persistence context to commit or to undo the changes. As soon as an EntityManager object is created, it is implicitly associated with a persistence context formanaging a set of entities. Persistent Context comes in two flavors, one is the transaction-scoped persistent context and the other one is extended persistent context. Transaction-Scoped Persistence Context: Imagine that a set of entities are managed by the persistence context. At this time, we say that the entities are bound to (or attached) to the persistent context. Changes may happen to these entities and these changes will occur within a transaction. Sometimes later when the transaction ends (commits or roll-back), the entities will unbind (detached) from the persistent context. As soon as the entities are detached from the persistence context, they are no longer being managed. Any changes that happen to these entities will not be persisted as they don’t have any association with the persistence context. Such kind of persistent context whose life-time is dependent on the life-time of the transaction (for a set of entities at that particular point of time) is termed as transaction-scoped persistent context. All the transaction-scoped persistence context are configured by injecting @PersistentContext to EntityManager objects , like this, @PersistenceContext(name=”PersistentUnitName”) private EntityManager entityManager; [Note: There is no such public interface called PersitenceContext in the Java Persistence API. The EntityManager may implicitly depend on a virtual Persistence Context class formanaging the entities. So, creating a transaction-scoped persistence context is nothing but creating an EntityManager object that has been configured with @PersistenceContext annotation.] Extended Persistence Context: Unlike transaction-scoped persistence context, where the life-time of the persistence context will end as soon the transaction is completed, a persistence context may be configured to live even after a transaction completes. In such a case, all the entities that are managed by such a persistence context will still be in a manageable state only even after the transaction ends. They won’t be detached from the context. Such long-lived persistence context that will continue to exist even after the completion of a transaction is called extended persistence context. All the extended persistence context objects are created and managed manually by the application code only (that is by the developers). [As soon as an EntityManager object is created, an implicit Persistence context will be associated with it and it is soon kept open and prepared formanaging a set of entities, meaning that the calling EntityManager.isOpen() method will always return true. Calling the EntityManager.clear() method will clear the current persistence context associated with the EntityManager and all the entities that have their associations will now be cleared and they become detached from the EntityManager. To release all the resources referenced by the EntityManager, call the close() method, After this method call, calling any of the methods will throw IllegalStateException.]
EntityManager The EntityManager interface is providing the API for interacting with the Entity. Some of the functions provided by EntityManager API are: persist – this method is used to save a new entity merge – this method is used to update the sate of entity into database remove – this method is used to remove the entity instance EntityManagerFactory The EntityManagerFactory is used to create an instance of EntityManager. In your application when there is no use of EntityManagerFactory or application shuts down then it is necessary to close the instance of EntityManagerFactory . Once the EntityManagerFactory is closed, all its EntityManagers are also closed.
The Query API http://www.javabeat.net/articles/5-introduction-to-java-persistence-apijpa-6.html
@Entity / @Table Table defaults to the class name if not annotated We choose to explicitly specify the table for each mapped class @Id All Entities require a unique identifier @Basic is the default @Column needed only if column name != field name @Transient So any field that is unannotated in your class will be persisted (or at least attempted, Remember @Basic) For fields that don’t need persistenting – they must be marked with @Transient @Enumerated To use enum as field. e.g. @Enumerated(EnumType.STRING) @Column(name = &quot;PRSP_STATUS_EN&quot;) ProspectStatusEnum prospectStatusEnum; @Temporal The @Temporal is used to specify the type that a JPA extension must persist for entity fields of type java.util.Date and java.util.Calendar only e.g. @Temporal(TemporalType.DATE) @Column(name = &quot;PRSP_STATUS_DT&quot;) private Date prospectStatusDate;
Entities and Transactions All entities have the property of transactionability and their CRUD operations will take place within a transactional context. Transactions can be broadly classified into two types based on who actually owns (or manages) the transaction. They are JTA and Resource-local transaction. In the case of a J2EE Application, the default transaction type is JTA (Java Transaction API), unless explicitly specified. A method can be simply annotated with @RequiresNew (or @Requires) in which case a new transaction will always started by the container and the transaction completes as soon as themethod ends. Whereas in a J2SE application, the transaction-type defaults to Resource-local, which means that the developer (or the application code) has to explicitly start and end a transaction. It means that the user has to explicitly start a transaction with the help of EntityManager object, and then have to commit it, if everything goes normal, else have to roll-back the transaction if some error occurs. With container-managed transactions, the transactional behavior for your EJBs is determined at deployment time. A transaction attribute determines the scope of a transaction when an EJB method is invoked. It specifies whether an EJB method executes within an existing transaction context. An EJB method can have one of the following transaction attributes: Never The method must never execute within an existing transaction context. If the client invokes such a method within a transaction context, the EJB container must throw a RemoteException (EJBException for local client). NotSupported The EJB container ensures that the method doesn't execute in a transaction context. If one exists, the container suspends the transaction for the duration of the EJB method, and resumes the transaction once the method exits. Supports The method executes with or without an existing transaction context. A new transaction isn't created before the method starts, but if one exists, it will be used, and it may influence the outcome of the transaction. Required The method requires a transaction context before it is invoked. If one doesn't exist, a new transaction is created before the method starts. Mandatory The method must never execute without a transaction context. If an existing transaction context doesn't exist, the EJB container must throw a TransactionRequiredException. RequiresNew A new transaction is created regardless of whether a client transaction context exists. The existing transaction is suspended, the new transaction is created for the duration of the method call, and the existing transaction is resumed once the method terminates.
Transcript of "Entity Persistence with JPA"
Entity Persistence with JPA [email_address]
What’s Inside <ul><li>JPA </li></ul><ul><li>JPA Architecture </li></ul><ul><li>Entity </li></ul><ul><li>Object/Relational Mapping </li></ul><ul><li>Entity Relationship </li></ul><ul><li>Persistence Unit </li></ul><ul><li>Persistence Context </li></ul><ul><li>Entity Manager </li></ul><ul><li>Entity Manager API </li></ul><ul><li>Query API </li></ul><ul><li>Annotations </li></ul><ul><li>Transactions </li></ul><ul><li>Next Steps </li></ul>
JPA <ul><li>What </li></ul><ul><ul><li>JPA is just a specification from Sun, which is released under JEE 5 specification. </li></ul></ul><ul><ul><li>A feature-rich implementation of the persistence part of Enterprise Java Beans 3.0. JPA defines an interface to perform CRUD operations between POJO's and a data store. </li></ul></ul><ul><li>Why </li></ul><ul><ul><li>JPA is not a new technology; rather, it has collected the best ideas from existing persistence technologies like Hibernate, TopLink etc . The result is a standardized specification that helps you build a persistence layer that is independent of any particular persistence provider. </li></ul></ul>
Entity <ul><li>Lightweight persistent domain object – the thing you persist </li></ul><ul><li>Restrictions </li></ul><ul><ul><li>must have a public or protected no-arg constructor </li></ul></ul><ul><ul><li>cannot be final </li></ul></ul><ul><ul><li>cannot have final methods or final instance variables that are to be persisted </li></ul></ul><ul><ul><li>can be abstract or concrete class </li></ul></ul><ul><ul><li>must have a primary key </li></ul></ul><ul><ul><li>Example (Entity) </li></ul></ul>
Entity Relationship <ul><li>Defined by relationships in the database schema </li></ul><ul><ul><li>ManyToOne </li></ul></ul><ul><ul><li>OneToOne </li></ul></ul><ul><ul><li>OneToMany </li></ul></ul><ul><ul><li>ManyToMany </li></ul></ul>
Persistence Unit <ul><li>The set of all classes mapped to a single database for the application </li></ul><ul><li>Defined in META-INF/persistence.xml </li></ul><ul><li>An application can have multiple persistence units </li></ul><?xml version= "1.0" encoding="UTF-8"?> <persistence version= "1.0" xmlns= "http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name= “subin-persistence-unit“ transaction-type=" JTA "> <jta-data-source> jndi/jdbc/traceds </jta-data-source> </persistence-unit> <persistence-unit name= “subin-persistence-unit-test“ transaction-type=" RESOURCE_LOCAL "> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class> com.subin.entity.HistoryBean </class> <!-- <class>com.subin.entity.ServiceBean</class> <class>com.subin.entity.LookupBean</class> --> <properties> <property name= "hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> <property name= "hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <property name= "hibernate.show_sql" value="true" /> <property name= "hibernate.format.sql" value="true" /> <property name= "hibernate.connection.username" value="root" /> <property name= "hibernate.connection.password" value="root" /> <property name= "hibernate.connection.url" value="jdbc:mysql://192.168.160.107/testdb" /> </properties> </persistence-unit> </persistence>
Persistence Context <ul><li>Abstraction representing a set of “managed” entity instances </li></ul><ul><ul><li>Entities keyed by their persistent identity </li></ul></ul><ul><ul><li>Only one entity with a given persistent identity may exist in the PC </li></ul></ul><ul><ul><li>Entities are added to the PC, but are not individually removable (“detached”) </li></ul></ul><ul><li>Controlled and managed by EntityManager </li></ul><ul><ul><li>Contents of PC change as a result of operations on EntityManager API </li></ul></ul><ul><li>“ local working copy” of persistent objects </li></ul>
Persistence Context Application Persistence Context Entities MyEntity A MyEntity B MyEntity C MyEntity a EntityManager MyEntity b Entity state
Entity Manager <ul><li>API for interacting with the Entity </li></ul><ul><li>Can think of it as a proxy to a persistence context </li></ul><ul><ul><li>May access multiple different persistence contexts throughout its lifetime </li></ul></ul><ul><li>The EntityManagerFactory is used to create an instance of EntityManager. </li></ul><ul><li>Example (Persistence Context,EntityManagerFactory,EntityManager) </li></ul>
Entity Manager API <ul><li>persist()- Insert the state of an entity into the db </li></ul><ul><li>remove()- Delete the entity state from the db </li></ul><ul><li>refresh()- Reload the entity state from the db </li></ul><ul><li>merge()- Synchronize the state of detached entity with the pc </li></ul><ul><li>find()- Execute a simple PK query </li></ul><ul><li>createQuery()- Create query instance using dynamic JP QL </li></ul><ul><li>createNamedQuery()- Create instance for a predefined query </li></ul><ul><li>createNativeQuery()- Create instance for an SQL query </li></ul><ul><li>contains()- Determine if entity is managed by pc </li></ul><ul><li>flush()- Force synchronization of pc to database </li></ul>
Query API <ul><li>getResultList() – execute query returning multiple results </li></ul><ul><li>getSingleResult() – execute query returning single result </li></ul><ul><li>executeUpdate() – execute bulk update or delete </li></ul><ul><li>setFirstResult() – set the first result to retrieve </li></ul><ul><li>setMaxResults() – set the maximum number of results to retrieve </li></ul><ul><li>setParameter() – bind a value to a named or positional parameter </li></ul><ul><li>setHint() – apply a vendor-specific hint to the query </li></ul><ul><li>setFlushMode()– apply a flush mode to the query when it gets run </li></ul>
Transactions <ul><li>Two types </li></ul><ul><ul><li>Default to JTA in a Java EE environment </li></ul></ul><ul><ul><li>Default to RESOURCE_LOCAL in a Java SE environment </li></ul></ul><ul><li>@TransactionAttribute Annotation </li></ul><ul><li>TransactionAttributeType.REQUIRED </li></ul><ul><li>TransactionAttributeType.REQUIRES_NEW </li></ul><ul><li>TransactionAttributeType.MANDATORY </li></ul><ul><li>TransactionAttributeType.NOT_SUPPORTED </li></ul><ul><li>TransactionAttributeType.NEVER </li></ul><ul><li>TransactionAttributeType.SUPPORTS </li></ul><ul><li>How can we specify </li></ul>
Next Steps <ul><li>Dynamic quries </li></ul><ul><li>Named quries </li></ul><ul><li>JPA Queries and JPQL (http://www.objectdb.com/java/jpa/query) </li></ul>