1 / 69

Persistence: EntityManager

Persistence: EntityManager. In Java EE 5, persistence has been spun off into its own specification: Java Persistence 1.0. Persistence provides an ease-of-use abstraction on top of JDBC so that your code can be isolated from database, vendor-specific peculiarities and optimizations.

cjerome
Télécharger la présentation

Persistence: EntityManager

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Persistence: EntityManager • In Java EE 5, persistence has been spun off into its own specification: • Java Persistence 1.0. Persistence provides an ease-of-use abstraction on top of JDBC so that your code can be isolated from database, vendor-specific peculiarities and optimizations.

  2. Persistence: EntityManager • In the new Java Persistence specification, the EntityManager is the central service for all persistence actions. • The EntityManager is tightly integrated with Java EE and EJB but is not limited to this environment; it can be used in plain Java programs. • You can use Java Persistence outside of an application server and in plain Java SE programs.

  3. Entities Are POJOs • Let's look at a simple example of a Customer entity: import javax.persistence.*; @Entity public class Customer { private int id; private String name; @Id @GeneratedValue public int getId( ) { return id; }

  4. Entities Are POJOs public void setId(int id) { this.id = id; } String getName( ) { return name; } public void setName(String name) { this.name = name; } }

  5. Entities Are POJOs • Calling the new operator does not magically interact with some underlying service to create the Customer class in the database: Customer cust = new Customer( ); cust.setName("Bill"); • Allocated instances of the Customer class remain POJOs until you ask the EntityManager to create the entity in the database.

  6. Managed Versus Unmanaged Entities • An entity bean instance is either managed (a.k.a. attached) by an entity manager or unmanaged (a.k.a. detached). • When an entity is attached to an EntityManager, the manager tracks state changes to the entity and synchronizes those changes to the database whenever the entity manager decides to flush its state. • When an entity is detached, it is unmanaged. Any state changes to an entity that is detached are not tracked by the entity manager.

  7. Persistence Context • A persistence context is a set of managed entity object instances. • Persistence contexts are managed by an entity manager. • Once a persistence context is closed, all managed entity object instances become detached and are no longer managed.

  8. Persistence Context • Once an object is detached from a persistence context, it can no longer be managed by an entity manager, and any state changes to this object instance will not be synchronized with the database. • There are two types of persistence contexts: transaction-scoped and extended persistence contexts.

  9. Transaction-scoped persistence context • Persistence contexts may live as long as a transaction and be closed when a transaction completes. • This is called a transaction-scoped persistence context • Only application server managed persistence contexts can be transaction-scoped.

  10. Transaction-scoped persistence context • In other words, only EntityManager instances injected with the @PersistenceContext annotation or its XML equivalent may be transaction-scoped. @PersistenceContext (unitName="titan") EntityManager entityManager; @TransactionAttribute(REQUIRED) public Customer someMethod( ) { Customer cust = entityManager.find(Customer.class, 1); cust.setName("new name"); return cust;}

  11. Extended persistence context • Persistence contexts may also be configured to live longer than a transaction. This is called an extended persistence context • Here's some small pseudocode to illustrate this concept: Customer cust = null; transaction.begin( ); // start transaction 1 cust = extendedEntityManager.find(Customer.class, 1); transaction.commit( ); // transaction 1 ends transaction.begin( ); // start transaction 2

  12. Extended persistence context cust.setName("Bill"); extendedEntityManager.flush( ); transaction.commit( ); // cust instance remains managed and changes are flushed • In this example, a local variable, cust, is initialized by calling the find( ) method in transaction 1.

  13. Extended persistence context • Unlike a transaction-scoped persistence context, the Customer instance pointed to by this local variable remains managed. • This is because persistence context stays alive past the completion of transaction 1. • In transaction 2, the customer is updated and the changes are flushed to the database.

  14. Detached entities • Entity instances become unmanaged and detached when a transaction scope or extended persistence context ends. • An interesting side effect is that detached entities can be serialized and sent across the network to a remote client. • The client can make changes remotely to these serialized object instances and send them back to the server to be merged back and synchronized with the database.

  15. Packaging a Persistence Unit • A persistence unit is defined in a persistence.xml file. • This file is a required deployment descriptor for the Java Persistence specification. • A persistence.xml file can define one or more persistence units. • This file is located in the META-INF directory of: • A plain JAR file within the classpath of a regular Java SE program.

  16. Packaging a Persistence Unit • An EJB-JAR file. A persistence unit can be included with an EJB deployment. • A JAR file in the WEB-INF/lib directory in a web archive file (.war). A JAR file in the root of an enterprise archive (.ear). • A JAR file in the EAR lib directory.

  17. Packaging a Persistence Unit titan-persistence.jar

  18. Packaging a Persistence Unit • The set of classes that belong to the persistence unit can be specified, or you can opt for the persistence provider to scan the JAR file automatically for the set of classes to deploy as entities. • Each persistence unit is tied to one and only one data source. In Java SE environments, vendor-specific configuration must be used to define and configure these data sources. • In Java EE environments, specific XML elements define this association.

  19. Packaging a Persistence Unit • The root of the persistence.xml XML schema is the <persistence> element, which contains one or more <persistence-unit> elements. • Each <persistence-unit> has two attributes: name (required) and transaction-type (optional). • The subelements of <persistence-unit> are <description> (optional), <provider> (optional), <jta-data-source> (optional), <non-jta-data-source> (optional), <mapping-file> (optional), <jar-file> (optional), <class> (optional), <properties> (optional), and <exclude-unlisted-classes> (optional).

  20. Packaging a Persistence Unit • Here's an example of a persistence.xml file: <persistence> <persistence-unit name="titan"> <jta-data-source>java:/OracleDS</jta-data-source> <properties> <property name="org.hibernate.hbm2ddl">update</property> </properties> </persistence-unit> </persistence>

  21. The Persistence Unit Class Set • Scanning JAR files is guaranteed to work in Java EE environments but is not portable in Java SE applications. • In theory, it may not be possible to determine the set of JAR files that must be scanned. • In practice, however, this is not the case. All major vendors in the EJB 3.0 Expert Group were polled unofficially and said they would have no problems supporting this feature in SE.

  22. The Persistence Unit Class Set • Whether you do or do not rely on a JAR scan, classes can be listed explicitly with the <class> element: <persistence> <persistence-unit name="titan"> <jta-data-source>java:/OracleDS</jta-data-source> <class>com.titan.domain.Cabin</class> <class>com.titan.domain.Customer</class> <properties> <property name="org.hibernate.hbm2ddl">update</property> </properties> </persistence-unit> </persistence>

  23. The Persistence Unit Class Set • The Cabin and Customer classes listed within the <class> elements are added to the persistence unit set along with any other classes scanned in the persistence unit's archive. • The final set of classes is determined by a union of all of the following metadata:

  24. The Persistence Unit Class Set • Classes annotated with @Entity in the persistence.xml file's JAR file (unless <exclude-unlisted-classes> is specified) • Classes annotated with @Entity that are contained within any JARs listed with any <jar-file> elements • Classes mapped in the META-INF/orm.xml file if it exists • Classes mapped in any XML files referenced with the <mapping-file> element • Classes listed with any <class> elements

  25. Obtaining an EntityManager • Now that you have packaged and deployed your persistence units, you need to obtain access to an EntityManager so that you can persist, update, remove, and query your entity beans within your databases. • In Java SE, entity managers are created using a javax.persistence.EntityManagerFactory.

  26. Obtaining an EntityManager • Although you can use the factory interface in Java EE, this platform provides some additional features that make it easier and less verbose to manage entity manager instances.

  27. EntityManagerFactory • EntityManagers may be created or obtained from an EntityManagerFactory. In a Java SE application, you must use an EntityManagerFactory to create instances of an EntityManager. Using the factory isn't a requirement in Java EE. package javax.persistence; public interface EntityManagerFactory { EntityManager createEntityManager( ); EntityManager createEntityManager(java.util.Map map); void close( ); boolean isOpen( ); }

  28. Getting an EntityManagerFactory in Java SE • In Java SE, the javax.persistence.Persistence class is responsible for bootstrapping an EntityManagerFactory: public class Persistence { public static EntityManagerFactory createEntityManagerFactory( String unitName ); public static EntityManagerFactory createEntityManagerFactory( String unitName, java.util.Map properties );

  29. Getting an EntityManagerFactory in Java SE • The javax.persistence.Persistence class looks for persistence.xml deployment descriptors within your Java classpath. • The unitName parameter you pass in will allow the Persistence implementation to locate an EntityManagerFactory that matches the given name.

  30. Getting an EntityManagerFactory in Java SE • Additionally, you can override or add any vendor-specific properties defined in the <properties> element of the persistence.xml file by passing in a java.util.Map as a second parameter: EntityManagerFactory factory = Persistence.createEntityManagerFactory("CRM"); ... factory.close( );

  31. Getting an EntityManagerFactory in Java SE • In Java SE, it is recommended that you close( ) the EntityManagerFactory. • This frees up any resources that are being held by the factory.

  32. Getting an EntityManagerFactory in Java EE • In Java EE, it is a bit easier to get an EntityManagerFactory. It can be injected directly into a field or setter method of your EJBs using the @javax.persistence.PersistenceUnitannotation: package javax.persistence; @Target({METHOD, FIELD, TYPE}) @Retention(RUNTIME) public @interface PersistenceUnit { String name( ) default ""; String unitName( ) default ""; }

  33. Getting an EntityManagerFactory in Java EE • The unitName( ) is the identity of the PersistenceUnit. • When the PersistenceUnit is used, it not only injects the EntityManagerFactory, it also registers a reference to it within the JNDI ENC of the EJB. • The EJB container is responsible for noticing the @PersistenceUnit annotation and injecting the correct factory:

  34. Getting an EntityManagerFactory in Java EE import javax.persistence.*; import javax.ejb.*; @Stateless public MyBean implements MyBusinessInterface { @PersistenceUnit(unitName="CRM") private EntityManagerFactory factory; private EntityManagerFactory factory2; @PersistenceUnit(unitName="CUSTDB") public void setFactory2(EntityManagerFactory f) { this.factory2 = f; }

  35. Getting an EntityManagerFactory in Java EE • When an instance of the stateless session bean is created, the EJB container sets the factory field to the persistence unit identified by "CRM". • It also calls the setFactory2( ) method with the "CUSTDB" persistence unit.

  36. Obtaining a Persistence Context • A persistence context can be created by calling the EntityManagerFactory.createEntityManager( ) method. • The returned EntityManager instance represents an extended persistence context.

  37. Obtaining a Persistence Context • If the EntityManagerFactory is JTA-enabled, then you have to explicitly enlist the EntityManager instance within a transaction by calling the EntityManager.joinTransaction( ) method. • If you do not enlist the EntityManager within the JTA transaction, then changes you make to your entities are not synchronized with the database.

  38. Interacting with an EntityManager • The EntityManager API has methods to insert and remove entities from a database as well as merge updates from detached entity instances. There is also a rich query API that you can access by creating query objects from certain EntityManager methods: package javax.persistence; public interface EntityManager { public void persist(Object entity); public <T> T find(Class <T> entityClass, Object primaryKey); public <T> T getReference(Class <T> entityClass, Object primaryKey); public <T> T merge(T entity);

  39. Interacting with an EntityManager public void remove(Object entity); public void lock(Object entity, LockModeType lockMode); public void refresh(Object entity); public boolean contains(Object entity); public void clear( ); public void joinTransaction( ); public void flush( ); public FlushModeType getFlushMode( ); public void setFlushMode(FlushModeType type);

  40. Interacting with an EntityManager public Query createQuery(String queryString); public Query createNamedQuery(String name); public Query createNativeQuery(String sqlString); public Query createNativeQuery(String sqlString, String resultSetMapping); public Query createNativeQuery(String sqlString, Class resultClass); public Object getDelegate( ); public void close( ); public boolean isOpen( ); }

  41. Persisting Entities • Persisting an entity is the act of inserting it within a database. You persist entities that have not yet been created in the database. • You interact with the entity manager service by calling the EntityManager.persist( ) method: Custom cust = new Customer( ); cust.setName("Bill"); entityManager.persist(cust);

  42. Persisting Entities • When this method is called, the entity manager queues the Customer for insertion into the database, and the object instance becomes managed. • When the actual insertion happens depends on a few variables. • If persist( ) is called within a transaction, the insert may happen immediately, or it may be queued until the end of the transaction, depending on the flush mode (described later in this chapter).

  43. Persisting Entities • You can always force the insertion manually within a transaction by calling the flush( ) method. • You may call persist( ) outside of a transaction if and only if the entity manager is an EXTENDED persistence context. • When you call persist( ) outside of a transaction with an EXTENDED persistence context, the insert is queued until the persistence context is associated with a transaction.

  44. Persisting Entities • If the entity has any relationships with other entities, these entities may also be created within the database if you have the appropriate cascade policies set up. • The persist( ) method throws an IllegalArgumentException if its parameter is not an entity type. • TransactionRequiredException is thrown if this method is invoked on a transaction-scoped persistence context.

  45. Finding Entities • The entity manager provides two mechanisms for locating objects in your database. • One way is with simple entity manager methods that locate an entity by its primary key. • The other is by creating and executing queries.

  46. find( ) and getReference( ) • The EntityManager has two different methods that allow you to find an entity by its primary key: public interface EntityManager { <T> T find(Class<T> entityClass, Object primaryKey); <T> T getReference(Class<T> entityClass, Object primaryKey); }

  47. find( ) and getReference( ) • The find( ) method returns null if the entity is not found in the database. It also initializes the state based on the lazy-loading policies of each property. Customer cust = entityManager.find(Customer.class, 2); Customer cust = null; try { cust = entityManager.getReference(Customer.class, 2); } catch (EntityNotFoundException notFound) { // recovery logic }

  48. find( ) and getReference( ) • getReference( ) differs from find( ) in that if the entity is not found in the database, this method throws a javax.persistence.EntityNotFoundException and there is no guarantee that the entity's state will be initialized.

  49. Queries • Persistent objects can also be located by using EJB QL. • Unlike EJB 2.1, there are no finder methods, and you must create a Queryobject by calling the EntityManager's createQuery( ), createNamedQuery( ), or createNativeQuery( ) method:

  50. Queries public interface EntityManager { Query createQuery(String queryString); Query createNamedQuery(String name); Query createNativeQuery(String sqlString); Query createNativeQuery(String sqlString, Class resultClass); Query createNativeQuery(String sqlString, String resultSetMapping); }

More Related