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: Scott Marlow <smarlow_at_redhat.com>
Date: Mon, 17 Jun 2013 09:56:38 -0400

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