slides - JHU Distributed Computing Home Page (webdev.apl.jhu.edu)

streakconvertingΛογισμικό & κατασκευή λογ/κού

13 Δεκ 2013 (πριν από 3 χρόνια και 8 μήνες)

81 εμφανίσεις

Enterprise

Java

v120215

Java Persistence: EntityManager

1

Java Persistence:


EntityManager

Enterprise

Java

v120215

Java Persistence: EntityManager

2

Goals


Become familiar with the Java Persistence API and
EntityManager


Become familiar with how to setup a project using JPA
and a provider (Hibernate)

Enterprise

Java

v120215

Java Persistence: EntityManager

3

Objectives


Provide an Overview of the Java Persistence API


Go through Details of the EntityManager


Go through some implementation details associated
with class projects

Enterprise

Java

v120215

Java Persistence: EntityManager

4

Overview


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

Enterprise

Java

v120215

Java Persistence: EntityManager

5

javax.persistence.EntityManager


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

Enterprise

Java

v120215

Java Persistence: EntityManager

6

Entities


(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);

Enterprise

Java

v120215

Java Persistence: EntityManager

7

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;




public Author() {}


public Author(long id) { this.id = id; }




@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;


}

...

}


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.

Enterprise

Java

v120215

Java Persistence: EntityManager

8

Creating Entity in Database

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, ln=seuss, subject=children,

pdate=Fri Sep 15 11:54:15 EDT 2006

-
created author:
id=50
, fn=dr, ln=seuss, subject=children,

pdate=Fri Sep 15 11:54:15 EDT 2006


Enterprise

Java

v120215

Java Persistence: EntityManager

9

Managed and Unmanaged Entities


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

Enterprise

Java

v120215

Java Persistence: EntityManager

10

Persistence Context


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

Enterprise

Java

v120215

Java Persistence: EntityManager

11

Persistence Context Examples


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

Enterprise

Java

v120215

Java Persistence: EntityManager

12

Persistence Unit


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)

Enterprise

Java

v120215

Java Persistence: EntityManager

13

Example Component Layout

META
-
INF/


+
---
persistence.xml

ejava


+
---
examples


+
---



+
---
DAOException.class


+
---
AuthorDAO.class


+
---
jpa


| +
---
JPAAuthorDAO.class


+
--
bo


+
---
Author.class


Enterprise

Java

v120215

Java Persistence: EntityManager

14

Example persistence.xml

<?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">









<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>


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



vendor
-
specific way to configure

persistence provider

Enterprise

Java

v120215

Java Persistence: EntityManager

15

Another Example persistence.xml

<?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

Enterprise

Java

v120215

Java Persistence: EntityManager

16

Solution
-
specific property option:
hibernate.properties


Easier to provide unit testing options that do
not get propagated into production artifacts

$ 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

Enterprise

Java

v120215

Java Persistence: EntityManager

17

persistence.xml elements


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

Enterprise

Java

v120215

Java Persistence: EntityManager

18

Specifying an optional orm.xml file

<?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

Enterprise

Java

v120215

Java Persistence: EntityManager

19

Optional orm.xml overrides

<?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>


Enterprise

Java

v120215

Java Persistence: EntityManager

20

Entities Discovered


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

Enterprise

Java

v120215

Java Persistence: EntityManager

21

Java SE Steps


Startup


Get EntityManagerFactory


Runtime


Create EntityManager


Start Transaction


Interact with Entity Manager


Commit Transaction


Close EntityManager


Shutdown


Close EntityManagerFactory

Enterprise

Java

v120215

Java Persistence: EntityManager

22

javax.persistence.Persistence


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”);

Enterprise

Java

v120215

Java Persistence: EntityManager

23

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();

Enterprise

Java

v120215

Java Persistence: EntityManager

24

javax.persistence.EntityManager

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 createQuery(java.lang.String);


Query createNamedQuery(java.lang.String);


Query createNativeQuery(java.lang.String);


Query createNativeQuery(java.lang.String, java.lang.Class);


Query createNativeQuery(java.lang.String, java.lang.String);


...



Enterprise

Java

v120215

Java Persistence: EntityManager

25

persist()

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

Enterprise

Java

v120215

Java Persistence: EntityManager

26

find()

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

Enterprise

Java

v120215

Java Persistence: EntityManager

27

getReference()

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

Enterprise

Java

v120215

Java Persistence: EntityManager

28

createQuery()


5 createQuery() methods

Query createQuery(String ejbqlString);

Query createNamedQuery(String name);

Query createNativeQuery(String sqlString);

Query createNativeQuery(String sqlString, Class resultClass);

Query 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

Enterprise

Java

v120215

Java Persistence: EntityManager

29

updating entities


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

Enterprise

Java

v120215

Java Persistence: EntityManager

30

merge()


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



Enterprise

Java

v120215

Java Persistence: EntityManager

31

remove()

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

Enterprise

Java

v120215

Java Persistence: EntityManager

32

refresh() and contains()


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

Enterprise

Java

v120215

Java Persistence: EntityManager

33

clear() and flush()


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

Enterprise

Java

v120215

Java Persistence: EntityManager

34

lock() and getDelegate()


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

Enterprise

Java

v120215

Java Persistence: EntityManager

35

EntityTransactions


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()

Enterprise

Java

v120215

Java Persistence: EntityManager

36

Example


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();




assertNotNull(author2);


assertEquals(author.getFirstName(), author2.getFirstName());


assertEquals(author.getLastName(), author2.getLastName());


assertEquals(author.getSubject(), author2.getSubject());


assertEquals(author.getPublishDate(), author2.getPublishDate());


}


Enterprise

Java

v120215

Java Persistence: EntityManager

37

Implementation/Testing Details

Enterprise

Java

v120215

Java Persistence: EntityManager

38

Add JPA Dependencies


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


Enterprise

Java

v120215

Java Persistence: EntityManager

39

Add Provider Dependencies


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 hibernate
-
entitymanager's pom.xml


<dependency>


<groupId>org.hibernate</groupId>


<artifactId>hibernate
-
entitymanager</artifactId>


<version>3.6.0.Final</version>


<scope>test</scope>


</dependency>

Enterprise

Java

v120215

Java Persistence: EntityManager

40

Add Dependency Overrides


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)


Enterprise

Java

v120215

Java Persistence: EntityManager

41

Add Standard DB Properties


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>


</dependencies>


</profile>

Enterprise

Java

v120215

Java Persistence: EntityManager

42

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

Enterprise

Java

v120215

Java Persistence: EntityManager

43

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>

Enterprise

Java

v120215

Java Persistence: EntityManager

44

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

Enterprise

Java

v120215

Java Persistence: EntityManager

45

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>

Enterprise

Java

v120215

Java Persistence: EntityManager

46

target/classes/META
-
INF/persistence.xml

<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>

Enterprise

Java

v120215

Java Persistence: EntityManager

47

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

Enterprise

Java

v120215

Java Persistence: EntityManager

48

Setup JUnit TestCase

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 { … }


Enterprise

Java

v120215

Java Persistence: EntityManager

49

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


}


Enterprise

Java

v120215

Java Persistence: EntityManager

50

Teardown EntityManager within
TestCase


@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();



}


}



Enterprise

Java

v120215

Java Persistence: EntityManager

51

(optional!)Potential Utiltity Class

package ejava.examples.dao.jpa;


import java.util.HashMap;

import java.util.Map;

import javax.persistence.EntityManagerFactory;

import 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();


}


}

}

Enterprise

Java

v120215

Java Persistence: EntityManager

52

(optional!) Junit Test Suites



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();


}


};




return wrapper;


}



Enterprise

Java

v120215

Java Persistence: EntityManager

53

JUnit Tests

@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());

Enterprise

Java

v120215

Java Persistence: EntityManager

54

Summary


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

Enterprise

Java

v120215

Java Persistence: EntityManager

55

References


“Enterprise JavaBeans 3.0, 5
th

Edition”; Burke &
Monsen
-
Haefel; ISBN 0
-
596
-
00978
-
X; O'Reilly