JPA 2.1 Schema Generation (TOTD #187)

Posted by arungupta on Oracle Blogs See other posts from Oracle Blogs or by arungupta
Published on Wed, 21 Nov 2012 21:25:25 +0000 Indexed on 2012/11/21 23:06 UTC
Read the original article Hit count: 204

Filed under:

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
Purpose
Values
javax.persistence.schema-generation-action
Controls action to be taken by persistence provider
"none", "create", "drop-and-create", "drop"
javax.persistence.schema-generation-target
Controls whehter schema to be created in database, whether DDL scripts are to be created, or both
"database", "scripts", "database-and-scripts"
javax.persistence.ddl-create-script-target,
javax.persistence.ddl-drop-script-target
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.ddl-create-script-source,
javax.persistence.ddl-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.sql-load-script-source
Specifies location of SQL bulk load script.
java.io.Reader (e.g. MyReader.class) or URL string
javax.persistence.schema-generation-connection
JDBC connection to be used for schema generation

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.create-database-schemas Whether Persistence Provider need to create schema in addition to creating database objects such as tables, sequences, constraints, etc.
"true", "false"

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;

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

These features will be available in GlassFish 4 promoted builds in the near future.

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.

© Oracle Blogs or respective owner

Related posts about /General