users@jpa-spec.java.net

[jpa-spec users] [jsr338-experts] schema generation proposed changes

From: Linda DeMichiel <linda.demichiel_at_oracle.com>
Date: Mon, 23 Jul 2012 16:55:43 -0700

Here's an updated version of my earlier schema generation proposal,
broken out as to proposed spec changes. You should hopefully find
this considerably more flexible and detailed than the earlier draft.

-Linda

----------------------------

Proposed spec changes:


New Section: Schema Generation [to follow section 9.3]

Schema generation may either happen prior to application deployment or
when the entity manager factory is created as part of the application
deployment and initialization process.

   * In Java EE environments, the container may call the
      PersistenceProvider generateSchema method separately from and/or
      prior to the creation of the entity manager factory for the
      persistence unit, or the container may pass additional
      information to the createContainerEntityManagerFactory call to
      cause schema generation to happen as part of the entity manager
      factory creation and application initialization process. The
      information passed to these methods determines whether the
      generation of schemas and/or tables occurs directly in the target
      database, or whether DDL scripts for schema generation are
      created, or both.

  * In Java SE environments, the application may call the Persistence
      generateSchema method separately from and/or prior to the creation
      of the entity manager factory or may pass information to the
      createEntityManagerFactory method to cause schema generation to
      occur as part of the entity manager factory creation.


The application may provide DDL scripts to be used for schema
generation, and package these scripts as part of the persistence unit
or specify URLs corresponding to the location of such scripts. In
Java EE environments, such scripts may be executed by the container,
or the container may direct the persistence provider to execute the
scripts; in Java SE environments, the execution of the scripts is the
responsibility of the persistence provider. In the absence of the
specification of scripts, schema generation, if requested, will be
determined by the object/relational metadata of the persistence unit.


The following standard properties are defined for use in schema
generation. In Java EE environments these properties are passed by
the container in the Map argument to the PersistenceProvider
generateSchema method or createContainerEntityManagerFactory method.
In Java SE environments, they are passed in the Map argument to the
Persistence generateSchema or createEntityManagerFactory method.


javax.persistence.schema-generation-target:

    The schema-generation-target property specifies whether the schema
    is to be created in the database, whether scripts are to be
    generated, or both.

    values for this property: DATABASE, SCRIPTS, DATABASE_AND_SCRIPTS
    [Open Issue: introduce for these enum or use strings? Better names??]


javax.persistence.schema-generation-action:

    The schema-generation-action property is used to specify the action
    to be taken by the persistence provider. If the
    schema-generation-target property is not specified, no action must
    be taken.

    values for this property: NONE, CREATE, DROP_AND_CREATE, DROP
    [Open Issue: enum strings ("none", "create", "drop-and-create",...)


javax.persistence.create-database-schemas

    In Java EE environments, it is anticipated that the Java EE
    platform provider may wish to control the creation of database
    schemas rather than delegate this task to the persistence provider.
    The create-database-schemas property specifies whether the
    persistence provider is to create the database schema(s) in
    addition to creating database objects such as tables, sequences,
    constraints, etc. The value of this boolean property should be set
    to true if the persistence provider is to create schemas in the
    database or to generate DDL which is to contain "CREATE SCHEMA"
    commands. If this property is not supplied, the provider should
    not attempt to create database schemas. This property may be
    specified in Java SE environments as well.


javax.persistence.ddl-create-script-target,
javax.persistence.ddl-drop-script-target:

    If scripts are to be generated, the target locations for the
    writing of these scripts must be specified. These targets may take
    the form of either Writers or strings designating URLs. The
    persistence provider must produce both create and drop scripts if
    the corresponding DDL targets are specified. This is independent
    of whether a drop action is included in the value passed for the
    schema-generation-action property. If the schema-generation-target
    property specifies scripts and script targets are not specified,
    the IllegalArgumentException should be thrown by the provider.

    ddl-create-script-target: a Writer configured for the persistence
       provider for output of the DDL script or a string specifying
       the URL for the DDL script. This property should only be
       specified if scripts are to be generated.

    ddl-drop-script-target: a Writer configured for the persistence
       provider for output of the DDL script or a string specifying the
       URL for the DDL script. This property should only be specified
       if scripts are to be generated.
   [Suggestions for better names ??]


javax.persistence.database-product-name,
javax.persistence.database-product-version,

     If scripts are to be generated by the persistence provider and a
     connection to the target database is not supplied, the
     javax.persistence.database-product-name property must be
     specified. The value of this property should be the value
     returned for the target database by the JDBC DatabaseMetaData
     method getDatabaseProductName. If sufficient database version
     information is not included in the result of this method, the
     database-product-version property should also be specified, and
     should contain the value returned by the JDBC
     getDatabaseProductVersion method.



javax.persistence.ddl-create-script-source,
javax.persistence.ddl-drop-script-source:

     The ddl-create-script-source and ddl-drop-script-source properties
     are used for script execution. In Java EE container environments,
     it is generally expected that the container will be responsible
     for executing DDL scripts, although the container is permitted to
     delegate this task to the persistence provider. If DDL scripts
     are to be used in Java SE environments or if the Java EE container
     delegates the execution of scripts to the persistence provider,
     these properties must be specified. The script sources may take
     the form of either Readers or strings designating URLs.

    ddl-create-script-source: a Reader configured for reading of the
       DDL script or a string specifying the URL for the DDL script.

    ddl-drop-script-source: a Reader configured for reading of the DDL
       script or a string specifying the URL for the DDL script.
   [Suggestions for better names ??]



javax.persistence.sql-load-script-source:

    A data load script may be supplied as part of the persistence
    unit. In Java EE container environments, it is generally expected
    that the container will be responsible for executing data load
    scripts, although the container is permitted to delegate this task
    to the persistence provider. If a load script is to be used in
    Java SE environments or if the Java EE container delegates the
    execution of the load script to the persistence provider, this
    property must be specified. The script source may take the form
    of either a Reader or a string designating a URL.

    sql-load-script-source: a Reader configured for reading of the SQL
       load script for database initialization or a string specifying
       the URL for the script.



javax.persistence.schema-generation-connection:

   JDBC connection to be used for schema generation. This is intended
   for use in Java EE environments, where the platform provider may
   want to control the database privileges that are available to the
   persistence provider. This connection is provided by the container,
   and should be closed by the container when the schema generation
   request or entity manager factory creation completes. The
   connection provided must have credentials sufficient for the
   persistence provider to carry out the requested actions. If this
   property is not specified, the persistence provider should use the
   DataSource that has otherwise been provided.



9.4.1 PersistenceProvider Interface:

New method:

/**
  * Create database schemas and/or tables and/or create DDL
  * scripts as determined by the supplied properties
  *
  * @param info metadata for use by the persistence provider
  * @param map properties for schema generation; these
  * may also contain provider-specific properties
  * @throws PersistenceException if insufficient or inconsistent
  * configuration information is provided or if schema
  * generation otherwise fails.
  */
public void generateSchema(PersistenceUnitInfo info, Map map)


9.6 Persistence Class

New method:

/**
  * Create database schemas and/or tables and/or create DDL
  * scripts as determined by the supplied properties
  *
  * @param persistenceUnitName the name of the persistence unit
  * @param map properties for schema generation; these may also
  * contain provider-specific properties. The values of
  * these properties override any values that may have been
  * configured elsewhere.
  * @throws PersistenceException if insufficient or inconsistent
  * configuration information is provided or if schema
  * generation otherwise fails.
  */
public void generateSchema(String persistenceUnitName, Map properties)


-----------------------

Section 8.2.1 persistence.xml file

To be added to section 8.2.1:

Scripts for use in schema generation and bulk loading of data may be
packaged as part of the persistence unit.


To be added to Section 8.2.1.9 (properties):

Scripts for use in schema generation are specified using the
ddl-create-script and ddl-drop-script elements. A script to specify
SQL for the bulk loading of data may be specified by the
sql-load-script element. These scripts may be packaged as part of the
persistence unit or designated by URL strings.

<xsd:element name="database-scripts" type="database-scripts-type"
              minOccurs="0"/>

<xsd:complexType name="database-scripts-type">
   <xsd:sequence>
     <xsd:element name="ddl-create-script" type="xsd:string"/>
     <xsd:element name="ddl-drop-script" type="xsd:string" minOccurs="0"/>
     <xsd:element name="sql-load-script" type="xsd:string" minOccurs="0"/>
   </xsd:sequence>
</xsd:complexType>

[Open Issue: do we want to require a drop-script if a create-script
has been provided?]

-----------

Chapter 11:

New annotations for use in schema generation:

@Target({}) @Retention(RUNTIME)
public @interface Index {
   String name() default "";
   String columnList();
   boolean unique() default false; // should this be here or just use UniqueConstraints?
}

columnList syntax follows that of the OrderBy annotation:

    columnList::= indexColumn [, indexColumn]*
    indexColumn::= columnName [ASC | DESC]

    If ASC or DESC is not specified, ASC is assumed

Index[] indexes() default {};
is to be added to Table, SecondaryTable, CollectionTable, JoinTable, and TableGenerator



/**
  * Provides for defining a foreign key constraint or for overriding
  * or disabling the persistence provider's default foreign key
  * definition.
  */
@Target({}) @Retention(RUNTIME)
public @interface ForeignKey {
    String name() default "";
    String foreignKeyDefinition() default "";
    boolean disableForeignKey() default false;
}


The syntax used in the foreignKeyDefinition element should follow the
SQL syntax used by the target database for foreign key constraints.
E.g., this would likely be similar to the following:

       FOREIGN KEY ( <COLUMN expression> {, <COLUMN expression>}... )
       REFERENCES <TABLE identifier> [ ( <COLUMN expression> {, <COLUMN expression>}... ) ]
       [ ON UPDATE <referential action> ]
       [ ON DELETE <referential action> ]

If disableForeignKey is specified as true, the provider must not generate
a foreign key constraint.


The following is to be added to JoinColumn, JoinColumns, MapKeyJoinColumn,
MapKeyJoinColumns, PrimaryKeyJoinColumn and PrimaryKeyJoinColumns:

     ForeignKey foreignKey() default @ForeignKey();