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();