Wednesday Nov 21, 2012

JPA 2.1 Schema Generation (TOTD #187)

UPDATED: May 24, 2012

JPA 2.1 specification is now final and can be download from here. The Reference Implementation is integrated in 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 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
Specifies the action to be taken by the persistence provider with regard to the database artifacts "none", "create", "drop-and-create", "drop"
Specifies which scripts are to be generated by the persistence provider "none", "create", "drop-and-create", "drop"
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"
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"
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. (e.g. MyWriter.class) or URL strings
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.

Specifies locations from which DDL scripts are to be read. Readers are pre-configured for the persistence provider. (e.g. MyReader.class) or URL strings
JDBC connection to be used for schema generation

Specifies location of SQL bulk load script. (e.g. MyReader.class) or URL string

Section 11.2 in the 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;

        @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 seen here (click on CON4212_mp4_4212_001 in Media).

These features will be available in GlassFish 4 promoted builds in the near future. The development in EclipseLink is tracked here.

JPA 2.1 will be delivered as part of Java EE 7. The different components in the Java EE 7 platform are tracked here.

JPA 2.1 Expert Group has released Early Draft 2 of the specification. Section 9.4 and 11.2 provide all details about Schema Generation. The latest javadocs can be obtained from here. And the JPA EG would appreciate feedback.


profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.

Java EE 7 Samples

Stay Connected


« November 2012 »