1 / 55

Java Persistence: EntityManager

Java Persistence: EntityManager. Goals. Become familiar with the Java Persistence API and EntityManager Become familiar with how to setup a project using JPA and a provider (Hibernate). Objectives. Provide an Overview of the Java Persistence API Go through Details of the EntityManager

callowaym
Télécharger la présentation

Java Persistence: EntityManager

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

E N D

Presentation Transcript


  1. Java Persistence: EntityManager Java Persistence: EntityManager

  2. Java Persistence: EntityManager Goals • Become familiar with the Java Persistence API and EntityManager • Become familiar with how to setup a project using JPA and a provider (Hibernate)

  3. Java Persistence: EntityManager Objectives • Provide an Overview of the Java Persistence API • Go through Details of the EntityManager • Go through some implementation details associated with class projects

  4. Java Persistence: EntityManager 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

  5. Java Persistence: EntityManager 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

  6. Java Persistence: EntityManager 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);

  7. Java Persistence: EntityManager Example Author POJO Entity 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. @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; } ... }

  8. Java Persistence: EntityManager 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

  9. Java Persistence: EntityManager 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

  10. Java Persistence: EntityManager 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

  11. Java Persistence: EntityManager 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

  12. Java Persistence: EntityManager 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)

  13. Java Persistence: EntityManager Example Component Layout META-INF/ +---persistence.xml ejava + ---examples +---… +---DAOException.class +---AuthorDAO.class +---jpa | +---JPAAuthorDAO.class +--bo +---Author.class

  14. Java Persistence: EntityManager 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

  15. Java Persistence: EntityManager 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

  16. Java Persistence: EntityManager Solution-specific property option: hibernate.properties $ 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

  17. Java Persistence: EntityManager 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

  18. Java Persistence: EntityManager 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

  19. Java Persistence: EntityManager 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>

  20. Java Persistence: EntityManager 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

  21. Java Persistence: EntityManager Java SE Steps • Startup • Get EntityManagerFactory • Runtime • Create EntityManager • Start Transaction • Interact with Entity Manager • Commit Transaction • Close EntityManager • Shutdown • Close EntityManagerFactory

  22. Java Persistence: EntityManager 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”);

  23. Java Persistence: EntityManager 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();

  24. Java Persistence: EntityManager 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); ...

  25. Java Persistence: EntityManager 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

  26. Java Persistence: EntityManager 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

  27. Java Persistence: EntityManager 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

  28. Java Persistence: EntityManager 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

  29. Java Persistence: EntityManager 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

  30. Java Persistence: EntityManager 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

  31. Java Persistence: EntityManager 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

  32. Java Persistence: EntityManager 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

  33. Java Persistence: EntityManager 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

  34. Java Persistence: EntityManager 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

  35. Java Persistence: EntityManager 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()

  36. Java Persistence: EntityManager 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()); }

  37. Java Persistence: EntityManager Implementation/Testing Details

  38. Java Persistence: EntityManager 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

  39. Java Persistence: EntityManager 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>

  40. Java Persistence: EntityManager 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)

  41. Java Persistence: EntityManager 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>

  42. Java Persistence: EntityManager 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

  43. Java Persistence: EntityManager 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>

  44. Java Persistence: EntityManager 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

  45. Java Persistence: EntityManager 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>

  46. Java Persistence: EntityManager 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>

  47. Java Persistence: EntityManager 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

  48. Java Persistence: EntityManager 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 { … }

  49. Java Persistence: EntityManager 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 }

  50. Java Persistence: EntityManager 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(); } }

More Related