EJB3.0 Persistence: Professional Open Source™
EJB3.0 Persistence: Professional Open Source™
EJB3.0 Persistence: Professional Open Source™
0 Persistence
Professional Open Source
EntityManager is the central sevice for all persistence actions. Entities are plain java objects that are allocated just like any other Java object. They donot become persistent until your code explicitly interacts with the EntityManager to make them persistent. The EntityManager manages the O/R mapping between a fixed set of entity classes and an underlying data source. It provides APIs for creating queries, finding objects, synchronizing objects, and inserting objects into the database. EntityManager also can provide caching and manage the interaction between an entity and transactional services in a Java EE environent such as JTA.
Managed Versus Unmanaged Entities : - When an entity is attached to an EntityManager, the manager tracks the 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.
Persistence Context
Professional Open Source
A persistence context is a set of managed entity object instances. Persistence contexts are managed by an entity manager. The entity manager tracks all entity objects within a persistence context for changes and updates made, and flushes these changes to the database using the flush mode rules. Once the 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. When a persistence context is closed, all managed entity objects become detached and are unmanaged.
There are two types of persistence contexts: 1. Transaction-scoped persistence context 2. Extended persistence context Transaction-scoped persistence context : Persistence context may live as long as a transaction and be closed when a transaction completes. This is called a transaction-scoped persistence context. When the transaction completes, the transaction-scoped persistence context will be destroyed and all managed entity object instances will become detached.
Application server managed persistence contexts can be transctionscoped. In other words, only Entity Manager instances injected with the @PersistenceContext annotation or its XML equivalent may be transaction-scoped. @PersistenceContext(unit name=titan) EntityManager entityManager; @TransactionAttribute(REQUIRED) public Customer someMethod() { Customer cust = entityManager.find(Customer.class,1); cust.setName(new name); return cust; }
Extended Persistence Context Persistence contexts may also be configured to live longer than a transaction. This is called an extended persistence context. Entity object instances that are attached to an extended context remain managed even after a transaction is complete. This feature is extremely useful in situations where you want to have a conversation with your database but not keep a longrunning transaction, as transactions hold valuable resources like JDBC connections and database locks.
. Customer cust = null; transaction.begin(); //start tranasaction 1 cust = extendedManager.find(Customer.class,1); tranasction.commit(); // tranasaction 1 ends transaction.begin(); // start transaction 2 cust.setName(bill); extendedManager.flush(); tranasaction.commit(); // cust instance remains managed and changes // are flushed
Detached Entities
Professional Open Source
Entity instances become unmanaged and detached when a transaction scope or extended persistence context ends.
Detached entities can be serialized and sent across the network to a remote client. The client make changes remotely to these serialized object instances and send them back to the server to be merged back and synchronized with the database.
EJB2.1 code uses Value Object (DTO) . The idea of this pattern was that the entity bean exposed a method that copied its entire state into an object that could be serialized to remote clients. EJB3.0 eliminates the need for this pattern because persistent objects become value objects automatically when they are detached from a persistence context.
An example of persistence.xml fle : <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> The JAR file of the persistence unit may also optionally contain a mapping XML DD called orm.xml in the META-INF directory of the deployment. This file used to define the mapping between the classes container in the persistence unit and the database to which they map.
A persistence unit maps a fixed a set of classes to a relational database. By default, it you specify no other metadata within your persistence.xml file, the JAR file that contains persistence.xml will be scanned from its root for any classes annotated with the @javax.persistence.Enity annotation. We can specify additional JARs that we want to be scanned using the <jar-file> element. <persistence> <jar-file>./lib/customer.jar</jar-file> </persistence.
10
Scanning JAR files is guaranteed to work in Java EE environment but it is not portable in Java SE applications.
Whether we do or do not rely on a JAR scan, classes can be lised explicitly with <class> element:
<persistence> <class>com.titan.domain.Cabin</class> <class>com.titan.domain.Customer</class> </persistence>
11
If you do not want the persistence.xmls JAR file to be scanned, then you can use the <exclude-unlisted-classes> element.
12
The final set of classes is determined by a union of all of the following metadata : 1. Classes annotated with @Entity in the persistence.xml files JAR file
(unless <exclude-unlisted-classes> is specified) 2. Classes annotated with @Entity that are contained within any JARs listed with any <jar-file> element 3. Classes mapped in the META-INF/orm.xml file if it exists 4. Classes mapped in any XML files referenced with the <mapping-file> element. 5. Classes listed with any <class> elements
13
EntityManagerFactory
Professional Open Source
public interface EntityManagerFactory { EntityManager createEntityManager(); EntityManager createEntityManager(java.util.Map map); void close(); boolean isOpen(); }
The createEntityManager() methods return EntityManager instances that manage a distinct extended persistence context.
14
EntityManagerFactory in Java SE
Professional Open Source
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 createEntityMangerFactory( string unitname); } public static EntityManagerFactory createEntityManagerFactory( Stirng unitName, java.util.Map.properties); } The javax.persistence.Persistence class looks for persistence.xml deployment descriptor within the java classpath. EntityManagerFactory factory = Persistence.createEntityManagerFactory(CRM); factory.close();
15
The EntityManager API has methods to insert and remove entities from a database as well as merge, updates from detached enity instances.
public interface EntityManager { public void persist(Object entity); // from new to managed public <T> T merge(T entity); // from detached to managed public void remove(Object entity); // from managed to removed public Object find(String entityName, Object primaryKey);// find by primary key public <T> T find(Class entityClass, Object primaryKey); // ---public void flush(); // sync to database public Query createQuery(String ejbqlString); // create EJB-QL query public Query createNamedQuery(String name); // named queries public Query createNativeQuery(String sqlString); // create SQL query (not portable) public void refresh(Object entity); // sync from database ... }
16
<entity-manger> <entity class=com.titan.domain.Customer access=PROPERTY> <attributes> <id name=id/> </attritubes> </entity> </entity-manger>
17
Entity Life-cycle
Professional Open Source
18
Entity Life-cycle
Professional Open Source
19
EJB QL
Professional Open Source
20
Query API
Professional Open Source
21
Polymorphic Queries
Professional Open Source
22
Joins
Professional Open Source
23
Dynamic Queries
Professional Open Source
24
Named Queries
Professional Open Source
25
To enable JBoss Cache as the second level cache for EJB3 entity beans, you need to add the JBoss Cache classes and services to the persistence.xml file as optional properties. <entity-manager> <name>clusterstore</name> <jta-data-source>java:/DvdStoreDS</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="none"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> <property name="hibernate.cache.provider_class" value="org.jboss.ejb3.entity.TreeCacheProviderHook"/> <property name="hibernate.treecache.mbean.object_name" value="jboss.cache:service=EJB3EntityTreeCache"/> </properties> </entity-manager>
JBoss, Inc. 2003, 2004.
26
To cache an entity bean, you can simply annotate the class with the @Cache tag. In the case of the Category bean, we use the READ_ONLY strategy. Once the categories are read from the database by one server, they become available to all servers in the cluster in a replicated in-memory cache. If you do change the categories in the database, you will need to manually evict the existing cache for the change to show up in the application server. @Entity @Table(name="CATEGORIES") @Cache(usage=CacheConcurrencyStrategy.READ_ONLY) public class Category implements Serializable { int category; String categoryName; // ... ...
27
You can fine tune the cache for each entity bean in the ejb3-entitycache-service.xml configuration file. For instance, you can specify the size of the cache. If there are too many objects in the cache, the cache could evict oldest objects (or least used objects, depending on configuration) to make room for new objects. The cache for the clusterstore.par.Category entity bean is /clusterstore/par/Category cache region. <server> <mbean code="org.jboss.cache.TreeCache" name="jboss.cache:service=EJB3EntityTreeCache"> <depends>jboss:service=Naming <depends>jboss:service=TransactionManager ... ...
JBoss, Inc. 2003, 2004.
28
<attribute name="EvictionPolicyConfig"> <config> <attribute name="wakeUpIntervalSeconds">5</attribute> <region name="/_default_"> <attribute name="maxNodes">5000</attribute> <attribute name="timeToLiveSeconds">1000</attribute>
</region>
<region name="/clusterstore/par/Category"> <attribute name="maxNodes">10</attribute> <attribute name="timeToLiveSeconds">5000</attribute> </region> ... ... </config> </attribute> </mbean>
</server>
JBoss, Inc. 2003, 2004.
29
Query Cache
Professional Open Source
@Entity @Table(name="PRODUCTS") @Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL) public class Product implements Serializable { long productId; String title; String actor; float price;
// ... ...
}
30
Query Cache
Professional Open Source
you need to explicitly enable query cache in the persistence.xml file. <entity-manager> <name>clusterstore</name> <jta-data-source>java:/DvdStoreDS</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="none"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect" /> <property name="hibernate.cache.provider_class" value="org.jboss.ejb3.entity.TreeCacheProviderHook"/>
<property name="hibernate.treecache.mbean.object_name"
value="jboss.cache:service=EJB3EntityTreeCache"/> <property name="hibernate.cache.use_query_cache" value="true"/> </properties>
</entity-manager>
JBoss, Inc. 2003, 2004.
31
Query Cache
Professional Open Source
EntityManager em; // ... ... List <Product> products = em.createQuery("from Product p where p.title LIKE :title " + "and p.actor LIKE :actor") .setParameter("title", title) .setParameter("actor", actor) .setHint("org.hibernate.cacheRegion", "/ProductSearch");
32
Query Cache
Professional Open Source
In the ejb3-entity-cache-service.xml configuration file, you can define the named /ProductSearch query cache region. The query cache expires if any server in the cluster updates the queried database table (i.e., the PRODUCTS table for the Product bean) in any way. In the example below, we also specify an optional cache region for the Product entity bean, which stores the actual entity objects in the query result. <server> <mbean code="org.jboss.cache.TreeCache" name="jboss.cache:service=EJB3EntityTreeCache"> <depends>jboss:service=Naming <depends>jboss:service=TransactionManager ... ...
JBoss, Inc. 2003, 2004.
33
Query Cache
Professional Open Source
<attribute name="EvictionPolicyConfig"> <config> <attribute name="wakeUpIntervalSeconds">5</attribute> <region name="/_default_"> <attribute name="maxNodes">5000</attribute> <attribute name="timeToLiveSeconds">1000</attribute>
</region>
<region name="/clusterstore/par/Product"> <attribute name="maxNodes">10000</attribute> <attribute name="timeToLiveSeconds">5000</attribute> </region> <region name="/ProductSearch"> <attribute name="maxNodes">1000</attribute> <attribute name="timeToLiveSeconds">5000</attribute> </region> ... ... <config> </attribute> </mbean> </server>
34