users@jpa-spec.java.net

[jpa-spec users] [jsr338-experts] Re: two phase approach to creating the EMF, implicit CDI bean manager support ... was :schema generation proposed changes

From: gordon yorke <gordon.yorke_at_oracle.com>
Date: Mon, 17 Jun 2013 11:18:25 -0300

Having a two step deployment of the persistence unit is a good idea. It
would be a lot simpler to add a single "preDeploy" or "preCreate" method
to the current SPI though.
--Gordon

On 17/06/2013 10:56 AM, Scott Marlow wrote:
> A few minor changes to the below proposed interfaces are here (they
> just need a package change to javax.persistence :-)
>
> https://github.com/scottmarlow/jipijapa/commit/db861170076cc9dbc4c07b6fb2facb30c0bc0e8e#L3R30
>
>
> +
>
> https://github.com/scottmarlow/jipijapa/commit/db861170076cc9dbc4c07b6fb2facb30c0bc0e8e#L2R27
>
>
>
> On 06/11/2013 10:18 AM, Scott Marlow wrote:
>> I would like to introduce the least pain, when/if we switch to allowing
>> a two phase bootstream of the container EMF. I propose that we
>> introduce a TwoPhaseBootstrap interface, if the persistence provider
>> implements the TwoPhaseBootstrap interface, the methods can be used by
>> the caller (e.g. EE container looking to create the container entity
>> manager factory).
>>
>> public interface TwoPhaseBootstrap {
>> Bootstrap
>> createContainerEntityManagerFactoryTwoPhase(PersistenceUnitInfo, Map);
>> }
>>
>> public interface Bootstrap {
>> EntityManagerFactory buildEntityManagerFactory();
>> }
>>
>> IMO, this is a good way to allow full JPA support
>> (ClassFileTransformers) and CDI implicit/explicit support (bean manager
>> can be passed into the persistence provider). Without this change, I'm
>> afraid that all deployments with EJB modules, will need to choose
>> between ClassFileTransformers working or use of CDI with entity
>> listeners (performance vs functionality).
>>
>> Does anyone agree or disagree with making a change like the above asap?
>>
>> Scott
>>
>> On 06/07/2013 11:40 AM, Scott Marlow wrote:
>>> On 08/10/2012 07:35 PM, Linda DeMichiel wrote:
>>>> Scott, Steve
>>>>
>>>> Thanks for the proposal.
>>>>
>>>> Folks, I'd like to get feedback from the group on this, particularly
>>>> from container and
>>>> persistence provider implementors.
>>>>
>>>> thanks,
>>>>
>>>> -Linda
>>>>
>>>>
>>>> On 8/9/2012 10:50 AM, Scott Marlow wrote:
>>>>> The idea of having a separate generateSchema() that might do the same
>>>>> work as would of been done in
>>>>> createContainerEntityManagerFactory() (if certain properties are
>>>>> specified), brings to mind some other recent
>>>>> discussions (one that I raised about deployment ordering concerns).
>>>>>
>>>>> Could we add other methods that provide a two-step approach to
>>>>> creating the container manager entity manager factory? EE
>>>>> Containers will still need to handle older JPA providers but we could
>>>>> offer faster/more concurrent application
>>>>> deployment for JPA 2.1 and greater.
>>>>>
>>>>> The reason for turning createContainerEntityManagerFactory(), into
>>>>> two
>>>>> phases, is to allow the EE container to control
>>>>> when different JPA deployment operations can occur. More
>>>>> specifically,
>>>>> I would like to have control over when the
>>>>> persistence provider performs the following aspects of
>>>>> createContainerEntityManagerFactory():
>>>
>>> Perhaps we should start a new thread if there is more interest in
>>> switching to a two phase approach to creating the container entity
>>> manager factory (for post 2.1). I'm just now learning of a conflict
>>> between implicit CDI bean manager support and using
>>> ClassFileTransformers to enhance/rewrite entity classes. I'd like to
>>> allow both but the features seem to conflict with each other.
>>>
>>> Knowing whether there is an explicit CDI bean manager, is easy to
>>> detect
>>> (beans.xml is found) but for the implicit support, we assume there is a
>>> bean manager if there is an EJB module. When we create the container
>>> entity manager factory, if we pass in an implicit CDI bean manager, the
>>> CDI bean manager creation will scan application classes, which means
>>> ClassFileTransformers will register to late.
>>>
>>> Thoughts?
>>>
>>>>>
>>>>> - Scanning for annotations & adding class transformers (to ensure
>>>>> that
>>>>> this happens before other EE deployers load
>>>>> application classes).
>>>>>
>>>>> - DataSource is used (this will help with use of
>>>>> @DataSourceDefinition
>>>>> which might not be initialized until after the
>>>>> other EE deployers have at least started scanning application classes
>>>>> for @DataSourceDefinition).
>>>>>
>>>>> The following is from an extension that we (Steve & I) started to
>>>>> work
>>>>> on, to accomplish this:
>>>>>
>>>>> public interface PersistenceProvider {
>>>>> // Transformers added during this call
>>>>> Bootstrap getBootstrap(PersistenceUnitInfo, Map);
>>>>> }
>>>>>
>>>>> public interface Bootstrap {
>>>>> // datasources accessible during either of these calls
>>>>> void manageSchema();
>>>>> EntityManagerFactory buildEntityManagerFactory();
>>>>> }
>>>>>
>>>>> Scott
>>>>>
>>>>> On 08/08/2012 01:17 PM, Linda DeMichiel wrote:
>>>>>> Please let me know if there are any further comments on this, as I
>>>>>> would otherwise like to proceed to fold it into the spec.
>>>>>>
>>>>>> thanks,
>>>>>>
>>>>>> -Linda
>>>>>>
>>>>>>
>>>>>> On 7/23/2012 4: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();
>>>>>>>
>>>>>>>
>>>>>
>>>>>
>>>
>>
>