General | Wednesday, November 21, 2012

JPA 2.1 Schema Generation (TOTD #187)

UPDATED: May 24, 2012



JPA 2.1 specification is now final and can be download href="http://jcp.org/aboutJava/communityprocess/final/jsr338/index.html">from
here. The Reference Implementation is integrated in href="http://dlc.sun.com.edgesuite.net/glassfish/4.0/promoted/glassfish-4.0-b89.zip">GlassFish
4 Promoted Builds (soon to be final). The Schema Generation
property names have changed since the blog was originally published
and is now updated in the table below.



Blog from Nov 11, 2012



This blog explained
some of the href="https://blogs.oracle.com/arungupta/entry/jpa_2_1_early_draft">key
features
of JPA 2.1 earlier. Since then Schema Generation has been
added to JPA 2.1. This Tip Of The Day
(TOTD)
will provide more details about this new feature in JPA 2.1.



Schema Generation refers to generation of database artifacts like
tables, indexes, and constraints in a database schema. It may or may
not involve generation of a proper database schema depending upon
the credentials and authorization of the user. This helps in
prototyping of your application where the required artifacts are
generated either prior to application deployment or as part of
EntityManagerFactory creation. This is also useful in environments
that require provisioning database on demand, e.g. in a cloud.



This feature will allow your JPA domain object model to be directly
generated in a database. The generated schema may need to be tuned
for actual production environment. This usecase is supported by
allowing the schema generation to occur into DDL scripts which can
then be further tuned by a DBA.



The following set of properties in persistence.xml or specified
during EntityManagerFactory creation controls the behaviour of
schema generation.
























































Property Name

Purpose

Values

javax.persistence.schema-generation.database.action

Specifies the action to be taken by the
persistence provider with regard to the database artifacts

Per.book
"none", "create", "drop-and-create", "drop"

javax.persistence.schema-generation.scripts.action

Specifies which scripts are to be generated
by the persistence provider
Per.book
"none", "create", "drop-and-create", "drop"

javax.persistence.schema-generation.create-source

javax.persistence.schema-generation.drop-source
Specifies whether the creation/dropping of
database artifacts is to occur on the basis of the
object/relational mapping metadata, DDL script, or a
combination of the two.

"metadata", "script", "metadata-then-script",
"script-then-metadata"

javax.persistence.schema-generation.create-database-schemas

Specifies whether the persistence provider is
to create the database schema(s) in addi- tion to creating
database objects such as tables, sequences, constraints,
etc.

"true", "false"

javax.persistence.schema-generation.scripts.create-target

javax.persistence.schema-generation.scripts.drop-target

If scripts are to be generated, controls
target locations for writing of scripts. Writers are
pre-configured for the persistence provider. Need to be
specified only if scripts are to be generated.

java.io.Writer (e.g. MyWriter.class) or URL
strings

javax.persistence.database-product-name,

javax.persistence.database-major-version,
javax.persistence.database-minor-version
Needed if scripts are to be generated and no
connection to target database. Values are those obtained
from JDBC DatabaseMetaData.



javax.persistence.schema-generation.scripts.create-script-source

javax.persistence.schema-generation.scripts.drop-script-source
Specifies locations from which DDL scripts
are to be read. Readers are pre-configured for the
persistence provider.

java.io.Reader (e.g. MyReader.class) or URL
strings
javax.persistence.schema-generation.connection

JDBC connection to be used for schema
generation



javax.persistence.sql-load-script-source

Specifies location of SQL bulk load script.

java.io.Reader (e.g. MyReader.class) or URL
string




Section 11.2 in the href="http://download.oracle.com/otndocs/jcp/persistence-2_1-edr2-spec/index.html">JPA
2.1
specification defines the annotations used for schema
generation process. For example, @Table, @Column, @CollectionTable,
@JoinTable, @JoinColumn, are used to define the generated schema.
Several layers of defaulting may be involved. For example, the table
name is defaulted from entity name and entity name (which can be
specified explicitly as well) is defaulted from the class name.
However annotations may be used to override or customize the values.

The following entity class:

@Entity public class Employee {
    @Id private int id;
    private String name;

    . . .

    @ManyToOne
    private Department dept;
}

is generated in the database with the following attributes:

  • Maps to EMPLOYEE table in default schema
  • "id" field is mapped to ID column as primary key
  • "name" is mapped to NAME column with a default VARCHAR(255).
    The length of this field can be easily tuned using @Column.

  • @ManyToOne is mapped to DEPT_ID foreign key column. Can be
    customized using JOIN_COLUMN.

In addition to these properties, couple of new annotations are
added to JPA 2.1:

  • @Index - An index for the primary key is generated by default
    in a database. This new annotation will allow to define
    additional indexes, over a single or multiple columns, for a
    better performance. This is specified as part of @Table,
    @SecondaryTable, @CollectionTable, @JoinTable, and
    @TableGenerator. For example:


    @Table(indexes = {@Index(columnList="NAME"), @Index(columnList="DEPT_ID DESC")})
    @Entity public class Employee {
        . . .
    }



    The generated table will have a default index on the primary
    key. In addition, two new indexes are defined on the NAME column
    (default ascending) and the foreign key that maps to the
    department in descending order.

  • @ForeignKey - It is used to define foreign key constraint or
    to otherwise override or disable the persistence provider's
    default foreign key definition. Can be specified as part of
    JoinColumn(s), MapKeyJoinColumn(s), PrimaryKeyJoinColumn(s). For
    example:


    @Entity public class Employee {
        @Id private int id;
        private String name;

        @ManyToOne
        @JoinColumn(foreignKey=@ForeignKey(foreignKeyDefinition="FOREIGN KEY (MANAGER_ID) REFERENCES MANAGER"))
        private Manager manager;
        . . .
    }



    In this entity, the employee's manager is mapped by MANAGER_ID
    column in the MANAGER table. The value of foreignKeyDefinition
    would be a database specific string.

A complete replay of Linda's talk at JavaOne 2012 can be href="https://oracleus.activeevents.com/connect/sessionDetail.ww?SESSION_ID=4212">seen
here (click on CON4212_mp4_4212_001 in Media).

These features will be available in href="http://dlc.sun.com.edgesuite.net/glassfish/4.0/promoted/">GlassFish
4
promoted builds in the near future. The development in
EclipseLink is tracked href="http://wiki.eclipse.org/EclipseLink/Development/JPA_2.1">here.

JPA 2.1 will be delivered as part of Java EE 7. The different
components in the Java EE 7 platform are href="https://wikis.oracle.com/display/GlassFish/PlanForGlassFish4.0#PlanForGlassFish4.0-SpecificationStatus">tracked
here.

JPA 2.1 Expert Group has released href="http://jcp.org/aboutJava/communityprocess/edr/jsr338/index2.html">Early
Draft
2 of the specification. Section 9.4 and 11.2 provide all
details about Schema Generation. The latest javadocs can be
obtained href="http://java.net/projects/jpa-spec/downloads/download/JPAjavadocs091212.zip">from
here. And the JPA EG would href="http://java.net/projects/jpa-spec/lists/users/archive">appreciate
feedback.

Join the discussion

Comments ( 7 )
  • Michal Matloka Wednesday, November 21, 2012

    Finally "javax.persistence.schema-generation-action" ! Now jpa configuration might really work with different providers without any changes.


  • Masudul Haque Thursday, November 22, 2012

    At last, a really useful feature have added with JPA 2.1, specially for cloud. But it takes too much time, where hibernate added this feature 4-5 years ago.


  • guest Thursday, November 22, 2012

    Any chances for redesign/addition for Criteria/Restriction especially for integration with business-logic and UI layer? In my opinion, this is what missing key from JPA, and lead to born of many proprietary API out there:

    - http://www.querydsl.com/

    - Spring Data JPA (described here: https://jira.springsource.org/browse/DATAJPA-209?focusedCommentId=84851&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-84851)

    - mine (http://dynamicfinder.github.com/)

    - Some Generic DAO library that you able to find in github and google-code.

    I think all of this exists because JPA lack this integration part. So I think supporting this feature into JPA 2.1 would be nice.


  • guest Thursday, November 29, 2012

    have got an issue when using Schema generation with hibernate, and it seems it will be same with jpa 2.1, it's when we map an entity with a view, there is no way to say "don't create a table !". I think a good idea would be to allow custom sql for table creation.


  • guest Friday, April 5, 2013

    What's the rationale behind the absence of "update" and "verify" as possible values of javax.persistence.schema-generation-action?


  • Christian Beikov Friday, May 24, 2013

    The properties are outdated. Could you please update them according to final release of jpa 2.1 spec?


  • Arun Gupta Friday, May 24, 2013

    Christian,

    The property values are now updated.


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
 

Visit the Oracle Blog

 

Contact Us

Oracle

Integrated Cloud Applications & Platform Services