Skip to content

Commit

Permalink
add SchemaManager
Browse files Browse the repository at this point in the history
see #399
  • Loading branch information
gavinking committed Aug 21, 2023
1 parent 5604d11 commit 618d148
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 4 deletions.
12 changes: 12 additions & 0 deletions api/src/main/java/jakarta/persistence/EntityManagerFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/

// Contributors:
// Gavin King - 3.2
// Linda DeMichiel - 2.1
// Linda DeMichiel - 2.0

Expand Down Expand Up @@ -167,6 +168,17 @@ public interface EntityManagerFactory extends AutoCloseable {
*/
public PersistenceUnitUtil getPersistenceUnitUtil();

/**
* Return interface providing access to schema management
* operations for the persistence unit.
* @return <code>SchemaManager</code> interface
* @throws IllegalStateException if the entity manager factory
* has been closed
*
* @since 3.2
*/
public SchemaManager getSchemaManager();

/**
* Define the query, typed query, or stored procedure query as
* a named query such that future query objects can be created
Expand Down
86 changes: 86 additions & 0 deletions api/src/main/java/jakarta/persistence/SchemaManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2008, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

// Contributors:
// Gavin King - 3.2

package jakarta.persistence;

import java.util.Map;

/**
* Allows programmatic {@linkplain #create schema creation},
* {@linkplain #validate schema validation},
* {@linkplain #truncate data cleanup}, and
* {@linkplain #drop schema cleanup} for entities belonging
* to a certain persistence unit.
*
* <p>Properties are inherited from the {@link EntityManagerFactory},
* that is, they may be specified via {@code persistence.xml} or
* {@link Persistence#createEntityManagerFactory(String, Map)}.
*
* @see EntityManagerFactory#getSchemaManager()
*
* @since 3.2
*/
public interface SchemaManager {
/**
* Create database objects mapped by entities belonging to the
* persistence unit.
*
* <p>If a DDL operation fails, the behavior is undefined.
* A provider may throw an exception, or it may ignore the problem
* and continue.
*
* @param createSchemas if {@code true}, attempt to create schemas,
* otherwise, assume the schemas already exist
*/
void create(boolean createSchemas);

/**
* Drop database objects mapped by entities belonging to the
* persistence unit, undoing the effects of the
* {@linkplain #create(boolean) previous creation}.
*
* <p>If a DDL operation fails, the behavior is undefined.
* A provider may throw an exception, or it may ignore the problem
* and continue.
*
* @param dropSchemas if {@code true}, drop schemas,
* otherwise, leave them be
*/
void drop(boolean dropSchemas);

/**
* Validate that the database objects mapped by entities belonging
* to the persistence unit have the expected definitions.
*
* <p>The persistence provider is not required to perform
* any specific validation, so the semantics of this operation are
* entirely provider-specific.
*
* @throws SchemaValidationException if a database object is missing or
* does not have the expected definition
*/
void validate() throws SchemaValidationException;

/**
* Truncate the database tables mapped by entities belonging to
* the persistence unit, and then re-import initial data from any
* configured SQL scripts for data loading.
*
* <p>If a SQL operation fails, the behavior is undefined.
* A provider may throw an exception, or it may ignore the problem
* and continue.
*/
void truncate();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2008, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

// Contributors:
// Gavin King - 3.2

package jakarta.persistence;

/**
* Thrown when {@link SchemaManager#validate() schema validation} fails.
*
* @see SchemaManager#validate()
*
* @since 3.2
*/
public class SchemaValidationException extends Exception {
private final Exception[] failures;

/**
* An array of problems detected while validating the schema.
*
* <p>A persistence provider might choose to fail fast upon
* encountering a problem with one database object, in which
* case there is only one problem reported here. Alternatively,
* a provider might choose to continue validating the remaining
* database objects, in which case multiple problems might be
* reported, each as a separate exception instance.
*/
public Exception[] getFailures() {
return failures;
}

/**
* Constructs a new instance with a message and, optionally,
* an array of exceptions, each representing a problem detected
* while validating the schema.
* @param message an overall message
* @param failures an array of exceptions, each representing a
* separate problem
*/
public SchemaValidationException(String message, Exception... failures) {
super(message);
this.failures = failures == null ? new Exception[0] : failures;
}

}
2 changes: 2 additions & 0 deletions spec/src/main/asciidoc/appendixes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ Added `||` string concatenation operator

Added support for specifying null precedence when ordering JPQL and criteria queries

Introduced SchemaManager API

Added _getSingleResultOrNull()_ to _Query_, _TypedQuery_, _StoredProcedureQuery_

Added new operations to _PersistenceUnitUtil_
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,17 @@ public interface EntityManagerFactory extends AutoCloseable {
*/
public PersistenceUnitUtil getPersistenceUnitUtil();
/**
* Return interface providing access to schema management
* operations for the persistence unit.
* @return <code>SchemaManager</code> interface
* @throws IllegalStateException if the entity manager factory
* has been closed
*
* @since 3.2
*/
public SchemaManager getSchemaManager();
/**
* Define the query, typed query, or stored procedure query as
* a named query such that future query objects can be created
Expand Down Expand Up @@ -1525,4 +1536,101 @@ public interface PersistenceUnitUtil extends PersistenceUtil {
*/
public Object getIdentifier(Object entity);
}
----

=== SchemaManager Interface [[a12178]]

The _SchemaManager_ interface allows programmatic control over schema
generation and cleanup at runtime. This differs from the functionality
described in <<a12917>> which allows schema generation before or during
the application deployment and initialization process. Similarly, the
_generateSchema_ method described in <<a12803>> is intended to be called
before the _EntityManagerFactory_ is available. By contrast, an instance
of _SchemaManager_ is only available after an _EntityManagerFactory_ has
already been created.

For example, _SchemaManager_ is especially useful in tests.

The methods of _SchemaManager_ correspond to values of the property
_jakarta.persistence.schema-generation.scripts.action_. The methods
_create()_, _drop()_, and _validate()_ correspond to the actions
_create_, _drop_, and _validate_. The method _truncate()_ has no
corresponding action.

Thus, the behavior of the _SchemaManager_ may be controlled via the
properties defined in <<a12917>> and <<a12384>>.

[source,java]
----
package jakarta.persistence;
import java.util.Map;
/**
* Allows programmatic {@linkplain #create schema creation},
* {@linkplain #validate schema validation},
* {@linkplain #truncate data cleanup}, and
* {@linkplain #drop schema cleanup} for entities belonging
* to a certain persistence unit.
*
* <p>Properties are inherited from the {@link EntityManagerFactory},
* that is, they may be specified via {@code persistence.xml} or
* {@link Persistence#createEntityManagerFactory(String, Map)}.
*
* @see EntityManagerFactory#getSchemaManager()
*
* @since 3.2
*/
public interface SchemaManager {
/**
* Create database objects mapped by entities belonging to the
* persistence unit.
*
* <p>If a DDL operation fails, the behavior is undefined.
* A provider may throw an exception, or it may ignore the problem
* and continue.
*
* @param createSchemas if {@code true}, attempt to create schemas,
* otherwise, assume the schemas already exist
*/
void create(boolean createSchemas);
/**
* Drop database objects mapped by entities belonging to the
* persistence unit, undoing the effects of the
* {@linkplain #create(boolean) previous creation}.
*
* <p>If a DDL operation fails, the behavior is undefined.
* A provider may throw an exception, or it may ignore the problem
* and continue.
*
* @param dropSchemas if {@code true}, drop schemas,
* otherwise, leave them be
*/
void drop(boolean dropSchemas);
/**
* Validate that the database objects mapped by entities belonging
* to the persistence unit have the expected definitions.
*
* <p>The persistence provider is not required to perform
* any specific validation, so the semantics of this operation are
* entirely provider-specific.
*
* @throws SchemaValidationException if a database object is missing or
* does not have the expected definition
*/
void validate() throws SchemaValidationException;
/**
* Truncate the database tables mapped by entities belonging to
* the persistence unit, and then re-import initial data from any
* configured SQL scripts for data loading.
*
* <p>If a SQL operation fails, the behavior is undefined.
* A provider may throw an exception, or it may ignore the problem
* and continue.
*/
void truncate();
}
----
4 changes: 2 additions & 2 deletions spec/src/main/asciidoc/ch08-entity-packaging.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,8 @@ properties used in the _persistence.xml_ file.
The _jakarta.persistence.schema-generation.database.action_ property specifies
the action to be taken by the persistence provider with regard to the
database artifacts. The values for this property are _none_, _create_,
_drop-and-create_, _drop_. If this property is not specified, it is
assumed that schema generation is not needed or will be initiated by
_drop-and-create_, _drop_, _validate_. If this property is not specified,
it is assumed that schema generation is not needed or will be initiated by
other means, and, by default, no schema generation actions will be taken
on the database. (See <<a12917>>.)
* _jakarta.persistence.schema-generation.scripts.action_ +
Expand Down
4 changes: 2 additions & 2 deletions spec/src/main/asciidoc/ch09-container-provider-contracts.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ If a provider does not qualify as the
provider for the named persistence unit, it must return _null_ when
_createEntityManagerFactory_ is invoked on it.

==== Schema Generation
==== Schema Generation [[a12803]]

In Java SE environments, the
_Persistence.generateSchema_ method may be used by the application to
Expand Down Expand Up @@ -389,7 +389,7 @@ deploying the persistence unit
The _jakarta.persistence.schema-generation.database.action_ property specifies
the action to be taken by the persistence provider with regard to the
database artifacts. The values for this property are _"none"_,
_"create"_, _"drop-and-create"_, _"drop"_. If the
_"create"_, _"drop-and-create"_, _"drop"_, _"validate"_. If the
_jakarta.persistence.schema-generation.database.action_ property is not
specified, no schema generation actions must be taken on the database.
* _jakarta.persistence.schema-generation.scripts.action_ +
Expand Down

0 comments on commit 618d148

Please sign in to comment.