Skip to content

Commit

Permalink
add and spec PersistenceConfiguration
Browse files Browse the repository at this point in the history
see #358, #149, #114
  • Loading branch information
gavinking committed Aug 13, 2023
1 parent 5604d11 commit 6edba8c
Show file tree
Hide file tree
Showing 6 changed files with 470 additions and 12 deletions.
30 changes: 30 additions & 0 deletions api/src/main/java/jakarta/persistence/Persistence.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,36 @@ public static EntityManagerFactory createEntityManagerFactory(String persistence
return emf;
}

/**
* Create and return an EntityManagerFactory for the named persistence unit
* using the given properties.
*
* @param configuration
* configuration of the persistence unit
* @return the factory that creates EntityManagers configured according to
* the specified persistence unit.
*
* @since 3.2
*/
public static EntityManagerFactory createEntityManagerFactory(PersistenceConfiguration configuration) {

EntityManagerFactory emf = null;
PersistenceProviderResolver resolver = PersistenceProviderResolverHolder.getPersistenceProviderResolver();

List<PersistenceProvider> providers = resolver.getPersistenceProviders();

for (PersistenceProvider provider : providers) {
emf = provider.createEntityManagerFactory(configuration);
if (emf != null) {
break;
}
}
if (emf == null) {
throw new PersistenceException("No Persistence provider for EntityManager named " + configuration.name());
}
return emf;
}


/**
* Create database schemas and/or tables and/or create DDL
Expand Down
323 changes: 323 additions & 0 deletions api/src/main/java/jakarta/persistence/PersistenceConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
/*
* Copyright (c) 2008, 2020 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 javax.sql.DataSource;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Represents a configuration of a persistence unit, allowing programmatic
* creation of an {@link EntityManagerFactory}. The configuration options
* available via this API reflect the similarly-named elements of the
* {@code persistence.xml} file.
*
* <p>This API may not be used to configure a container-managed persistence
* unit. That is, the configured persistence unit should be considered a
* Java SE persistence unit, even when this API is used within the Jakarta
* EE environment.
*
* <p>If injection of the {@link EntityManagerFactory} is required, a CDI
* {@code Producer} may be used to make the {@link EntityManagerFactory}
* available as a CDI managed bean.
*
* <pre>
* &#064;Produces &#064;ApplicationScoped &#064;Documents
* EntityManagerFactory configure() {
* DataSource datasource = (DataSource)
* new InitialContext()
* .lookup("java:global/jdbc/DocumentDatabase");
* return new PersistenceConfiguration()
* .name("DocumentData")
* .nonJtaDataSource(datasource)
* .managedClass(Document.class)
* .createEntityManagerFactory();
* }
* </pre>
*
* <p>Similarly, if injection of an {@link EntityManager} is required,
* a CDI {@code Producer} method/{@code Disposer} method pair may be
* used to make the {@link EntityManager} available as a CDI managed
* bean.
*
* <pre>
* &#064;Produces &#064;TransactionScoped &#064;Documents
* EntityManager create(&#064;Documents EntityManagerFactory factory) {
* return factory.createEntityManager();
* }
*
* void close(&#064;Disposes &#064;Documents EntityManager entityManager) {
* entityManager.close();
* }
* </pre>
*
* @see Persistence#createEntityManagerFactory(PersistenceConfiguration)
*
* @since 3.2
*/
public class PersistenceConfiguration {

private String name;
private String provider;
private DataSource jtaDataSource;
private DataSource nonJtaDataSource;
// private URL persistenceUnitRootUrl;

private SharedCacheMode sharedCacheMode = SharedCacheMode.UNSPECIFIED;
private ValidationMode validationMode = ValidationMode.AUTO;
private TransactionType transactionType = TransactionType.RESOURCE_LOCAL;
// private boolean excludeUnlistedClasses = false;

private List<URL> jarFileUrls = new ArrayList<>();
private List<Class<?>> managedClasses = new ArrayList<>();
private List<String> mappingFileNames = new ArrayList<>();
private Map<String,Object> properties = new HashMap<>();

public enum TransactionType { JTA, RESOURCE_LOCAL }

/**
* Create a new {@link EntityManagerFactory} based on this configuration.
* @throws IllegalStateException if required configuration is missing
*/
public EntityManagerFactory createEntityManagerFactory() {
return Persistence.createEntityManagerFactory(this);
}

/**
* Specify the name of the persistence unit.
*/
public PersistenceConfiguration name(String name) {
this.name = name;
return this;
}

/**
* @return the name of the persistence unit.
*/
public String name() {
return name;
}

// /**
// * Specify a root URL for the persistence unit.
// * @param url the URL of a directory or JAR archive
// * @return this configuration
// */
// public PersistenceConfiguration persistenceUnitRootUrl(URL url) {
// persistenceUnitRootUrl = url;
// return this;
// }
//
// /**
// * @return the root URL for the persistence unit, if any
// */
// public URL persistenceUnitRootUrl() {
// return persistenceUnitRootUrl;
// }

/**
* Specify the persistence provider.
* @param providerClassName the qualified name of the persistence provider class
* @return this configuration
*/
public PersistenceConfiguration provider(String providerClassName) {
this.provider = providerClassName;
return this;
}

/**
* @return the qualified name of the persistence provider class.
*/
public String provider() {
return provider;
}

/**
* Specify a JTA {@link DataSource}.
* @param dataSource the JTA datasource
* @return this configuration
*/
public PersistenceConfiguration jtaDataSource(DataSource dataSource) {
this.jtaDataSource = dataSource;
return this;
}

/**
* @return the configured JTA datasource, if any
*/
public DataSource jtaDataSource() {
return jtaDataSource;
}

/**
* Specify a non-JTA {@link DataSource}.
* @param dataSource the non-JTA datasource
* @return this configuration
*/
public PersistenceConfiguration nonJtaDataSource(DataSource dataSource) {
this.nonJtaDataSource = dataSource;
return this;
}

/**
* @return the configured non-JTA datasource, if any
*/
public DataSource nonJtaDataSource() {
return nonJtaDataSource;
}

/**
* Add a managed class (an {@link Entity}, {@link Embeddable}, or
* {@link MappedSuperclass}) to the configuration.
* @param managedClass the managed class
* @return this configuration
*/
public PersistenceConfiguration managedClass(Class<?> managedClass) {
managedClasses.add(managedClass);
return this;
}

/**
* @return all configured managed classes
*/
public List<Class<?>> managedClasses() {
return managedClasses;
}

/**
* Add an {@code orm.xml} mapping file name to the configuration.
* @param name the file path of the mapping file
* @return this configuration
*/
public PersistenceConfiguration mappingFile(String name) {
mappingFileNames.add(name);
return this;
}

/**
* @return all configured mapping file names
*/
public List<String> mappingFiles() {
return mappingFileNames;
}

/**
* Add a JAR archive to the configuration.
* @param url the URL of the JAR archive
* @return this configuration
*/
public PersistenceConfiguration jarFileUrl(URL url) {
jarFileUrls.add(url);
return this;
}

/**
* @return all configured JAR archives
*/
public List<URL> jarFileUrls() {
return jarFileUrls;
}

/**
* Specify the transaction type for the persistence unit.
* @param transactionType the transaction type
* @return this configuration
*/
public PersistenceConfiguration transactionType(TransactionType transactionType) {
this.transactionType = transactionType;
return this;
}

/**
* @return the transaction type
*/
public TransactionType transactionType() {
return transactionType;
}

/**
* Specify the shared cache mode for the persistence unit.
* @param sharedCacheMode the shared cache mode
* @return this configuration
*/
public PersistenceConfiguration sharedCacheMode(SharedCacheMode sharedCacheMode) {
this.sharedCacheMode = sharedCacheMode;
return this;
}

/**
* @return the shared cache mode
*/
public SharedCacheMode sharedCacheMode() {
return sharedCacheMode;
}

/**
* Specify the validation mode for the persistence unit.
* @param validationMode the shared cache mode
* @return this configuration
*/
public PersistenceConfiguration validationMode(ValidationMode validationMode) {
this.validationMode = validationMode;
return this;
}

/**
* @return the validation mode
*/
public ValidationMode validationMode() {
return validationMode;
}

// public PersistenceConfiguration excludeUnlistedClasses(boolean excludeUnlistedClasses) {
// this.excludeUnlistedClasses = excludeUnlistedClasses;
// return this;
// }
//
// public boolean excludeUnlistedClasses() {
// return excludeUnlistedClasses;
// }

/**
* Set a property of this persistence unit.
* @param name the property name
* @param value the property value
* @return this configuration
*/
public PersistenceConfiguration property(String name, Object value) {
properties.put(name, value);
return this;
}

/**
* Set multiple properties of this persistence unit.
* @param properties the properties
* @return this configuration
*/
public PersistenceConfiguration properties(Map<String,?> properties) {
this.properties.putAll(properties);
return this;
}

/**
* @return the configured properties
*/
public Map<String, Object> properties() {
return properties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import jakarta.persistence.PersistenceConfiguration;
import jakarta.persistence.PersistenceException;
import java.util.Map;

Expand Down Expand Up @@ -45,10 +46,27 @@ public interface PersistenceProvider {
* properties not specified in the <code>persistence.xml</code>
* (and may be null if no properties are specified).
* @return EntityManagerFactory for the persistence unit,
* or null if the provider is not the right provider
* or null if the provider is not the right provider
*
* @see Persistence#createEntityManagerFactory(String, Map)
*/
public EntityManagerFactory createEntityManagerFactory(String emName, Map map);

/**
* Called by <code>Persistence</code> class when an
* <code>EntityManagerFactory</code> is to be created.
*
* @param configuration the configuration of the persistence unit
* @return EntityManagerFactory for the persistence unit,
* or null if the provider is not the right provider
* @throws IllegalStateException if required configuration is missing
*
* @see Persistence#createEntityManagerFactory(PersistenceConfiguration)
*
* @since 3.2
*/
public EntityManagerFactory createEntityManagerFactory(PersistenceConfiguration configuration);

/**
* Called by the container when an <code>EntityManagerFactory</code>
* is to be created.
Expand Down
Loading

0 comments on commit 6edba8c

Please sign in to comment.