Enterprise Java Development@TOPIC@

Chapter 38. JPA Overview

38.1. Background
38.2. EntityManager
38.3. Entity
38.4. JPA Example
38.5. Entity States
38.5.1. Managed
38.5.2. Detached
38.6. Persistence Context
38.7. Persistence Unit
38.8. Example Layout
38.9. Persistence.xml
38.9.1. Application Example
38.9.2. Server Example
38.9.3. Optional hibernate.properties
38.9.4. Sample orm.xml
38.9.5. persistence.xml Elements
38.9.6. Entity Discovery
38.10. Schema Generation
38.10.1. Hibernate DDL Generation Example
38.10.2. javax.persistence Schema Generation
38.11. Basic Testing Usage Steps
38.12. Entity Manager Methods
38.12.1. Basic CRUD Operations
38.12.2. Membership Operations
38.12.3. State Synchronization Operations
38.12.4. Locking Operations
38.12.5. Query Operations
38.12.6. Other Operations


Author author = new Author();
author.setFirstName("dr");
author.setLastName("seuss");
author.setSubject("children");
author.setPublishDate(new Date());
logger.debug("creating author: {}", author);
assertEquals("unexpected initialized id", 0, author.getId());
logger.debug("em.contains(author)={}", em.contains(author));
assertFalse("author managed", em.contains(author));
em.persist(author);
logger.debug("created author: {}", author);        
logger.debug("em.contains(author)={}", em.contains(author));
assertNotEquals("missing id", 0, author.getId());
assertTrue("author not managed", 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
|-- ejava
|   `-- examples
|       `-- daoex
|           |-- bo
|           |   `-- Author.class
|           |-- dao
|           |   |-- AuthorDAO.class
|           |   `-- DAOException.class
|           `-- jpa
|               `-- JPAAuthorDAO.class
`-- META-INF
    |-- orm.xml
    `-- persistence.xml

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
                      http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" 
  version="2.1">

    <persistence-unit name="jpaDemo">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</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.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>

The above example:


<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
                      http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
  version="2.1">

    <persistence-unit name="ejbsessionbank">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
        <jar-file>lib/info.ejava.examples.ejb-ejbsessionBankImpl-5.0.0-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>

The above example:

hibernate.hbm2ddl.auto

Controls hibernate schema generation

create, drop, create-drop, update, validate, and none

hibernate.hbm2ddl.import_files

Allows for self-authored files to be used as well

  • Expressed thru hibernate.properties using hibernate.hbm2ddl properties

    hibernate.hbm2ddl.auto=create-drop
    
    
    hibernate.hbm2ddl.import_files=/ddl/mydb-tuningdrop.ddl,/ddl/mydb-tuning.ddl
    hibernate.connection.url=${jdbc.url}
    hibernate.connection.driver_class=${jdbc.driver}
    hibernate.connection.username=${jdbc.user}
    hibernate.connection.password=${jdbc.password}
    #hibernate.show_sql=true
    #hibernate.format_sql=true
  • Can be expressed thru persistence.xml but use standard properties instead to avoid confusion

javax.persistence.schema-generation.database.action

Values: drop-and-create, drop, create, none

javax.persistence.schema-generation.create-source

Values: metadata (default), script, metadata-then-script, script-then-metadata

javax.persistence.schema-generation.create-script-source - provides reference to create source

javax.persistence.schema-generation.drop-script-source - provides reference to drop source

javax.persistence.sql-load-script-source

Provides reference to script to execute after schema initialized

Useful in Pre-populating sample database tables with content

  • Database schema generation example

    
    <persistence-unit name="jpa-schemagen-test">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
            
            <!-- a database connection definition is required for database actions -->
            <property name="javax.persistence.jdbc.url" value="${jdbc.url}"/>
            <property name="javax.persistence.jdbc.driver" value="${jdbc.driver}"/>
            <property name="javax.persistence.jdbc.user" value="${jdbc.user}"/>
            <property name="javax.persistence.jdbc.password" value="${jdbc.password}"/>
        </properties>
    </persistence-unit>
  • Script schema generation example

    
    <persistence-unit name="jpa-schemagen-test">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <!-- a script file containing create and drop commands will be generated without interacting with database --> 
            <property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/>
            <property name="javax.persistence.schema-generation.scripts.create-target" value="${project.build.outputDirectory}/ddl/${project.artifactId}-create.ddl"/>
            <property name="javax.persistence.schema-generation.scripts.drop-target" value="${project.build.outputDirectory}/ddl/${project.artifactId}-drop.ddl"/>

            <!-- otherwise we would get 1 line per statement without standard delimiter character -->
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.hbm2ddl.delimiter" value=";"/>
            <!-- required when no database connection specified -->
            <property name="hibernate.dialect" value="${hibernate.dialect}"/>
        </properties>    
    </persistence-unit>
    • Scripts written to target files

      target/classes/ddl/
      |-- jpa-schemagen-create.ddl
      `-- jpa-schemagen-drop.ddl
      
    • Create script contains commands to create schema

      create sequence hibernate_sequence start with 1 increment by 1;
      
      
      create table JPAUTIL_TABLET (
         id integer not null,
          maker varchar(255),
          primary key (id)
      );
    • Drop script contains commands to drop schema

      drop table JPAUTIL_TABLET if exists;
      
      
      drop sequence if exists hibernate_sequence;
public interface javax.persistence.EntityManager{
...
}