Enterprise Java Development@TOPIC@
Built on: 2014-03-06 23:58 EST
Copyright © 2014 jim stafford (jcstaff@apl.jhu.edu)
Abstract
This presentation provides and introduction to JPA and coverage of the methods of the EntityManager.
At the completion of this topic, the student shall
have an understanding of:
Requirements for entity classes
How to define a persistence unit
How to obtain an entity manager
Persistence methods available from EntityManager
be able to:
Define a Java class as an entity
Define a persistence unit with entity class(es)
Implement DAO operations in terms of javax.persistence.Persistence API
Earlier versions of EJB Spec defined persistence as part of javax.ejb.EntityBean
JavaEE 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 (JPA-QL) - SQL-like - main carryover from EJB 2.x
JavaEE 6 advanced specification
Java Persistence API (JPA) version 2.0
More mapping capabilities
More entity manager capabilities
Standardization of properties
Criteria API
Replaced EJB 2.x Home Functionality
Handles O/R Mapping to the database
Provides APIs for
Inserting into database
Updating entities in database
Finding and querying for entities in database
Removing entities from database
Provides caching
Integrates with JTA transactions
Tightly integrated with JavaEE and EJB, but not coupled to it
Plain Old Java Objects (POJOs)
Nothing special happens when calling new()
Author author = new Author();
From JPA perspective the above is a new/unmanaged entity
Persistent when associated with an entity manager/persistence context
em.persist(author);
@javax.persistence.Entity
public class Author implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private long id;
private long version=0;
private String firstName;
private String lastName;
private String subject;
private Date publishDate;
public Author() {
}
...
}
Entity minimum requirements:
Annotated as entity or declared in orm.xml
Unique identity (form primary key(s))
Non-private default constructor
Author author = new Author();
author.setFirstName("dr");
author.setLastName("seuss");
author.setSubject("children");
author.setPublishDate(new Date());
log.debug("creating author:" + author);
assertFalse("unexpected initialized id", author.getId() > 0);
log.debug("em.contains(author)=" + em.contains(author));
em.persist(author);
log.debug("created author:" + author);
assertTrue("missing id", author.getId() > 0);
log.debug("em.contains(author)=" + em.contains(author));
-creating author:ejava.examples.daoex.bo.Author@1d8e9e, id=0,
fn=dr, ln=seuss, subject=children, pdate=Mon Sep 17 00:22:25 EDT 2012, version=0
-em.contains(author)=false
-created author:ejava.examples.daoex.bo.Author@1d8e9e, id=50,
fn=dr, ln=seuss, subject=children, pdate=Mon Sep 17 00:22:25 EDT 2012, version=0
-em.contains(author)=true
Associated with persistence context
Has identity
Changes to the entity will impact the database
Method em.contains(entity) returns true
Has identity but not associated with persistence context
Changes to entity will not impact the database
Method em.contains(entity) returns false
An entity becomes detached when:
Has not yet been persisted
After a transaction-scoped transaction is committed
After a transaction rollback
Manually detaching entity from persistence context thru em.detach()
Manually clearing the persistence context thru em.clear()
Closing EntityManager
Serializing entity thru a remote interface
A set of managed instances managed by an EntityManager
All entities become detached once closed
Two types:
Extended
Author author = new Author();
...
em.persist(author);
em.getTransaction().begin();
em.getTransaction().commit();
author.setFirstName("foo");
em.getTransaction().begin();
em.getTransaction().commit();
em.getTransaction().begin();
author.setFirstName("bar");
em.getTransaction().commit();
Live beyond a single transaction
Allow long-lived algorithms to process without tying up a database transaction
Transaction-Scoped
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Author createAuthor(...) {
Author author = new Author();
...
em.persist(author);
return author;
}
Begin/end at transaction boundaries
Injected by containers
A set of classes that are mapped to the database
Defined in META-INF/persistence.xml
Entity classes may be named in persistence.xml or searched for
Entity mapping may be provided, augmented, or overridden with orm.xml mapping file
|-- ejava
| `-- examples
| `-- daoex
| |-- AuthorDAO.class
| |-- bo
| | `-- Author.class
| |-- DAOException.class
| `-- jpa
| `-- JPAAuthorDAO.class
`-- META-INF
|-- orm.xml
`-- 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_2_0.xsd"
version="2.0">
<persistence-unit name="jpaDemo">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>META-INF/orm.xml</mapping-file>
<properties>
<!-- standard properties -->
<property name="javax.persistence.jdbc.url" value="jdbc:h2:./target/h2db/ejava"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<!-- hibernate-specific properties -->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<!-- set to 0 to improve error messages when needed
<property name="hibernate.jdbc.batch_size" value="0"/>
-->
</properties>
</persistence-unit>
</persistence>
Above example defines properties for entity manager to establish physical connections to database
<?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_2_0.xsd"
version="2.0">
<persistence-unit name="ejbsessionbank">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
<jar-file>lib/ejbsessionBankImpl-3.0.2012.2-SNAPSHOT.jar</jar-file>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.show_sql" value="false"/>
<!-- create is used here for demo project only -->
<property name="hibernate.hbm2ddl.auto" value="create"/>
<!--
<property name="hibernate.jdbc.batch_size" value="0"/>
-->
</properties>
</persistence-unit>
</persistence>
Above example used DataSource from JNDI tree to obtain connections to database
Can be used to specify connection properties outside of persistence.xml
Useful in separating production mapping information from runtime connection properties
#hibernate-specific alternate source of persistence.xml properties
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.connection.url=jdbc:h2:./target/h2db/ejava
hibernate.connection.driver_class=org.h2.Driver
hibernate.connection.password=
hibernate.connection.username=sa
hibernate.hbm2ddl.auto=create
hibernate.show_sql=true
hibernate.format_sql=true
#hibernate.jdbc.batch_size=0
<?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_2_0.xsd"
version="2.0">
<entity class="ejava.examples.daoex.bo.Author"
access="FIELD"
metadata-complete="false"
name="jpaAuthor">
<table name="DAO_AUTHOR"/>
<attributes>
<id name="id">
<generated-value strategy="SEQUENCE"
generator="AUTHOR_SEQUENCE"/>
</id>
</attributes>
</entity>
</entity-mappings>
nameIdentity used to reference persistence unit
providerFully qualified name of javax.persistence.PersistenceProvider
Not needed if provider is in classpath
mapping-filePath reference to an orm.xml mapping file
jta-data-sourceJNDI path of a JTA javax.sql.DataSource
non-jta-datasourceJNDI path of a RESOURCE_LOCAL javax.sql.DataSource
jarfileReference to an archive with entity classes
classFully qualified package name of entity class
One source of entity information
exclude-unlisted-classesIf set, provider will not scan to discover entity classes
propertiesname/value property pairs to express additional configuration info
setUp
Create EntityManagerFactory
public class javax.persistence.Persistence extends java.lang.Object{
public static javax.persistence.EntityManagerFactory createEntityManagerFactory(java.lang.String);
public static javax.persistence.EntityManagerFactory createEntityManagerFactory(java.lang.String, java.util.Map);
...
}
private static EntityManagerFactory emf;
@BeforeClass
public static void setUpClass() {
emf = Persistence.createEntityManagerFactory("jpaDemo");
Create EntityManager
public interface javax.persistence.EntityManagerFactory{
public abstract javax.persistence.EntityManager createEntityManager();
public abstract javax.persistence.EntityManager createEntityManager(java.util.Map);
...
}
private EntityManager em;
@Before
public void setUp() throws Exception {
em = emf.createEntityManager();
Runtime
Start Transaction
em.getTransaction().begin();
Interact with EntityManager
em.persist(author);
Commit Transaction
em.getTransaction().commit();
tearDown
Close EntityManager
@After
public void tearDown() throws Exception {
try {
if (em != null) {
if (!em.getTransaction().isActive()) {
em.getTransaction().begin();
em.getTransaction().commit();
}
else if (!em.getTransaction().getRollbackOnly()) {
em.getTransaction().commit();
}
else {
em.getTransaction().rollback();
}
}
}
finally {
if (em != null) { em.close(); em=null;}
}
Close EntityManagerFactory
@AfterClass
public static void tearDownClass() {
if (emf != null) {
emf.close();
emf=null;
}
}
public interface javax.persistence.EntityManager{
...
}
void persist(Object entity);
<T> T find(Class<T> entityClass, Object primaryKey);
<T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties);
<T> T merge(T entity);
void remove(Object entity);
<T> T getReference(Class<T> entityClass, Object primaryKey);
void clear();
void detach(Object entity);
boolean contains(Object entity);
void flush();
void setFlushMode(javax.persistence.FlushModeType);
javax.persistence.FlushModeType getFlushMode();
void refresh(Object);
void refresh(Object, java.util.Map);
void lock(Object entity, javax.persistence.LockModeType);
void lock(Object entity, javax.persistence.LockModeType, Map<String, Object> properties);
<T> T find(Class<T> entityClass, Object primaryKey, javax.persistence.LockModeType);
<T> T find(Class<T> entityClass, Object primaryKey, javax.persistence.LockModeType, Map<String, Object> properties);
void refresh(Object, javax.persistence.LockModeType);
void refresh(Object, javax.persistence.LockModeType, Map<String, Object> properties);
javax.persistence.LockModeType getLockMode(Object entity);
javax.persistence.Query createQuery(String jpaql);
<T> javax.persistence.TypedQuery<T> createQuery(String jpaql, Class<T> resultClass);
javax.persistence.Query createNamedQuery(String name);
<T> javax.persistence.TypedQuery<T> createNamedQuery(String name, Class<T> resultClass);
javax.persistence.Query createNativeQuery(String sql);
javax.persistence.Query createNativeQuery(String sql, Class resultClass);
javax.persistence.Query createNativeQuery(String sql, String resultMapping);
<T> javax.persistence.TypedQuery<T> createQuery(javax.persistence.criteria.CriteriaQuery<T> criteria);
javax.persistence.criteria.CriteriaBuilder getCriteriaBuilder();
void close();
boolean isOpen();
javax.persistence.EntityTransaction getTransaction();
void joinTransaction();
void setProperty(String key, Object value);
java.util.Map getProperties();
<T> T unwrap(Class<T> clazz);
Object getDelegate();
javax.persistence.metamodel.Metamodel getMetamodel();
javax.persistence.EntityManagerFactory getEntityManagerFactory();
Author author = new Author();
author.setFirstName("dr");
author.setLastName("seuss");
author.setSubject("children");
author.setPublishDate(new Date());
log.debug("creating author:" + author);
em.persist(author);
log.debug("created author:" + author);
-creating author:ejava.examples.daoex.bo.Author@17e7691, id=0, fn=dr, ln=seuss, subject=children, pdate=Sun Sep 16 10:14:32 EDT 2012, version=0 -created author:ejava.examples.daoex.bo.Author@17e7691, id=50, fn=dr, ln=seuss, subject=children, pdate=Sun Sep 16 10:14:32 EDT 2012, version=0
Inserts entity into database
Actual insert time depends on transaction active and FlushMode
Extended Persistence Context - queues insert until transaction active
Transaction-Scoped Persistence Context - always has transaction active
Flush occurs automatically prior to or during commit()
Flush can be forced with manual em.flush() call
New or removed entity enters managed state
All further changes are watched and will update database
log.debug("em.contains(author)=" + em.contains(author));
em.persist(author);
log.debug("created author:" + author);
log.debug("em.contains(author)=" + em.contains(author));
-em.contains(author)=false -created author:... -em.contains(author)=true
Existing entity is ignored
Cascades will still occur for CascadeType.PERSIST and ALL relationships
em.persist(author);
...
em.persist(author);
Detached entities will be rejected
Entities with an identity but not associated with a persistence context
Author author = new Author(1);
author.setFirstName("dr");
...
log.debug("creating author:" + author);
log.debug("em.contains(author)=" + em.contains(author));
try {
em.persist(author);
fail("did not detect detached entity");
} catch (PersistenceException ex) {
log.debug("caught expected exception:" + ex.getLocalizedMessage(), ex);
}
log.debug("em.contains(author)=" + em.contains(author));
-creating author:ejava.examples.daoex.bo.Author@ad339b, id=1, ...
-em.contains(author)=false
-caught expected exception:javax.persistence.PersistenceException: org.hibernate.PersistentObjectException:
detached entity passed to persist: ejava.examples.daoex.bo.Author
-em.contains(author)=false
<T> T find(Class<T> entityClass, Object primaryKey);
<T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties);
Searches for the entity by primary key value
Returns managed entity if found, else null
Properties permitted for vendor-specific values and ignored if not understood
<T> T getReference(Class<T> entityClass, Object primaryKey);
Searches for the entity by primary key
Returns a LAZY load reference if found
Throws EntityNotFoundException if not exist
//create initial author
Author author = new Author();
...
em.persist(author);
//create detached author with changes
Author author2 = new Author(author.getId());
author2.setFirstName("updated " + author.getFirstName());
...
//merge changes
Author tmp = em.merge(author2);
em.getTransaction().begin();
em.getTransaction().commit();
...
//verify results
assertFalse("author2 is managed", em.contains(author2));
assertTrue("tmp Author is not managed", em.contains(tmp));
assertSame("merged result not existing managed", author, tmp);
...
//verify changes were made to the DB
Author author3 = em.find(Author.class, author.getId());
assertEquals("updated " + firstName, author3.getFirstName());
Update database with state of detached object
State of detached object copied into managed entity or new instance created
Merging a managed entity is ignored. CascadeType.MERGE and ALL relationships are propagated
Merging a removed entity instance results in an IllegalArgumentException
Includes automatic checking of @Version property
Could be replaced with manual merge
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;
}
The above manual merge will successfully merge a transient entity -- but what errors and conditions does it not account for?
void remove(Object entity);
Managed entity is removed from database
Actual delete time depends on transaction active and FlushMode
Extended Persistence Context - queues delete until transaction active
New entities are ignored but CascadeType.REMOVE and ALL relationships are cascaded
log.debug("em.contains(author)=" + em.contains(author));
em.remove(author);
log.debug("em.contains(author)=" + em.contains(author));
-em.contains(author)=false -HHH000114: Handling transient entity in delete processing -em.contains(author)=false
Detached entities are rejected
Author author = new Author(1);
...
try {
em.remove(author);
fail("did not reject removal of detached object");
} catch (IllegalArgumentException ex) {
log.debug("caught expected exception:" + ex);
}
-caught expected exception:java.lang.IllegalArgumentException:
Removing a detached instance ejava.examples.daoex.bo.Author#1
Removed entities are ignored
Author author = new Author();
...
log.debug("peristed:" + author);
log.debug("em.contains(author)=" + em.contains(author));
em.remove(author);
log.debug("em.contains(author)=" + em.contains(author));
//entity managers will ignore the removal of a removed entity
em.remove(author);
log.debug("em.contains(author)=" + em.contains(author));
-peristed:ejava.examples.daoex.bo.Author@6c5356, id=50, ... -em.contains(author)=true -em.contains(author)=false -em.contains(author)=false
boolean contains(Object entity);
Returns true if object is managed in the persistence context
void clear();
Clears all entities and queued changes from the persistence context
All entities become detached
em.persist(author);
//callers can detach entity from persistence context
log.debug("em.contains(author)="+em.contains(author));
log.debug("detaching author");
em.getTransaction().begin();
em.flush();
em.detach(author);
log.debug("em.contains(author)="+em.contains(author));
em.getTransaction().commit();
//changes to detached entities do not change database
author.setFirstName("foo");
em.getTransaction().begin();
em.getTransaction().commit();
Author author2 = em.find(Author.class, author.getId());
log.debug("author.firstName=" + author.getFirstName());
log.debug("author2.firstName=" + author2.getFirstName());
assertFalse("unexpected name change",
author.getFirstName().equals(author2.getFirstName()));
-em.contains(author)=true -detaching author -em.contains(author)=false -author.firstName=foo -author2.firstName=dr
Detaches existing entity from persistence context
Detach cascaded to CascadeType.DETACH and ALL relationships
Subsequent changes to entity will not change database
Portable use requires call to flush() prior to detach()
New entities are ignored
Author author = new Author();
log.debug("em.contains(author)="+em.contains(author));
log.debug("detaching author");
em.detach(author);
log.debug("em.contains(author)="+em.contains(author));
-em.contains(author)=false -detaching author -em.contains(author)=false
Detached entities are ignored
Author author = new Author();
...
em.persist(author);
em.getTransaction().begin();
em.getTransaction().commit();
//detaching detached entity will be ignored
Author detached = new Author(author.getId());
log.debug("em.contains(author)="+em.contains(detached));
log.debug("detaching detached author");
em.detach(detached);
log.debug("em.contains(author)="+em.contains(detached));
-em.contains(author)=false -detaching detached author -em.contains(author)=false
void flush();
Synchronizes cached changes with underlying database
Requires active transaction
void setFlushMode(javax.persistence.FlushModeType);
javax.persistence.FlushModeType getFlushMode();
AUTO (default) - unspecified
COMMIT - flush only happens during commit
em.persist(author);
em.getTransaction().begin();
em.getTransaction().commit();
//change DB state out-of-band from the cache
em.getTransaction().begin();
String newName="foo";
int count=em.createQuery(
"update jpaAuthor a set a.firstName=:name where a.id=:id")
.setParameter("id", author.getId())
.setParameter("name", newName)
.executeUpdate();
em.getTransaction().commit();
assertEquals("unexpected count", 1, count);
//object state becomes stale when DB changed out-of-band
log.debug("author.firstName=" + author.getFirstName());
assertFalse("unexpected name", author.getFirstName().equals(newName));
//get the cached object back in sync
log.debug("calling refresh");
em.refresh(author);
log.debug("author.firstName=" + author.getFirstName());
assertEquals("unexpected name", newName, author.getFirstName());
-author.firstName=dr
-calling refresh
-author.firstName=foo
Updates/overwrites cached entity state with database state
Refresh of new entity results in java.lang.IllegalArgumentException
Author author = new Author();
author.setFirstName("test");
author.setLastName("new");
try {
em.refresh(author);
fail("refresh of new entity not detected");
} catch (IllegalArgumentException ex) {
log.debug("caught expected exception:" + ex);
}
-caught expected exception:java.lang.IllegalArgumentException: Entity not managed
Refresh of detached entity results in java.lang.IllegalArgumentException
em.persist(author);
em.getTransaction().begin();
em.getTransaction().commit();
//refreshing a detached entity will get rejected
Author detached = new Author(author.getId());
em.refresh(author);
log.debug("refreshed managed entity");
try {
em.refresh(detached);
fail("refresh of detached entity not detected");
} catch (IllegalArgumentException ex) {
log.debug("caught expected exception:" + ex);
}
-refreshed managed entity -caught expected exception:java.lang.IllegalArgumentException: Entity not managed
Optimistic
Entity assumed not to have concurrent access
No active database locks are obtained at start
Success judged based on entity state at end
State tracked in entity @Version field
Pessimistic
Entity requires mitigation for concurrent access
Active database locks are obtained at start of transaction
NONE
No locks
OPTIMISTIC (was READ)
Requires entity to have a @Version property
Prevent dirty reads
Prevent non-repeatable reads
OPTIMISTIC_FORCE_INCREMENT (was WRITE)
Requires entity to have a @Version property
Update only occurs if change has proper version
Version is incremented upon update
Incorrect version results in OptimisticLockException
PESSIMISTIC_READ
Supported with or without @Version property
Obtains active database lock
Provides repeatable reads
Does not block other reads
PESSIMISTIC_WRITE
Supported with or without @Version property
Forces serialization of entity updates among transactions
PESSIMISTIC_FORCE_INCREMENT
Requires entity to have a @Version property
PESSIMISTIC_WRITE lock with increment of @Version
void lock(Object entity, javax.persistence.LockModeType);
void lock(Object entity, javax.persistence.LockModeType, Map<String, Object> properties);
Requests lock on entity
<T> T find(Class<T> entityClass, Object primaryKey, javax.persistence.LockModeType);
<T> T find(Class<T> entityClass, Object primaryKey, javax.persistence.LockModeType, Map<String, Object> properties);
Find object by primary key and lock
void refresh(Object, javax.persistence.LockModeType);
void refresh(Object, javax.persistence.LockModeType, Map<String, Object> properties);
Refresh entity state and obtain lock
javax.persistence.Query createQuery(String jpaql);
<T> javax.persistence.TypedQuery<T> createQuery(String jpaql, Class<T> resultClass);
javax.persistence.Query createNamedQuery(String name);
<T> javax.persistence.TypedQuery<T> createNamedQuery(String name, Class<T> resultClass);
Create query based on JPA Query Language (JPAQL)
javax.persistence.Query createNativeQuery(String sql);
javax.persistence.Query createNativeQuery(String sql, Class resultClass);
javax.persistence.Query createNativeQuery(String sql, String resultMapping);
Create query based on SQL
javax.persistence.EntityTransaction getTransaction();
Returns transaction object for inspection and control
Invalid call for transaction-scoped persistence contexts
void joinTransaction();
Associate a persistence context with a JTA transaction
<T> T unwrap(Class<T> clazz);
Return object of specified type
Provides access to underlying implementation classes
javax.persistence.metamodel.Metamodel getMetamodel();
Returns metamodel object for persistence context
javax.persistence.EntityManagerFactory getEntityManagerFactory();
Returns EntityManagerFactory associated with EntityManager
src
|-- main
| |-- java
| | `-- ejava
| | `-- examples
| | `-- daoex
| | |-- AuthorDAO.java
| | |-- bo
| | | `-- Author.java
| | |-- DAOException.java
| | `-- jpa
| | `-- JPAAuthorDAO.java
| `-- resources
| `-- META-INF
| |-- orm.xml
| `-- persistence.xml (could be placed in src/test branch)
`-- test
|-- java
| `-- ejava
| `-- examples
| `-- daoex
| `-- jpa
| |-- JPAAuthorDAOTest.java
| |-- JPACRUDTest.java
| `-- JPATestBase.java
`-- resources
|-- hibernate.properties (optional)
`-- log4j.xml
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.0.1.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
...
</build>
Above will depend on whether you use src/main or src/test for resource file(s)
<properties>
<!-- standard properties -->
<property name="javax.persistence.jdbc.url" value="jdbc:h2:/home/jenkins/workspace/javaee-class-deploy/jpa/jpa-entitymgr/jpa-entitymgr-docbook/target/h2db/ejava"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<!-- hibernate-specific properties -->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
...
</properties>
<properties>
<jdbc.driver>org.h2.Driver</jdbc.driver>
<jdbc.url>jdbc:h2:/home/jenkins/workspace/javaee-class-deploy/jpa/jpa-entitymgr/jpa-entitymgr-docbook/target/h2db/ejava</jdbc.url>
<jdbc.user>sa</jdbc.user>
<jdbc.password/>
<hibernate.dialect>
org.hibernate.dialect.H2Dialect
</hibernate.dialect>
</properties>
<properties>
<!-- standard properties -->
<property name="javax.persistence.jdbc.url" value="jdbc:h2:/home/jcstaff/proj/ejava-javaee/git/jpaDAO/target/h2db/ejava"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<!-- hibernate-specific properties -->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
...
</properties>