users@jpa-spec.java.net

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

From: Steve Ebersole <steve.ebersole_at_redhat.com>
Date: Thu, 30 Aug 2012 22:56:52 -0500

Personally I think we get into trouble having both sets of versions.
What happens if the user specifies both DatabaseProductVersion and
DatabaseMajorVersion/DatabaseMinorVersion?

To be completely honest, personally I'd much rather have access to the
DatabaseMetaData. But if thats not going to be an option, I'd vote for
just DatabaseMajorVersion and DatabaseMinorVersion (optional).

On Thu 30 Aug 2012 10:41:00 PM CDT, Linda DeMichiel wrote:
> Great, thanks!
>
> So, should we specify all 4 pieces of information?
>
>
> On 8/30/2012 8:09 PM, Steve Ebersole wrote:
>> Another is PostgreSQL adds "if exists" as an option for dropping
>> tables in 8.2 (major=8, minor=2) which did not exist in
>> 8.1 or earlier
>>
>>
>> On Thu 30 Aug 2012 10:04:35 PM CDT, Steve Ebersole wrote:
>>> Well a real simple example is that Derby supports sequences after
>>> 10.6, but not before. So there
>>> DatabaseMetaData#getDatabaseMajorVersion=10 and
>>> DatabaseMetaData#getDatabaseMinorVersion=6. Even if the Derby driver
>>> were to report the DatabaseMetaData#getDatabaseProductVersion="10.6"
>>> or somesuch, relying on being able to parse that into ints to be able
>>> to do range checks make me nervous, especially when JDBC already
>>> offers means to know the major/minor.
>>>
>>> And thats just one example that came to me immediately.
>>>
>>> On Thu 30 Aug 2012 07:24:45 PM CDT, Linda DeMichiel wrote:
>>>> Hi Steve,
>>>>
>>>> I'd like to understand this better, as the info I have from our team
>>>> here
>>>> indicates that database produce name together with version (in the
>>>> worst case)
>>>> would be sufficient. Do we need all four properties to accommodate
>>>> the range
>>>> of drivers/databases?
>>>>
>>>> thanks,
>>>>
>>>> -Linda
>>>>
>>>>
>>>> On 8/29/2012 7:30 AM, Steve Ebersole wrote:
>>>>> As far as:
>>>>>
>>>>> javax.persistence.database-product-name,
>>>>> javax.persistence.database-product-version,
>>>>>
>>>>> I'd really rather see major/minor version used:
>>>>>
>>>>> (int) java.sql.DatabaseMetaData#getDatabaseMajorVersion
>>>>> (int) java.sql.DatabaseMetaData#getDatabaseMinorVersion
>>>>>
>>>>> as opposed to the proposed:
>>>>>
>>>>> (String) java.sql.DatabaseMetaData#getDatabaseProductVersion
>>>>>
>>>>> For one Hibernate already uses those 2 ;) For another its more
>>>>> indicative of what is/isn't available consistently across
>>>>> databases.
>>>>>
>>>>>
>>>>> On 07/23/2012 06:55 PM, Linda DeMichiel wrote:
>>>>>> 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();
>>>>>>
>>>>>>