/******************************************************************************* | |
* Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* Oracle - initial API and implementation from Oracle TopLink | |
* | |
* 04/30/2009-2.0 Michael O'Brien | |
* - 266912: JPA 2.0 Metamodel API (part of Criteria API) | |
* Add Set<RelationalDescriptor> mappedSuperclassDescriptors | |
* to support the Metamodel API | |
* 06/17/2009-2.0 Michael O'Brien | |
* - 266912: change mappedSuperclassDescriptors Set to a Map | |
* keyed on MetadataClass - avoiding the use of a hashCode/equals | |
* override on RelationalDescriptor, but requiring a contains check prior to a put | |
* 09/23/2009-2.0 Michael O'Brien | |
* - 266912: Add metamodelIdClassMap to store IdClass types for exclusive | |
* use by the IdentifiableTypeImpl class in the JPA 2.0 Metamodel API | |
* 06/30/2011-2.3.1 Guy Pelletier | |
* - 341940: Add disable/enable allowing native queries | |
* 09/09/2011-2.3.1 Guy Pelletier | |
* - 356197: Add new VPD type to MultitenantType | |
* 09/14/2011-2.3.1 Guy Pelletier | |
* - 357533: Allow DDL queries to execute even when Multitenant entities are part of the PU | |
* 14/05/2012-2.4 Guy Pelletier | |
* - 376603: Provide for table per tenant support for multitenant applications | |
* 31/05/2012-2.4 Guy Pelletier | |
* - 381196: Multitenant persistence units with a dedicated emf should allow for DDL generation. | |
* 08/11/2012-2.5 Guy Pelletier | |
* - 393867: Named queries do not work when using EM level Table Per Tenant Multitenancy. | |
******************************************************************************/ | |
package org.eclipse.persistence.sessions; | |
import java.util.*; | |
import java.io.*; | |
import org.eclipse.persistence.annotations.IdValidation; | |
import org.eclipse.persistence.config.CacheIsolationType; | |
import org.eclipse.persistence.core.sessions.CoreProject; | |
import org.eclipse.persistence.descriptors.ClassDescriptor; | |
import org.eclipse.persistence.descriptors.MultitenantPolicy; | |
import org.eclipse.persistence.descriptors.partitioning.PartitioningPolicy; | |
import org.eclipse.persistence.internal.sessions.AbstractSession; | |
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl; | |
import org.eclipse.persistence.internal.helper.*; | |
import org.eclipse.persistence.internal.identitymaps.AbstractIdentityMap; | |
import org.eclipse.persistence.queries.AttributeGroup; | |
import org.eclipse.persistence.queries.DatabaseQuery; | |
import org.eclipse.persistence.queries.QueryResultsCachePolicy; | |
import org.eclipse.persistence.queries.SQLResultSetMapping; | |
import org.eclipse.persistence.sessions.server.*; | |
/** | |
* <b>Purpose</b>: Maintain all of the EclipseLink configuration information for a system. | |
* <p><b>Responsibilities</b>:<ul> | |
* <li> Project options and defaults | |
* <li> Database login information | |
* <li> Descriptors | |
* <li> Validate Descriptors | |
* <li> Maintain sequencing information & other project options | |
* </ul> | |
* | |
* @see DatabaseLogin | |
*/ | |
public class Project extends CoreProject<ClassDescriptor, Login, DatabaseSession> implements Serializable, Cloneable { | |
protected String name; | |
protected Login datasourceLogin; | |
protected Map<Class, ClassDescriptor> descriptors; | |
protected List<ClassDescriptor> orderedDescriptors; | |
// Currently only one is supported. | |
protected MultitenantPolicy multitenantPolicy; | |
/** Holds the default set of read-only classes that apply to each UnitOfWork. */ | |
protected Vector defaultReadOnlyClasses; | |
/** Cache the EJBQL descriptor aliases. */ | |
protected Map aliasDescriptors; | |
/** Cache if any descriptor is isolated. (set during initialization) */ | |
protected boolean hasIsolatedClasses; | |
/** Cache if all descriptors are isolated in the unit of work. (set during initialization) */ | |
protected boolean hasNonIsolatedUOWClasses; | |
/** Cache if any descriptor has history. (set during initialization) */ | |
protected boolean hasGenericHistorySupport; | |
/** Cache if any descriptor is using ProxyIndirection. (set during initialization */ | |
protected boolean hasProxyIndirection; | |
/** This a collection of 'maps' that allow users to map custom SQL to query results */ | |
protected Map<String, SQLResultSetMapping> sqlResultSetMappings; | |
/** PERF: Provide an JPQL parse cache to optimize dynamic JPQL. */ | |
protected transient ConcurrentFixedCache jpqlParseCache; | |
/** Define the default setting for configuring if dates and calendars are mutable. */ | |
protected boolean defaultTemporalMutable = false; | |
/** Indicates whether there is at least one descriptor that has at least on mapping that | |
* require a call on deleted objects to update change sets. | |
*/ | |
protected transient boolean hasMappingsPostCalculateChangesOnDeleted = false; | |
/** Default value for ClassDescriptor.identityMapClass. */ | |
protected Class defaultIdentityMapClass = AbstractIdentityMap.getDefaultIdentityMapClass(); | |
/** Default value for ClassDescriptor.identityMapSize. */ | |
protected int defaultIdentityMapSize = 100; | |
/** Default value for ClassDescriptor.isIsolated. */ | |
protected CacheIsolationType defaultCacheIsolation; | |
/** Default value for query caching options for all named queries. */ | |
protected QueryResultsCachePolicy defaultQueryResultsCachePolicy; | |
/** Default value for ClassDescriptor.idValidation. */ | |
protected IdValidation defaultIdValidation; | |
/** List of queries - once Project is initialized, these are copied to the Session. */ | |
protected List<DatabaseQuery> queries; | |
/** List of named AttributeGroups - once Project is initialized, these are copied to the Session. */ | |
protected Map<String, AttributeGroup> attributeGroups = null; | |
/** List of queries from JPA that need special processing before execution. */ | |
protected List<DatabaseQuery> jpaQueries; | |
/** List of queries from JPA that may special processing and handling before execution. */ | |
protected List<DatabaseQuery> jpaTablePerTenantQueries; | |
/** Flag that allows native queries or not */ | |
protected boolean allowNativeSQLQueries = true; | |
/** Flag that allows DDL generation of table per tenant multitenant descriptors */ | |
protected boolean allowTablePerMultitenantDDLGeneration = false; | |
/** | |
* Mapped Superclasses (JPA 2) collection of parent non-relational descriptors keyed on MetadataClass | |
* without creating a compile time dependency on JPA. | |
* The descriptor values of this map must not be replaced by a put() so that the | |
* mappings on the initial descriptor are not overwritten.<p> | |
* These descriptors are only to be used by Metamodel generation. | |
* @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation | |
*/ | |
protected Map<String, ClassDescriptor> mappedSuperclassDescriptors; | |
/** | |
* Store the IdClass Id attributes for exclusive use by the Metamodel API | |
* Keyed on the fully qualified accessible object owner class name. | |
* Value is a List of the fully qualified id class name or id attribute name. | |
* @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation | |
*/ | |
protected Map<String, List<String>> metamodelIdClassMap; | |
/** Map of named partitioning policies, keyed by their name. */ | |
protected Map<String, PartitioningPolicy> partitioningPolicies; | |
/** Ensures that only one thread at a time can add/remove descriptors */ | |
protected Object descriptorsLock = new Boolean(true); | |
/** VPD connection settings */ | |
protected String vpdIdentifier; | |
protected String vpdLastIdentifierClassName; // Used for validation exception. | |
/** used for Caching JPA projects */ | |
protected Collection<String> classNamesForWeaving; | |
protected Collection<String> structConverters; | |
/** | |
* PUBLIC: | |
* Create a new project. | |
*/ | |
public Project() { | |
this.name = ""; | |
this.descriptors = new HashMap(); | |
this.defaultReadOnlyClasses = NonSynchronizedVector.newInstance(); | |
this.orderedDescriptors = new ArrayList<ClassDescriptor>(); | |
this.hasIsolatedClasses = false; | |
this.hasGenericHistorySupport = false; | |
this.hasProxyIndirection = false; | |
this.jpqlParseCache = new ConcurrentFixedCache(200); | |
this.queries = new ArrayList<DatabaseQuery>(); | |
this.mappedSuperclassDescriptors = new HashMap<String, ClassDescriptor>(2); | |
this.metamodelIdClassMap = new HashMap<String, List<String>>(); | |
this.attributeGroups = new HashMap<String, AttributeGroup>(); | |
} | |
/** | |
* PUBLIC: | |
* Create a new project that will connect through the login information. | |
* This method can be used if the project is being create in code instead of being read from a file. | |
*/ | |
public Project(Login login) { | |
this(); | |
this.datasourceLogin = login; | |
} | |
/** | |
* PUBLIC: | |
* Create a new project that will connect through JDBC using the login information. | |
* This method can be used if the project is being create in code instead of being read from a file. | |
*/ | |
public Project(DatabaseLogin login) { | |
this(); | |
this.datasourceLogin = login; | |
} | |
/** | |
* PUBLIC: | |
* Return the default values for query caching options for all named queries. | |
*/ | |
public QueryResultsCachePolicy getDefaultQueryResultsCachePolicy() { | |
return defaultQueryResultsCachePolicy; | |
} | |
/** | |
* PUBLIC: | |
* Set the default values for query caching options for all named queries. | |
* By default no query caching is used. | |
*/ | |
public void setDefaultQueryResultsCachePolicy(QueryResultsCachePolicy defaultQueryResultsCachePolicy) { | |
this.defaultQueryResultsCachePolicy = defaultQueryResultsCachePolicy; | |
} | |
/** | |
* PUBLIC: | |
* Return the default setting for configuring if dates and calendars are mutable. | |
* Mutable means that changes to the date's year/month/day are detected. | |
* By default they are treated as not mutable. | |
*/ | |
public boolean getDefaultTemporalMutable() { | |
return defaultTemporalMutable; | |
} | |
/** | |
* PUBLIC: | |
* Set the default setting for configuring if dates and calendars are mutable. | |
* Mutable means that changes to the date's year/month/day are detected. | |
* By default they are treated as not mutable. | |
*/ | |
public void setDefaultTemporalMutable(boolean defaultTemporalMutable) { | |
this.defaultTemporalMutable = defaultTemporalMutable; | |
} | |
/** | |
* INTERNAL: | |
* Return all pre-defined not yet parsed JPQL queries. | |
*/ | |
public List<DatabaseQuery> getJPAQueries() { | |
// PERF: lazy init, not normally required. | |
if (jpaQueries == null) { | |
jpaQueries = new ArrayList(); | |
} | |
return jpaQueries; | |
} | |
/** | |
* INTERNAL: | |
* Return all pre-defined not yet parsed JPQL queries to table per tenant | |
* entities. | |
*/ | |
public List<DatabaseQuery> getJPATablePerTenantQueries() { | |
// PERF: lazy init, not normally required. | |
if (jpaTablePerTenantQueries == null) { | |
jpaTablePerTenantQueries = new ArrayList(); | |
} | |
return jpaTablePerTenantQueries; | |
} | |
/** | |
* INTERNAL: | |
* Return the JPQL parse cache. | |
* This is used to optimize dynamic JPQL. | |
*/ | |
public ConcurrentFixedCache getJPQLParseCache() { | |
if (jpqlParseCache==null) { | |
jpqlParseCache = new ConcurrentFixedCache(200); | |
} | |
return jpqlParseCache; | |
} | |
/** | |
* ADVANCED: | |
* Set the JPQL parse cache max size. | |
* This is used to optimize dynamic JPQL. | |
*/ | |
public void setJPQLParseCacheMaxSize(int maxSize) { | |
setJPQLParseCache(new ConcurrentFixedCache(maxSize)); | |
} | |
/** | |
* ADVANCED: | |
* Return the JPQL parse cache max size. | |
* This is used to optimize dynamic JPQL. | |
*/ | |
public int getJPQLParseCacheMaxSize() { | |
return getJPQLParseCache().getMaxSize(); | |
} | |
/** | |
* INTERNAL: | |
* Set the JPQL parse cache. | |
* This is used to optimize dynamic JPQL. | |
*/ | |
protected void setJPQLParseCache(ConcurrentFixedCache jpqlParseCache) { | |
this.jpqlParseCache = jpqlParseCache; | |
} | |
/** | |
* INTERNAL: | |
* List of queries that upon initialization are copied over to the session | |
*/ | |
public List<DatabaseQuery> getQueries() { | |
return queries; | |
} | |
/** | |
* INTERNAL: | |
* @param queries | |
*/ | |
public void setQueries(List<DatabaseQuery> queries) { | |
this.queries = queries; | |
} | |
/** | |
* INTERNAL: | |
* List of named AttributesGroups that will be copied to the session at initialization time. | |
*/ | |
public Map<String, AttributeGroup> getAttributeGroups(){ | |
return this.attributeGroups; | |
} | |
/** | |
* INTERNAL: | |
* Set the VPD identifier for this project. This identifier should be | |
* populated from a descriptor VPDMultitenantPolicy and should not be | |
* set directly. | |
*/ | |
public void setVPDIdentifier(String vpdIdentifier) { | |
this.vpdIdentifier = vpdIdentifier; | |
} | |
/** | |
* INTERNAL: | |
* Set from individual descriptors from the project that set a VPD | |
* identifier and used in validation exception. | |
*/ | |
public void setVPDLastIdentifierClassName(String vpdLastIdentifierClassName) { | |
this.vpdLastIdentifierClassName = vpdLastIdentifierClassName; | |
} | |
/** | |
* PUBLIC: | |
* Add the read-only class which apply to each UnitOfWork created by default. | |
*/ | |
public void addDefaultReadOnlyClass(Class readOnlyClass) { | |
getDefaultReadOnlyClasses().addElement(readOnlyClass); | |
} | |
/** | |
* PUBLIC: | |
* Add the descriptor to the project. | |
*/ | |
public void addDescriptor(ClassDescriptor descriptor) { | |
getOrderedDescriptors().add(descriptor); | |
String alias = descriptor.getAlias(); | |
if (alias != null) { | |
addAlias(alias, descriptor); | |
} | |
// Avoid loading class definition at this point if we haven't done so yet. | |
if ((descriptors != null) && !descriptors.isEmpty()) { | |
getDescriptors().put(descriptor.getJavaClass(), descriptor); | |
} | |
} | |
/** | |
* INTERNAL: Used by the BuilderInterface when reading a Project from INI files. | |
*/ | |
public void addDescriptor(ClassDescriptor descriptor, DatabaseSessionImpl session) { | |
synchronized (this.descriptorsLock) { | |
if (session.isConnected()) { | |
getOrderedDescriptors().add(descriptor); | |
String alias = descriptor.getAlias(); | |
// descriptor aliases may be concurrently accessed by other threads. | |
// make a clone, add new descriptor to the clone, override original with the clone. | |
if (alias != null) { | |
Map aliasDescriptorsClone = null; | |
if (getAliasDescriptors() != null) { | |
aliasDescriptorsClone = (Map)((HashMap)getAliasDescriptors()).clone(); | |
} else { | |
aliasDescriptorsClone = new HashMap(); | |
} | |
aliasDescriptorsClone.put(alias, descriptor); | |
setAliasDescriptors(aliasDescriptorsClone); | |
} | |
// descriptors may be concurrently accessed by other threads. | |
// make a clone, add new descriptor to the clone, override original with the clone. | |
Map<Class, ClassDescriptor> descriptorsClone = (Map)((HashMap)getDescriptors()).clone(); | |
descriptorsClone.put(descriptor.getJavaClass(), descriptor); | |
setDescriptors(descriptorsClone); | |
session.copyDescriptorsFromProject(); | |
session.initializeDescriptorIfSessionAlive(descriptor); | |
} else { | |
addDescriptor(descriptor); | |
} | |
} | |
} | |
/** | |
* INTERNAL: | |
* Add the descriptors to the session. | |
* All persistent classes must have a descriptor registered for them with the session. | |
* This method allows for a batch of descriptors to be added at once so that EclipseLink | |
* can resolve the dependencies between the descriptors and perform initialization optimally. | |
*/ | |
public void addDescriptors(Collection descriptors, DatabaseSessionImpl session) { | |
synchronized (this.descriptorsLock) { | |
if (session.isConnected()) { | |
// descriptor aliases may be concurrently accessed by other threads. | |
// make a clone, add new descriptors to the clone, override original with the clone. | |
Map aliasDescriptorsClone = null; | |
if (getAliasDescriptors() != null) { | |
aliasDescriptorsClone = (Map)((HashMap)getAliasDescriptors()).clone(); | |
} else { | |
aliasDescriptorsClone = new HashMap(); | |
} | |
// descriptors may be concurrently accessed by other threads. | |
// make a clone, add new descriptors to the clone, override original with the clone. | |
Map<Class, ClassDescriptor> descriptorsClone = (Map)((HashMap)getDescriptors()).clone(); | |
Iterator it = descriptors.iterator(); | |
while (it.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)it.next(); | |
descriptorsClone.put(descriptor.getJavaClass(), descriptor); | |
String alias = descriptor.getAlias(); | |
if (alias != null) { | |
aliasDescriptorsClone.put(alias, descriptor); | |
} | |
} | |
if (!aliasDescriptorsClone.isEmpty()) { | |
setAliasDescriptors(aliasDescriptorsClone); | |
} | |
setDescriptors(descriptorsClone); | |
session.copyDescriptorsFromProject(); | |
session.initializeDescriptors(descriptors); | |
} else { | |
Iterator it = descriptors.iterator(); | |
while (it.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)it.next(); | |
getDescriptors().put(descriptor.getJavaClass(), descriptor); | |
String alias = descriptor.getAlias(); | |
if (alias != null) { | |
addAlias(alias, descriptor); | |
} | |
} | |
} | |
getOrderedDescriptors().addAll(descriptors); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Merge the descriptors from another project into this one. | |
* All persistent classes must have a descriptor registered for them with the session. | |
* This method allows for a batch of descriptors to be added at once so that EclipseLink | |
* can resolve the dependencies between the descriptors and perform initialization optimally. | |
*/ | |
public void addDescriptors(Project project, DatabaseSessionImpl session) { | |
addDescriptors(project.getDescriptors().values(), session); | |
} | |
/** | |
* PUBLIC: | |
* Add a named SQLResultSetMapping to this project. These SQLResultSetMappings | |
* can be later used by ResultSetMappingQueries to map Custom sql results to | |
* results as defined by the SQLResultSetMappings. | |
*/ | |
public void addSQLResultSetMapping(SQLResultSetMapping sqlResultSetMapping){ | |
if (sqlResultSetMapping == null || sqlResultSetMapping.getName() == null){ | |
return; | |
} | |
if (this.sqlResultSetMappings == null){ | |
this.sqlResultSetMappings = new HashMap(); | |
} | |
this.sqlResultSetMappings.put(sqlResultSetMapping.getName(), sqlResultSetMapping); | |
} | |
/** | |
* PUBLIC: | |
* Set all this project's descriptors to conform all read queries within the context of the unit of work. | |
*/ | |
public void conformAllDescriptors() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.setShouldAlwaysConformResultsInUnitOfWork(true); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Convert all the class-name-based settings in this project to actual class-based settings. | |
* This will also reset any class references to the version of the class from the class loader. | |
*/ | |
public void convertClassNamesToClasses(ClassLoader classLoader){ | |
Iterator ordered = orderedDescriptors.iterator(); | |
while (ordered.hasNext()){ | |
ClassDescriptor descriptor = (ClassDescriptor)ordered.next(); | |
descriptor.convertClassNamesToClasses(classLoader); | |
} | |
for (AttributeGroup group : this.getAttributeGroups().values()){ | |
group.convertClassNamesToClasses(classLoader); | |
} | |
// Clear old descriptors to allow rehash on new classes. | |
this.descriptors = new HashMap(); | |
// convert class names to classes for each SQLResultSetMapping | |
if (this.sqlResultSetMappings != null) { | |
for (SQLResultSetMapping mapping : this.sqlResultSetMappings.values()) { | |
mapping.convertClassNamesToClasses(classLoader); | |
} | |
} | |
if (this.partitioningPolicies != null) { | |
for (PartitioningPolicy policy : this.partitioningPolicies.values()) { | |
policy.convertClassNamesToClasses(classLoader); | |
} | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to assume existence for non-null primary keys. | |
*/ | |
public void assumeExistenceForDoesExist() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.getQueryManager().assumeExistenceForDoesExist(); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to check the cache for existence. | |
*/ | |
public void checkCacheForDoesExist() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.getQueryManager().checkCacheForDoesExist(); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to check the database for existence. | |
*/ | |
public void checkDatabaseForDoesExist() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.getQueryManager().checkDatabaseForDoesExist(); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Clones the descriptor | |
*/ | |
public Project clone() { | |
try { | |
return (Project) super.clone(); | |
} catch (CloneNotSupportedException exception) { | |
throw new InternalError(exception.toString()); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Factory method to create session. | |
* This returns an implementor of the DatabaseSession interface, which can be used to login | |
* and add descriptors from other projects. The Session interface however should be used for | |
* reading and writing once connected for complete portability. | |
*/ | |
public DatabaseSession createDatabaseSession() { | |
return new DatabaseSessionImpl(this); | |
} | |
/** | |
* PUBLIC: | |
* Factory method to create a server session. | |
* This returns an implementor of the Server interface, which can be used to login | |
* and add descriptors from other projects, configure connection pooling and acquire client sessions. | |
* <br> | |
* By default the ServerSession has a single shared read/write connection pool | |
* with 32 min/max connections and an initial of 1 connection. | |
*/ | |
public Server createServerSession() { | |
return new ServerSession(this); | |
} | |
/** | |
* PUBLIC: | |
* Factory method to create a server session. | |
* This returns an implementor of the Server interface, which can be used to login | |
* and add descriptors from other projects, configure connection pooling and acquire client sessions. | |
* Configure the min and max number of connections for the default shared read/write pool. | |
*/ | |
public Server createServerSession(int min, int max) { | |
return new ServerSession(this, min, max); | |
} | |
/** | |
* PUBLIC: | |
* Factory method to create a server session. | |
* This returns an implementor of the Server interface, which can be used to login | |
* and add descriptors from other projects, configure connection pooling and acquire client sessions. | |
* Configure the min and max number of connections for the default shared read/write pool. | |
*/ | |
public Server createServerSession(int initial, int min, int max) { | |
return new ServerSession(this, initial, min, max); | |
} | |
/** | |
* PUBLIC: | |
* Factory method to create a server session. | |
* This returns an implementor of the Server interface, which can be used to login | |
* and add descriptors from other projects, configure connection pooling and acquire client sessions. | |
* Configure the default connection policy to be used. | |
* This policy is used on the "acquireClientSession()" protocol. | |
* <br> | |
* By default the ServerSession has a single shared read/write connection pool | |
* with 32 min/max connections and an initial of 1 connection. | |
*/ | |
public Server createServerSession(ConnectionPolicy defaultConnectionPolicy) { | |
return new ServerSession(this, defaultConnectionPolicy); | |
} | |
/** | |
* PUBLIC: | |
* Returns the default set of read-only classes. | |
*/ | |
public Vector getDefaultReadOnlyClasses() { | |
return defaultReadOnlyClasses; | |
} | |
/** | |
* PUBLIC: | |
* Return default value for descriptor cache type. | |
*/ | |
public Class getDefaultIdentityMapClass() { | |
return this.defaultIdentityMapClass; | |
} | |
/** | |
* PUBLIC: | |
* Return default value descriptor cache size. | |
*/ | |
public int getDefaultIdentityMapSize() { | |
return this.defaultIdentityMapSize; | |
} | |
/** | |
* PUBLIC: | |
* Return default value for whether descriptor should use isolated cache. | |
* @deprecated see getDefaultCacheIsolation() | |
*/ | |
@Deprecated | |
public boolean getDefaultIsIsolated() { | |
return this.defaultCacheIsolation.equals(CacheIsolationType.ISOLATED); | |
} | |
/** | |
* PUBLIC: | |
* Return the project level default for class cache isolation; | |
*/ | |
public CacheIsolationType getDefaultCacheIsolation(){ | |
return this.defaultCacheIsolation; | |
} | |
/** | |
* PUBLIC: | |
* Return default value for descriptor primary key validation. | |
*/ | |
public IdValidation getDefaultIdValidation() { | |
return this.defaultIdValidation; | |
} | |
/** | |
* PUBLIC: | |
* Return the descriptor specified for the class. | |
* If the passed Class parameter is null, null will be returned. | |
*/ | |
public ClassDescriptor getClassDescriptor(Class theClass) { | |
return getDescriptor(theClass); | |
} | |
/** | |
* PUBLIC: | |
* Return the descriptor specified for the class. | |
*/ | |
public ClassDescriptor getDescriptor(Class theClass) { | |
if (theClass == null) { | |
return null; | |
} | |
return getDescriptors().get(theClass); | |
} | |
/** | |
* PUBLIC: | |
* Return the descriptors in a ClassDescriptors Map keyed on the Java class. | |
*/ | |
public Map<Class, ClassDescriptor> getDescriptors() { | |
// Lazy initialize class references from orderedDescriptors when reading from XML. | |
if (descriptors.isEmpty() && (!orderedDescriptors.isEmpty())) { | |
for (Iterator iterator = orderedDescriptors.iterator(); iterator.hasNext();) { | |
ClassDescriptor descriptor = (ClassDescriptor)iterator.next(); | |
descriptors.put(descriptor.getJavaClass(), descriptor); | |
} | |
} | |
return descriptors; | |
} | |
/** | |
* INTERNAL: | |
* Return the descriptors in the order added. | |
* Used to maintain consistent order in XML. | |
*/ | |
public List<ClassDescriptor> getOrderedDescriptors() { | |
return orderedDescriptors; | |
} | |
/** | |
* INTERNAL: | |
* Set the descriptors order. | |
* Used to maintain consistent order in XML. | |
*/ | |
public void setOrderedDescriptors(List<ClassDescriptor> orderedDescriptors) { | |
this.orderedDescriptors = orderedDescriptors; | |
for (ClassDescriptor descriptor : orderedDescriptors) { | |
String alias = descriptor.getAlias(); | |
if (alias != null) { | |
addAlias(alias, descriptor); | |
} | |
} | |
} | |
/** | |
* INTERNAL: | |
* Returns all classes in this project that are needed for weaving. | |
* This list currently includes entity, embeddables and mappedSuperClasses. | |
*/ | |
public Collection<String> getClassNamesForWeaving() { | |
return classNamesForWeaving; | |
} | |
/** | |
* INTERNAL: | |
* Returns all classes in this project that are needed for weaving. | |
* This list currently includes entity, embeddables and mappedSuperClasses. | |
*/ | |
public void setClassNamesForWeaving(Collection<String> classNamesForWeaving) { | |
this.classNamesForWeaving = classNamesForWeaving; | |
} | |
/** | |
* OBSOLETE: | |
* Return the login, the login holds any database connection information given. | |
* This has been replaced by getDatasourceLogin to make use of the Login interface | |
* to support non-relational datasources, | |
* if DatabaseLogin API is required it will need to be cast. | |
*/ | |
public DatabaseLogin getLogin() { | |
return (DatabaseLogin)datasourceLogin; | |
} | |
/** | |
* PUBLIC: | |
* Return the login, the login holds any database connection information given. | |
* This return the Login interface and may need to be cast to the datasource specific implementation. | |
*/ | |
@Override | |
public Login getDatasourceLogin() { | |
return datasourceLogin; | |
} | |
/** | |
* PUBLIC: | |
* get the name of the project. | |
*/ | |
public String getName() { | |
return name; | |
} | |
/** | |
* PUBLIC: | |
* Get a named SQLResultSetMapping from this project. These SQLResultSetMappings | |
* can be used by ResultSetMappingQueries to map Custom sql results to | |
* results as defined by the SQLResultSetMappings. | |
*/ | |
public SQLResultSetMapping getSQLResultSetMapping(String sqlResultSetMapping){ | |
if (sqlResultSetMapping == null || this.sqlResultSetMappings == null){ | |
return null; | |
} | |
return this.sqlResultSetMappings.get(sqlResultSetMapping); | |
} | |
/** | |
* INTERNAL: | |
* Returns structure converter class names that would be set on the databasePlatform instance | |
* This is used to avoid the platform instance changing at login. | |
*/ | |
public Collection<String> getStructConverters() { | |
return structConverters; | |
} | |
/** | |
* INTERNAL: | |
* Returns structure converter class names that would be set on the databasePlatform instance | |
* This is used to avoid the platform instance changing at login. | |
*/ | |
public void setStructConverters(Collection<String> structConverters) { | |
this.structConverters = structConverters; | |
} | |
/** | |
* INTERNAL: | |
* Return the name of the last class to set a VPD identifiers. | |
*/ | |
public String getVPDLastIdentifierClassName() { | |
return vpdLastIdentifierClassName; | |
} | |
/** | |
* INTERNAL: | |
* Return the VPD identifier for this project. | |
*/ | |
public String getVPDIdentifier() { | |
return vpdIdentifier; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public MultitenantPolicy getMultitenantPolicy() { | |
return multitenantPolicy; | |
} | |
/** | |
* INTERNAL: | |
* Answers if at least one Descriptor or Mapping had a HistoryPolicy at initialize time. | |
*/ | |
public boolean hasGenericHistorySupport() { | |
return hasGenericHistorySupport; | |
} | |
/** | |
* PUBLIC: | |
* Set the read-only classes which apply to each UnitOfWork create by default. | |
*/ | |
public void setDefaultReadOnlyClasses(Collection newValue) { | |
this.defaultReadOnlyClasses = new Vector(newValue); | |
} | |
/** | |
* PUBLIC: | |
* Set default value for descriptor cache type. | |
*/ | |
public void setDefaultIdentityMapClass(Class defaultIdentityMapClass) { | |
this.defaultIdentityMapClass = defaultIdentityMapClass; | |
} | |
/** | |
* PUBLIC: | |
* Set default value descriptor cache size. | |
*/ | |
public void setDefaultIdentityMapSize(int defaultIdentityMapSize) { | |
this.defaultIdentityMapSize = defaultIdentityMapSize; | |
} | |
/** | |
* PUBLIC: | |
* Set default value for whether descriptor should use isolated cache. | |
* @deprecated see setDefaultCacheIsolation(CacheIsolationType) | |
*/ | |
@Deprecated | |
public void setDefaultIsIsolated(boolean defaultIsIsolated) { | |
this.defaultCacheIsolation = defaultIsIsolated ? CacheIsolationType.ISOLATED : CacheIsolationType.SHARED; | |
} | |
/** | |
* PUBLIC: | |
* Set project level default value for class cache isolation. | |
*/ | |
public void setDefaultCacheIsolation(CacheIsolationType isolationType) { | |
this.defaultCacheIsolation = isolationType; | |
} | |
/** | |
* PUBLIC: | |
* Set default value for descriptor primary key validation. | |
*/ | |
public void setDefaultIdValidation(IdValidation defaultIdValidation) { | |
this.defaultIdValidation = defaultIdValidation; | |
} | |
/** | |
* INTERNAL: | |
* Set the descriptors registered with this session. | |
*/ | |
public void setDescriptors(Map descriptors) { | |
this.descriptors = descriptors; | |
for (Iterator iterator = descriptors.values().iterator(); iterator.hasNext();) { | |
ClassDescriptor descriptor = (ClassDescriptor)iterator.next(); | |
String alias = descriptor.getAlias(); | |
if (alias != null) { | |
addAlias(alias, descriptor); | |
} | |
} | |
} | |
/** | |
* ADVANCED: | |
* This method is a 'helper' method for updating all of the descriptors | |
* within this project to have a particular deferral level. The levels are | |
* as follows | |
* ClassDescriptor.ALL_MODIFICATIONS - this is the default and recommended. | |
* The writing of all changes will be deferred until the end of the | |
* transaction | |
* ClassDescriptor.UPDATE_MODIFICATIONS - this will cause the update changes to | |
* be deferred and all other changes to be written immediately. | |
* ClassDescriptor.NONE - this will cause all changes to be written on each | |
* container call. | |
*/ | |
public void setDeferModificationsUntilCommit(int deferralLevel) { | |
for (Iterator iterator = descriptors.values().iterator(); iterator.hasNext();) { | |
ClassDescriptor descriptor = (ClassDescriptor)iterator.next(); | |
if (descriptor.getCMPPolicy() != null) { | |
descriptor.getCMPPolicy().setDeferModificationsUntilCommit(deferralLevel); | |
} | |
} | |
} | |
/** | |
* INTERNAL: | |
* Set to true during descriptor initialize if any descriptor has history. | |
*/ | |
public void setHasGenericHistorySupport(boolean hasGenericHistorySupport) { | |
this.hasGenericHistorySupport = hasGenericHistorySupport; | |
} | |
/** | |
* INTERNAL: | |
* Return whether this project has a descriptor that is both Isolated and | |
* has a cache isolation level other than ISOLATE_CACHE_ALWAYS | |
* @return | |
*/ | |
public boolean hasIsolatedCacheClassWithoutUOWIsolation(){ | |
// checked cached boolean to avoid iteration | |
if (!hasIsolatedClasses){ | |
return false; | |
} | |
Iterator<ClassDescriptor> i = orderedDescriptors.iterator(); | |
while (i.hasNext()){ | |
ClassDescriptor descriptor = i.next(); | |
if (descriptor.getCachePolicy().isIsolated() && !descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork()) { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* INTERNAL: | |
* Return if any descriptors are isolated. | |
* Set to true during descriptor initialize if any descriptor is isolated. | |
* Determines if an isolated client session is required. | |
*/ | |
public boolean hasIsolatedClasses() { | |
return hasIsolatedClasses; | |
} | |
/** | |
* INTERNAL: | |
* Set to true during descriptor initialize if any descriptor is isolated. | |
* Determines if an isolated client session is required. | |
*/ | |
public void setHasIsolatedClasses(boolean hasIsolatedClasses) { | |
this.hasIsolatedClasses = hasIsolatedClasses; | |
} | |
/** | |
* INTERNAL: | |
* Return if any descriptors are not isolated to the unit of work. | |
* Set to true during descriptor initialize if any descriptor is not isolated. | |
* Allows uow merge to be bypassed. | |
*/ | |
public boolean hasNonIsolatedUOWClasses() { | |
return hasNonIsolatedUOWClasses; | |
} | |
/** | |
* INTERNAL: | |
* Set if any descriptors are not isolated to the unit of work. | |
* Set to true during descriptor initialize if any descriptor is not isolated. | |
* Allows uow merge to be bypassed. | |
*/ | |
public void setHasNonIsolatedUOWClasses(boolean hasNonIsolatedUOWClasses) { | |
this.hasNonIsolatedUOWClasses = hasNonIsolatedUOWClasses; | |
} | |
/** | |
* INTERNAL: | |
* Return if any descriptors use ProxyIndirection. | |
* Set to true during descriptor initialize if any descriptor uses ProxyIndirection | |
* Determines if ProxyIndirectionPolicy.getValueFromProxy should be called. | |
*/ | |
public boolean hasProxyIndirection() { | |
return this.hasProxyIndirection; | |
} | |
/** | |
* PUBLIC: | |
* Return true if the sql result set mapping name exists. | |
*/ | |
public boolean hasSQLResultSetMapping(String sqlResultSetMapping) { | |
return sqlResultSetMappings.containsKey(sqlResultSetMapping); | |
} | |
/** | |
* PUBLIC: | |
* Return true if there is a VPD identifier for this project. Will not be | |
* set till after descriptor initialization. | |
*/ | |
public boolean hasVPDIdentifier(AbstractSession session) { | |
return (vpdIdentifier != null && session.getProperty(vpdIdentifier) != null); | |
} | |
/** | |
* INTERNAL: | |
* Set to true during descriptor initialize if any descriptor uses ProxyIndirection | |
* Determines if ProxyIndirectionPolicy.getValueFromProxy should be called. | |
*/ | |
public void setHasProxyIndirection(boolean hasProxyIndirection) { | |
this.hasProxyIndirection = hasProxyIndirection; | |
} | |
/** | |
* PUBLIC: | |
* Set the login to be used to connect to the database for this project. | |
*/ | |
public void setLogin(DatabaseLogin datasourceLogin) { | |
this.datasourceLogin = datasourceLogin; | |
} | |
/** | |
* INTERNAL: | |
* Set the multitenant policy. | |
*/ | |
public void setMultitenantPolicy(MultitenantPolicy policy) { | |
multitenantPolicy = policy; | |
} | |
/** | |
* PUBLIC: | |
* Set the login to be used to connect to the database for this project. | |
*/ | |
public void setLogin(Login datasourceLogin) { | |
this.datasourceLogin = datasourceLogin; | |
} | |
/** | |
* PUBLIC: | |
* Set the login to be used to connect to the database for this project. | |
*/ | |
public void setDatasourceLogin(Login datasourceLogin) { | |
this.datasourceLogin = datasourceLogin; | |
} | |
/** | |
* PUBLIC: | |
* Set the name of the project. | |
*/ | |
public void setName(String name) { | |
this.name = name; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public String toString() { | |
return Helper.getShortClassName(getClass()) + "(" + getName() + ")"; | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to use the cache identity map. | |
*/ | |
public void useCacheIdentityMap() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.useCacheIdentityMap(); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to use the cache identity map the size. | |
*/ | |
public void useCacheIdentityMap(int cacheSize) { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.useCacheIdentityMap(); | |
descriptor.setIdentityMapSize(cacheSize); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to use the full identity map. | |
*/ | |
public void useFullIdentityMap() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.useFullIdentityMap(); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to use the full identity map with initial cache size. | |
*/ | |
public void useFullIdentityMap(int initialCacheSize) { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.useFullIdentityMap(); | |
descriptor.setIdentityMapSize(initialCacheSize); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to use no identity map. | |
*/ | |
public void useNoIdentityMap() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.useNoIdentityMap(); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to use the soft cache weak identity map. | |
*/ | |
public void useSoftCacheWeakIdentityMap() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.useSoftCacheWeakIdentityMap(); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to use the soft cache weak identity map with soft cache size. | |
*/ | |
public void useSoftCacheWeakIdentityMap(int cacheSize) { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.useSoftCacheWeakIdentityMap(); | |
descriptor.setIdentityMapSize(cacheSize); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Asks each descriptor if is uses optimistic locking. | |
*/ | |
public boolean usesOptimisticLocking() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
if (descriptor.usesOptimisticLocking()) { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* INTERNAL: | |
* Asks each descriptor if is uses sequencing. | |
*/ | |
public boolean usesSequencing() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
if (descriptor.usesSequenceNumbers()) { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to use the weak identity map. | |
*/ | |
public void useWeakIdentityMap() { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.useWeakIdentityMap(); | |
} | |
} | |
/** | |
* PUBLIC: | |
* Switch all descriptors to use the weak identity map. | |
*/ | |
public void useWeakIdentityMap(int initialCacheSize) { | |
Iterator descriptors = getDescriptors().values().iterator(); | |
while (descriptors.hasNext()) { | |
ClassDescriptor descriptor = (ClassDescriptor)descriptors.next(); | |
descriptor.useWeakIdentityMap(); | |
descriptor.setIdentityMapSize(initialCacheSize); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Default apply login implementation. | |
* Defined for generated subclasses that may not have a login. | |
* BUG#2669342 | |
*/ | |
public void applyLogin() { | |
// Do nothing by default. | |
} | |
/** | |
* INTERNAL: | |
* Returns the alias descriptors hashtable. | |
*/ | |
public Map getAliasDescriptors() { | |
return aliasDescriptors; | |
} | |
/** | |
* PUBLIC: | |
* Add an alias for the descriptor. | |
*/ | |
public void addAlias(String alias, ClassDescriptor descriptor) { | |
if (aliasDescriptors == null) { | |
aliasDescriptors = new HashMap(10); | |
} | |
aliasDescriptors.put(alias, descriptor); | |
} | |
/** | |
* INTERNAL: | |
* Return true if native sql is allowed on this project. | |
*/ | |
public boolean allowTablePerMultitenantDDLGeneration() { | |
return this.allowTablePerMultitenantDDLGeneration; | |
} | |
/** | |
* INTERNAL: | |
* Return true if native sql is allowed on this project. | |
*/ | |
public boolean allowNativeSQLQueries() { | |
return this.allowNativeSQLQueries; | |
} | |
/** | |
* PUBLIC: | |
* Return the descriptor for the alias | |
*/ | |
public ClassDescriptor getDescriptorForAlias(String alias) { | |
ClassDescriptor descriptor = null; | |
if (aliasDescriptors != null) { | |
descriptor = (ClassDescriptor)aliasDescriptors.get(alias); | |
} | |
return descriptor; | |
} | |
/** | |
* INTERNAL: | |
* Set the alias descriptors hashtable. | |
*/ | |
public void setAliasDescriptors(Map aHashtable) { | |
aliasDescriptors = aHashtable; | |
} | |
/** | |
* INTERNAL: | |
* Set whether ddl generation should allowed for table per tenant | |
* multitenant descriptors. This will only be true when a non shared emf | |
* is used and all the tenant context properties are provided at deploy | |
* time. | |
*/ | |
public void setAllowTablePerMultitenantDDLGeneration(boolean allowTablePerMultitenantDDLGeneration) { | |
this.allowTablePerMultitenantDDLGeneration = allowTablePerMultitenantDDLGeneration; | |
} | |
/** | |
* INTERNAL: | |
* Set whether native sql is allowed on this project. | |
*/ | |
public void setAllowNativeSQLQueries(boolean allowNativeSQLQueries) { | |
this.allowNativeSQLQueries = allowNativeSQLQueries; | |
} | |
/** | |
* INTERNAL: | |
* Indicates whether there is at least one descriptor that has at least on mapping that | |
* require a call on deleted objects to update change sets. | |
*/ | |
public boolean hasMappingsPostCalculateChangesOnDeleted() { | |
return hasMappingsPostCalculateChangesOnDeleted; | |
} | |
/** | |
* INTERNAL: | |
* Indicates whether there is at least one descriptor that has at least on mapping that | |
* require a call on deleted objects to update change sets. | |
*/ | |
public void setHasMappingsPostCalculateChangesOnDeleted(boolean hasMappingsPostCalculateChangesOnDeleted) { | |
this.hasMappingsPostCalculateChangesOnDeleted = hasMappingsPostCalculateChangesOnDeleted; | |
} | |
/** | |
* INTERNAL: | |
* Return whether there any mappings that are mapped superclasses. | |
* @return | |
* @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation | |
*/ | |
public boolean hasMappedSuperclasses() { | |
return (null != this.mappedSuperclassDescriptors && !this.mappedSuperclassDescriptors.isEmpty()); | |
} | |
/** | |
* INTERNAL: | |
* Return whether the given class is mapped as superclass. | |
* @param className | |
* @return | |
* @since EclipseLink 2.3 for the JPA 2.0 Reference Implementation | |
*/ | |
public boolean hasMappedSuperclass(String className) { | |
if (!hasMappedSuperclasses()) { | |
return false; | |
} | |
return this.mappedSuperclassDescriptors.containsKey(className); | |
} | |
/** | |
* INTERNAL: | |
* Return all pre-defined not yet parsed EJBQL queries. | |
*/ | |
public void addJPAQuery(DatabaseQuery query) { | |
getJPAQueries().add(query); | |
} | |
/** | |
* INTERNAL: | |
* Return all pre-defined not yet parsed EJBQL queries to table per tenant entities. | |
*/ | |
public void addJPATablePerTenantQuery(DatabaseQuery query) { | |
getJPATablePerTenantQueries().add(query); | |
} | |
/** | |
* INTERNAL: | |
* 266912: Add a descriptor to the Map of mappedSuperclass descriptors | |
* @param key (Metadata class) | |
* @param value (RelationalDescriptor) | |
* @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation | |
*/ | |
public void addMappedSuperclass(String key, ClassDescriptor value, boolean replace) { | |
// Lazy initialization of the mappedSuperclassDescriptors field. | |
if(null == this.mappedSuperclassDescriptors) { | |
this.mappedSuperclassDescriptors = new HashMap<String, ClassDescriptor>(2); | |
} | |
// Avoid replacing the current RelationalDescriptor that may have mappings set | |
if(replace || !this.mappedSuperclassDescriptors.containsKey(key)) { | |
this.mappedSuperclassDescriptors.put(key, value); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Use the Metadata key parameter to lookup the | |
* Descriptor from the Map of mappedSuperclass descriptors | |
* @param key - theMetadata class | |
* @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation | |
*/ | |
public ClassDescriptor getMappedSuperclass(String key) { | |
// TODO: this implementation may have side effects when we have the same class | |
// in different class loaders - however currently there is only one classLoader per project | |
// Lazy initialization of the mappedSuperclassDescriptors field. | |
if(null == this.mappedSuperclassDescriptors) { | |
this.mappedSuperclassDescriptors = new HashMap<String, ClassDescriptor>(2); | |
return null; | |
} | |
return this.mappedSuperclassDescriptors.get(key); | |
} | |
/** | |
* INTERNAL: | |
* Return the Map of RelationalDescriptor objects representing mapped superclass parents | |
* keyed by className of the metadata class. | |
* @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation | |
*/ | |
public Map<String, ClassDescriptor> getMappedSuperclassDescriptors() { | |
// Lazy initialization of the mappedSuperclassDescriptors field. | |
if(null == this.mappedSuperclassDescriptors) { | |
this.mappedSuperclassDescriptors = new HashMap<String, ClassDescriptor>(2); | |
} | |
return this.mappedSuperclassDescriptors; | |
} | |
/** | |
* INTERNAL: | |
* Add an IdClass entry to the map of ids for a particular owner | |
* This function is used exclusively by the Metamodel API. | |
* @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation | |
*/ | |
public void addMetamodelIdClassMapEntry(String ownerName, String name) { | |
// Add a possible composite key to the owner - this function will handle duplicates by overwriting the entry | |
if(this.metamodelIdClassMap.containsKey(ownerName)) { | |
// If we have a key entry then the list will always exist | |
this.metamodelIdClassMap.get(ownerName).add(name); | |
} else { | |
List<String> ownerList = new ArrayList<String>(); | |
ownerList.add(name); | |
this.metamodelIdClassMap.put(ownerName, ownerList); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Return the Map of IdClass attribute lists keyed on owner class name. | |
* @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation | |
*/ | |
public Map<String, List<String>> getMetamodelIdClassMap() { | |
return metamodelIdClassMap; | |
} | |
/** | |
* PUBLIC: | |
* Return the map of partitioning policies, keyed by name. | |
*/ | |
public Map<String, PartitioningPolicy> getPartitioningPolicies() { | |
if (this.partitioningPolicies == null) { | |
this.partitioningPolicies = new HashMap<String, PartitioningPolicy>(); | |
} | |
return partitioningPolicies; | |
} | |
/** | |
* PUBLIC: | |
* Set the map of partitioning policies, keyed by name. | |
*/ | |
public void setPartitioningPolicies(Map<String, PartitioningPolicy> partitioningPolicies) { | |
this.partitioningPolicies = partitioningPolicies; | |
} | |
/** | |
* PUBLIC: | |
* Set the map of partitioning policies, keyed by name. | |
*/ | |
public void addPartitioningPolicy(PartitioningPolicy partitioningPolicy) { | |
getPartitioningPolicies().put(partitioningPolicy.getName(), partitioningPolicy); | |
} | |
/** | |
* PUBLIC: | |
* Return the partitioning policies for the name. | |
*/ | |
public PartitioningPolicy getPartitioningPolicy(String name) { | |
if (this.partitioningPolicies == null) { | |
return null; | |
} | |
return this.partitioningPolicies.get(name); | |
} | |
} | |