Download slides

Document related concepts
no text concepts found
Transcript
Enterprise
Java
Java Persistence:
EntityManager
v120215
Java Persistence: EntityManager
1
Goals
Enterprise
Java
• Become familiar with the Java Persistence API and
EntityManager
• Become familiar with how to setup a project using JPA
and a provider (Hibernate)
v120215
Java Persistence: EntityManager
2
Objectives
Enterprise
Java
• Provide an Overview of the Java Persistence API
• Go through Details of the EntityManager
• Go through some implementation details associated
with class projects
v120215
Java Persistence: EntityManager
3
Overview
Enterprise
Java
• Earlier versions of EJB Specification defined the
persistence layer
– javax.ejb.EntityBean
• Java EE 5 moved persistence to its own specification
– Java Persistence API (JPA) version 1.0
– javax.persistence
• ease of use API above JDBC
• Provides
– Object/Relational Mapping (ORM) Engine
– Query Language (SQL-Like, based on former EJB-QL)
• Java EE 6 uses JPA 2.0
v120215
Java Persistence: EntityManager
4
javax.persistence.EntityManager
Enterprise
Java
• Replaces much of the EJB 2.x “Home” functionality
• Handles O/R Mapping of Entities to the database
• Provides APIs
–
–
–
–
inserting objects into database
getting objects from database
synchronizing objects with database
querying database
• Provides caching
• Coordinates with transactional services (JTA)
• Tightly integrated with Java EE and EJB, but not
limited to that environment
v120215
Java Persistence: EntityManager
5
Entities
Enterprise
Java
• (formerly and sometimes still called Entity Beans)
• are now Plain Old Java Objects (POJOs)
– nothing special happens when calling new
Author author = new Author();
• are not persistent until associated with an
EntityManager
em.persist(author);
v120215
Java Persistence: EntityManager
6
Example Author POJO Entity
@javax.persistence.Entity
public class Author {
private long id;
private long version=0;
private String firstName;
private String lastName;
private String subject;
private Date publishDate;
Enterprise
Java
Warning: Using GeneratedValue
without specifying a specific strategy
should only be used when you have
no intention of controlling how the
provider manages primary keys for
this object type. This would be rare.
public Author() {}
public Author(long id) { this.id = id; }
...
}
v120215
@Id @GeneratedValue
public long getId() { return id;}
private void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
Java Persistence: EntityManager
7
Creating Entity in Database
Enterprise
Java
Author author = new Author(); //primary key will be gen
author.setFirstName("dr");
author.setLastName("seuss");
author.setSubject("children");
author.setPublishDate(new Date());
log_.info("creating author:" + author);
em.persist(author);
log_.info("created author:" + author);
//output
-creating author:id=0, fn=dr,
pdate=Fri Sep 15 11:54:15 EDT
-created author:id=50, fn=dr,
pdate=Fri Sep 15 11:54:15 EDT
v120215
ln=seuss, subject=children,
2006
ln=seuss, subject=children,
2006
Java Persistence: EntityManager
8
Managed and Unmanaged Entities
Enterprise
Java
• Unmanaged state (detached)
– instance not associated with an EntityManager
– state changes are not tracked
– can be serialized to client and returned to be
synchronized with database
– nothing equivalent to this state in EJB 2.1 entity beans
• Managed state (attached)
– instance associated with an EntityManager
– state changes are tracked within a Persistence Context
– EJB 2.1 entity beans were always managed
• client interfaced with data through a proxy or state
transferred through a Data Transfer Object
v120215
Java Persistence: EntityManager
9
Persistence Context
Enterprise
Java
• A set of attached entity instances managed by an
EntityManager
• All entities become detached once closed
• Two types
– Transaction-scoped Persistence Contexts
• begin/end at transaction boundaries
• only made available through container managed
persistence contexts
– Extended Persistence Contexts
• live beyond any single transaction
• allow longer-lived interactions with database without
lengthy transactions tying up database resources
v120215
Java Persistence: EntityManager
10
Persistence Context Examples
Enterprise
Java
• Transaction-scoped (inside server container)
@PersistenceContext(unitName=”jpaDemo”)
EntityManager em;
@TransactionAttribute(REQUIRED)
public void update(long authorId, String type) {
Author author = em.find(Author.class, authorId);
author.setType(type);
}
• Extended (inside or outside server container)
EntityManager em = Persistence.
createEntityManagerFactory(“jpaDemo”).createEntityManager();
tx.begin();
//tx 1 begins
Author author = em.find(Author.class, authorId);
tx.commit();
//tx 1 ends, but author remains managed
...
tx.begin();
//tx 2 begins
author.setType(type);
tx.commit();
//tx 2 ends, and author is still managed until close
v120215
Java Persistence: EntityManager
11
Persistence Unit
Enterprise
Java
• A set of classes that are mapped to the database
• defined in META-INF/persistence.xml
• must have an identity
– “” is a valid identity
• Classes
– may be named in persistence.xml file
– may be automatically scanned for in the classpath
• orm.xml
– optionally provided to augment, provide, or replace class
persistence metadata
– (more on orm.xml in Core ORM topic)
v120215
Java Persistence: EntityManager
12
Example Component Layout
Enterprise
Java
META-INF/
+---persistence.xml
ejava
+ ---examples
+---…
+---DAOException.class
+---AuthorDAO.class
+---jpa
|
+---JPAAuthorDAO.class
+--bo
+---Author.class
v120215
Java Persistence: EntityManager
13
Example persistence.xml
Enterprise
Java
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
version="1.0">
<persistence-unit name="jpaDemo">
referenced by name
• global JNDI name by which
provider references resource
(will be used when deployed within server)
• may use properties element in Java SE
environments that lack JNDI
<jta-data-source>java:/ejavaDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.show_sql" value="true"/
</properties>
</persistence-unit>
</persistence>
v120215
• vendor-specific way to configure
persistence provider
Java Persistence: EntityManager
14
Another Example persistence.xml
Enterprise
Java
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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" version="1.0">
<persistence-unit name="jpaDemo">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.cache.provider_class"
value="net.sf.ehcache.hibernate.Provider"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.url"
value="jdbc:hsqldb:hsql://localhost:9001"/>
<property name="hibernate.connection.driver_class"
value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.password"
value=""/>
<property name="hibernate.connection.username"
value="sa"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence
v120215
Java Persistence: EntityManager
15
Solution-specific property option:
hibernate.properties
Enterprise
Java
$ cat hibernate.properties
hibernate.dialecte=org.hibernate.dialect.HSQLDialect
hibernate.connection.url=jdbc:hsqldb:hsql://localhost:9001
hibernate.connection.driver_class=org.hsqldb.jdbcDriver
hibernate.connection.password=
hibernate.connection.username=sa
hibernate.hbm2ddl.auto=create
#hibernate.show_sql=true
#hibernate.format_sql=true
#hibernate.jdbc.batch_size=0
• Easier to provide unit testing options that do
not get propagated into production artifacts
v120215
Java Persistence: EntityManager
16
persistence.xml elements
•
•
•
•
•
•
•
•
•
Enterprise
Java
name – identity to reference Persistence Unit
provider – fully qualified name of javax.persistence.PersistenceProvider
– not needed if provider found in classpath acceptable
mapping-file – resource path to optional mapping file
– can be used to specify <class>es or specify/override @Annotation details
jta-data-source
– vendor-specific reference to data source using JTA transactions
non-jta-data-source
– vendor-specific reference to data source using RESOURCE_LOCAL transactions
jar-file
– optional/additional jar file to scan for classes
class
– specifies entity classes not automatically scanned by provider
exclude-unlisted-classes
– if set, provider will not automatically scan archive for entity classes
properties
– may be used to provide vendor-specific properties to configure persistence providers
v120215
Java Persistence: EntityManager
17
Specifying an optional orm.xml file
Enterprise
Java
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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" version="1.0">
<persistence-unit name="jpaDemo">
<provider>...</provider>
<mapping-file>META-INF/orm.xml</mapping-file>
<properties>
...
</properties>
</persistence-unit>
</persistence
v120215
Java Persistence: EntityManager
18
Optional orm.xml overrides
Enterprise
Java
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
<entity class="ejava.examples.daoex.bo.Author"
metadata-complete="false">
<table name="DAO_AUTHOR"/>
</entity>
</entity-mappings>
v120215
Java Persistence: EntityManager
19
Entities Discovered
Enterprise
Java
• classes with @Entity annotation
– in the persistence.xml's JAR file
– contained in any JAR file listed in jar-file element
• classes mapped
– with META-INF/orm.xml
– with custom mapping files
• classes listed in persistence.xml's “<class>” element
v120215
Java Persistence: EntityManager
20
Java SE Steps
Enterprise
Java
• Startup
– Get EntityManagerFactory
• Runtime
–
–
–
–
–
Create EntityManager
Start Transaction
Interact with Entity Manager
Commit Transaction
Close EntityManager
• Shutdown
– Close EntityManagerFactory
v120215
Java Persistence: EntityManager
21
javax.persistence.Persistence
Enterprise
Java
• used to bootstrap persistence in Java SE environments
public class javax.persistence.Persistence {
public static java.lang.String PERSISTENCE_PROVIDER;
public javax.persistence.Persistence();
public static EntityManagerFactory
createEntityManagerFactory(String puName);
public static EntityManagerFactory
createEntityManagerFactory(String puName, Map props);
}
• example usage
EntityManagerFactory emf = Persistence
.createEntityManagerFactory(“jpaDemo”);
v120215
Java Persistence: EntityManager
22
Enterprise
Java
javax.persistence.EntityManagerFactory
• used to obtain reference to EntityManager in standard
Java SE environments
package javax.persistence;
public interface EntityManagerFactory{
EntityManager createEntityManager();
EntityManager createEntityManager(Map props);
void close();
boolean isOpen();
}
• Map used to supply or override properties in
persistence.xml
• close() and isOpen() only valid for non-injected EMFs
• example usage
– EntityManager em = emf.createEntityManager();
v120215
Java Persistence: EntityManager
23
javax.persistence.EntityManager
Enterprise
Java
package javax.persistence;
public interface EntityManager{
EntityTransaction getTransaction();
void persist(java.lang.Object);
Object<T> find(Class<T>, Object pKey);
Object<T> getReference(Class<T>, Object pKey);
boolean contains(Object);
Object merge(java.lang.Object);
void refresh(java.lang.Object);
void remove(java.lang.Object);
Object find(java.lang.Class, java.lang.Object);
void flush();
void clear();
void close();
isOpen();
--Query
Query
Query
Query
Query
v120215
...
createQuery(java.lang.String);
createNamedQuery(java.lang.String);
createNativeQuery(java.lang.String);
createNativeQuery(java.lang.String, java.lang.Class);
createNativeQuery(java.lang.String, java.lang.String);
Java Persistence: EntityManager
24
persist()
Enterprise
Java
Author author = new Author();
author.setFirstName("dr");
author.setLastName("seuss");
author.setSubject("children");
author.setPublishDate(new Date());
em.persist(author);
• Extended persistence contexts
– queues write until associated with transaction
• Transaction-scoped persistence contexts
– illegal to call outside the scope of a transaction
• Actual write to the database depends on FlushMode
– manually controlled with flush() call
v120215
Java Persistence: EntityManager
25
find()
Enterprise
Java
Author author2=null;
author2 = em.find(Author.class, id);
log_.info("got author author:" + author2);
got author author:id=51, fn=thing, ln=one, subject=children,
pdate=Fri Sep 15 11:54:15 EDT 2006
• Returns an instance of the class associated with the specified primary
key value
– relationships are instantiated according to lazy-loading policies
• Returns null if primary key not found
• Uses generics, so no casting is necessary
• Ids can be autoboxed without a manual wrapper
• can be called outside the scope of a transaction
• will be attached to open persistence context
– second find() will return same object
v120215
Java Persistence: EntityManager
26
getReference()
Enterprise
Java
Author author2=null;
author2 = em.getReference(Author.class, id);
log_.info("got author author:" + author2);
• Similar to find()
– Returns an instance of the class associated with the
specified primary key value
• no guarantee that object state initialized
– Throws EntityNotFoundException if primary key not
found
v120215
Java Persistence: EntityManager
27
createQuery()
Enterprise
Java
• 5 createQuery() methods
Query
Query
Query
Query
Query
createQuery(String ejbqlString);
createNamedQuery(String name);
createNativeQuery(String sqlString);
createNativeQuery(String sqlString, Class resultClass);
createNativeQuery(String sqlString, String resultSetMap);
• example usage
Query query = em.createQuery("from jpaAuthor where id=" + id);
Author author = (Author)query.getSingleResult();
• use EJB-QL and native (SQL) query languages
• similar to find/getReference()
–returned objects attached to open persistence context
v120215
Java Persistence: EntityManager
28
updating entities
Enterprise
Java
• Updates to managed entities automatically get
propagated to database according to flush policy
public Author update(Author author) {
Author dbAuthor = em.find(Author.class,author.getId());
dbAuthor.setFirstName(author.getFirstName());
dbAuthor.setLastName(author.getLastName());
dbAuthor.setSubject(author.getSubject());
dbAuthor.setPublishDate(author.getPublishDate());
return dbAuthor;
}
– Note that if author passed in was already managed...
• the changes have already been queued
• the dbAuthor returned from the find() will be the same object as author
• the sets are unnecessarily changing the values of the Author to their current
values
v120215
Java Persistence: EntityManager
29
merge()
Enterprise
Java
• merges state changes to detached objects back into
persistent storage
public Author updateByMerge(Author author) {
Author managedAuthor = em.merge(author);
return managedAuthor;
}
• Original is left detached
• Object returned is managed
• Returned object is added to persistence if did not
already exist
• Updates are made to existing object if already exists
v120215
Java Persistence: EntityManager
30
remove()
Enterprise
Java
public void remove(Author author) {
em.remove(author);
}
– removes object from database
• physically performed in database according to flush policy
• cascades to related objects according to cascade policy
– object will be detached
v120215
Java Persistence: EntityManager
31
refresh() and contains()
Enterprise
Java
• refresh()
Author author = em.find(Author.class, id);
em.refresh(author);
– used to make sure entity is in sync with database
• cascades to related entities depending on cascade policy
– entity must be currently managed by entity manager
instance
• contains()
if (em.contains(author)) {
...
}
– used to test if instance is being managed by entity
manager instance
v120215
Java Persistence: EntityManager
32
clear() and flush()
•
•
Enterprise
Java
clear()
– detaches all entities
– does not commit queued changes
• call flush() prior to clear()
flush()
– changes not synchronized with database until entity manager flushed
• persist(), merge(), remove()
– occurs automatically before executing
• correlated queries
– permits query to reflect changes in persistence context
• transaction commit
– not impacted by primary key finders
• find(), getReference()
– FlushMode
• AUTO – default and most sane
• COMMIT – an optimization to only flush and end of transaction. May
limit amount of database locking that occurs
v120215
Java Persistence: EntityManager
33
lock() and getDelegate()
Enterprise
Java
• lock()
– provides a pessimistic write lock for entity
– will be covered with later during transaction topics
• getDelegate()
– returns vendor object that implements EntityManager
interface
– used to expose vendor-specific extension API
v120215
Java Persistence: EntityManager
34
EntityTransactions
Enterprise
Java
• Only available for Entity Managers with an extended
persistence context
– Transaction-scoped persistence contexts are only
available with containers that support JTA transactions
– Extended persistence contexts generally pertain to Java
SE applications using javax.persistence.Persistence class
to get EntityManagerFactory
• transaction-like API for managing transactions within
the single resource
• transaction context obtained from EntityManager
javax.persistence.EntityTransaction tx =
em.getTransaction();
tx.begin()
tx.commit()
tx.isActive()
tx.rollback()
v120215
Java Persistence: EntityManager
35
Example
Enterprise
Java
private EntityManager em = ...
public void testQuery() throws Exception {
Author author = new Author();
author.setFirstName("test");
author.setLastName("Query");
author.setSubject("testing");
author.setPublishDate(new Date());
em.persist(author);
//need to associate em with Tx to allow query to see entity in DB
try {
em.getTransaction().begin();
//note that the persist does not have to be within the tx
em.getTransaction().commit();
}
catch (Exception ex) {
em.getTransaction().rollback();
fail("" + ex);
}
Author author2 = null;
Query query = em.createQuery(
"from jpaAuthor where id=" + author.getId());
author2 = (Author)query.getSingleResult();
}
v120215
assertNotNull(author2);
assertEquals(author.getFirstName(), author2.getFirstName());
assertEquals(author.getLastName(), author2.getLastName());
assertEquals(author.getSubject(), author2.getSubject());
assertEquals(author.getPublishDate(), author2.getPublishDate());
Java Persistence: EntityManager
36
Enterprise
Java
Implementation/Testing Details
v120215
Java Persistence: EntityManager
37
Add JPA Dependencies
Enterprise
Java
• JPA API
– JPA 1.0
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
– JPA 2.0
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
</dependency>
– Both available from the JBoss Maven/Nexus repository
v120215
Java Persistence: EntityManager
38
Add Provider Dependencies
Enterprise
Java
• Identify the JBoss repository
<repositories>
<repository>
<id>jboss-nexus</id>
<name>JBoss Nexus Repository</name>
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
</repository>
</repositories>
• Add hibernate-entitymanager
– primary dependency we need to pull in hibernate
– maven will pull in many other dependencies based on hibernateentitymanager's pom.xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.0.Final</version>
<scope>test</scope>
</dependency>
v120215
Java Persistence: EntityManager
39
Add Dependency Overrides
Enterprise
Java
• We have to pull in a library that will allow hibernate to use log4j
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
<scope>test</scope>
</dependency>
• Otherwise, we’ll get the following error
Tests run: 12, Failures: 0, Errors: 12, Skipped: 0, Time elapsed: 0.078 sec
<<< FAILURE!
testCreate(ejava.examples.dao.jpa.JPAAuthorDAODemo) Time elapsed: 0.031 sec
<<< ERROR!
java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:60)
v120215
Java Persistence: EntityManager
40
Add Standard DB Properties
Enterprise
Java
• Identical to what was needed for JDBC
<profile> <!-- defines our default database -->
<id>hsql</id>
<activation>
<property> <!-- use this property to name another db -->
<name>jdbcdb</name>
<value>hsql</value>
</property>
</activation>
<properties>
<jdbc.driver>org.hsqldb.jdbcDriver</jdbc.driver>
<jdbc.url>jdbc:hsqldb:hsql://localhost:9001</jdbc.url>
<jdbc.user>sa</jdbc.user>
<jdbc.password />
<hibernate.dialect>org.hibernate.dialect.HSQLDialect
</hibernate.dialect>
</properties>
<dependencies>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.4</version>
<scope>test</scope>
</dependency>
v120215
Java Persistence: EntityManager
</dependencies>
</profile>
41
Enterprise
Java
Design Mechanism to Pass DB Properties
• Compile-time property filtering
– default values end up in .jar file; not ideal
– much less work; good for prototypes
– demonstrated here within JPA examples
• Runtime property passing
– more realistic
– more work
• could delegate details to a Test Utility Class
– demonstrated in JDBC examples
v120215
Java Persistence: EntityManager
42
Enterprise
Java
src/main/resources/META-INF/persistence.xml
<persistence ...>
<persistence-unit name="jpaDemo">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect"
value="${hibernate.dialect}"/>
<property name="hibernate.connection.url"
value="${jdbc.url}"/>
<property name="hibernate.connection.driver_class"
value="${jdbc.driver}"/>
<property name="hibernate.connection.password"
value="${jdbc.password}"/>
<property name="hibernate.connection.username"
value="${jdbc.user}"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false"/>
<!–- used in special cases
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.jdbc.batch_size" value=“0"/>
-->
</properties>
</persistence-unit>
</persistence>
v120215
Java Persistence: EntityManager
43
Enterprise
Java
src/test/resources/hibernate.properties
hibernate.dialecte=${hibernate.dialect}
hibernate.connection.url=${jdbc.url}
hibernate.connection.driver_class=${jdbc.driver}
hibernate.connection.password=${jdbc.password}
hibernate.connection.username=${jdbc.user}
#only use auto create for quick prototypes
#hibernate.hbm2ddl.auto=create
hibernate.show_sql=true
hibernate.format_sql=true
# eliminate batching to help debug DB errors
#hibernate.jdbc.batch_size=0
v120215
Java Persistence: EntityManager
44
Enterprise
Java
Add Resource Filtering Spec to pom.xml
• This overrides the default behavior of resource handling
<build>
<!--tell the resource plugin to perform filtering on resources
to fill in JDBC URL, etc. -->
<!–- if $vars in src/main/resources branch -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<!-- if $vars in src/test/resources branch
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
...
</build>
v120215
Java Persistence: EntityManager
45
target/classes/META-INF/persistence.xml
Enterprise
Java
<persistence ...>
<persistence-unit name="jpaDemo">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.url"
value="jdbc:hsqldb:hsql://localhost:9001"/>
<property name="hibernate.connection.driver_class"
value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.password"
value=""/>
<property name="hibernate.connection.username"
value="sa"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
v120215
Java Persistence: EntityManager
46
Enterprise
Java
target/test-classes/hibernate.properties
hibernate.dialecte=org.hibernate.dialect.HSQLDialect
hibernate.connection.url=jdbc:hsqldb:hsql://localhost:9001
hibernate.connection.driver_class=org.hsqldb.jdbcDriver
hibernate.connection.password=
hibernate.connection.username=sa
hibernate.hbm2ddl.auto=create
hibernate.show_sql=false
#hibernate.format_sql=true
#hibernate.jdbc.batch_size=0
v120215
Java Persistence: EntityManager
47
Setup JUnit TestCase
Enterprise
Java
import static org.junit.Assert.*;
import org.junit.*;
public class JPAAccountDAOTest {
@BeforeClass
public static void setUpClass() throws Exception { … }
@Before
public void setUp() throws Exception { … }
@After
public void tearDown() throws Exception { … }
@AfterClass
public static void tearDownClass() throws Exception { … }
@Test
public void testJPACreate() throws Exception { … }
@Test
public void testXXX() throws Exception { … }
v120215
Java Persistence: EntityManager
48
Enterprise
Java
Setup EntityManager within TestCase
public class JPAAccountDAOTest {
private static Log log = LogFactory.getLog(JPAAccountDAO.class);
private EntityManagerFactory emf;
private EntityManager em;
private AccountDAO dao;
@Before
public void setUp() throws Exception {
emf = Persistence.createEntityManagerFactory("eSalesBO");
em = emf.createEntityManager();
dao = new JPAAccountDAO();
((JPAAccountDAO)dao).setEntityManager(em);
cleanup(); //get env to a known state before starting tests
//may want in its own transaction
em.getTransaction().begin(); //optional
//have transaction started prior to test
}
v120215
Java Persistence: EntityManager
49
Teardown EntityManager within
TestCase
Enterprise
Java
@After
public void tearDown() throws Exception {
if (em != null) {
EntityTransaction tx = em.getTransaction();
if (tx.isActive()) {
if (tx.getRollbackOnly()) { tx.rollback(); }
else
{ tx.commit(); }
}
em.close();
}
if (emf != null) {
emf.close();
}
}
v120215
Java Persistence: EntityManager
50
(optional!)Potential Utiltity Class
Enterprise
Java
package ejava.examples.dao.jpa;
import
import
import
import
java.util.HashMap;
java.util.Map;
javax.persistence.EntityManagerFactory;
javax.persistence.Persistence;
public class JPAUtil {
private static final Map<String, EntityManagerFactory> factories =
new HashMap<String, EntityManagerFactory>();
public static EntityManagerFactory getEntityManagerFactory(String puName) {
EntityManagerFactory emf = factories.get(puName);
if (emf == null) {
synchronized(factories) {
emf = factories.get(puName);
if (emf == null) {
emf = Persistence.createEntityManagerFactory(puName);
factories.put(puName, emf);
}
}
}
return emf;
}
public static void close() {
synchronized(factories) {
for(String puName : factories.keySet()) {
factories.get(puName).close();
}
factories.clear();
}
}
}
v120215
Java Persistence: EntityManager
51
(optional!) Junit Test Suites
Enterprise
Java
• Supports the one-time startup or shutdown of components
public class AllTest extends TestCase {
private static Log log_ = LogFactory.getLog(AllTest.class);
public static Test suite() {
TestSuite tests = new TestSuite();
tests.addTestSuite(JPAAuthorDAODemo.class);
tests.addTestSuite(JPANoDAODemo.class);
TestSetup wrapper = new TestSetup(tests) {
//one-time setup
public void setUp() throws Exception {
}
//one-time tear down
public void tearDown() throws Exception {
JPAUtil.close();
}
};
}
v120215
return wrapper;
Java Persistence: EntityManager
52
JUnit Tests
Enterprise
Java
@Test
public void testJPACreate() throws Exception {
log.info("*** testJPACreate ***");
…
Account account = new Account(userId);
account.setFirstName(firstName);
account.getAddresses().add(new Address(0, "Shipping", "Laurel"));
account.getAddresses().add(new Address(0, "Billing", "Columbia"));
log.debug("instantiated Account:" + account);
dao.createAccount(account);
log.debug("dao created Account:" + account);
…
Account account2 = em.find(Account.class, userId);
assertNotNull(account2);
assertEquals("unexpected first name",
firstName, account2.getFirstName());
assertEquals("unexpected number of addresses",
account.getAddresses().size(), account2.getAddresses().size());
v120215
Java Persistence: EntityManager
53
Summary
•
•
•
•
•
•
•
Enterprise
Java
Java Persistence API
– Java standard for mapping objects to relational databases
– currently part of Java EE; will be in Java SE 6
– eliminates the need or desire for EJB 2.1 entity
Entity
– a POJO
– operates both detached and managed by OR Mapping
Persistence Unit
– a set of entity classes mapped to the database schema
Persistence Context
– a set of objects that managed
– Transaction-scoped or Extended
javax.persistence.EntityManager
– manages objects in a persistence context
javax.persistence.EntityManagerFactory
– used to create individual entity managers
javax.persistence.Persistence
– used to bootstrap EntityManagerFactory into Java SE applications
v120215
Java Persistence: EntityManager
54
References
Enterprise
Java
• “Enterprise JavaBeans 3.0, 5th Edition”; Burke &
Monsen-Haefel; ISBN 0-596-00978-X; O'Reilly
v120215
Java Persistence: EntityManager
55
Related documents