| /* |
| * Copyright (c) 1998, 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: |
| // 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 |
| // 04/11/2018 - Will Dazey |
| // - 533148 : Add the eclipselink.jpa.sql-call-deferral property |
| package org.eclipse.persistence.sessions; |
| |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| 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.helper.ConcurrentFixedCache; |
| import org.eclipse.persistence.internal.helper.Helper; |
| import org.eclipse.persistence.internal.helper.NonSynchronizedVector; |
| import org.eclipse.persistence.internal.identitymaps.AbstractIdentityMap; |
| import org.eclipse.persistence.internal.identitymaps.IdentityMap; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl; |
| 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.ConnectionPolicy; |
| import org.eclipse.persistence.sessions.server.Server; |
| import org.eclipse.persistence.sessions.server.ServerSession; |
| |
| /** |
| * <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 {@literal &} 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<Class<?>> defaultReadOnlyClasses; |
| |
| /** Cache the EJBQL descriptor aliases. */ |
| protected Map<String, ClassDescriptor> 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<? extends IdentityMap> 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; |
| |
| /** Flag that allows call deferral to be disabled */ |
| protected boolean allowSQLDeferral = true; |
| |
| /** Flag that allows transform named stored procedure parameters into positional/index based */ |
| protected boolean namingIntoIndexed = false; |
| |
| /** Flag that allows extended logging of JPA L2 cache or not. */ |
| protected boolean allowExtendedCacheLogging = false; |
| |
| /** Flag that allows extended thread logging or not. */ |
| protected boolean allowExtendedThreadLogging = false; |
| |
| /** Flag that allows add to extended thread logging output thread stack trace or not.*/ |
| protected boolean allowExtendedThreadLoggingThreadDump = 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 = 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; |
| |
| /** Force all queries and relationships to use deferred lock strategy during object building and L2 cache population. */ |
| protected boolean queryCacheForceDeferredLocks = false; |
| |
| /** |
| * PUBLIC: |
| * Create a new project. |
| */ |
| public Project() { |
| this.name = ""; |
| this.descriptors = new HashMap<>(); |
| this.defaultReadOnlyClasses = NonSynchronizedVector.newInstance(); |
| this.orderedDescriptors = new ArrayList<>(); |
| this.hasIsolatedClasses = false; |
| this.hasGenericHistorySupport = false; |
| this.hasProxyIndirection = false; |
| this.jpqlParseCache = new ConcurrentFixedCache(200); |
| this.queries = new ArrayList<>(); |
| this.mappedSuperclassDescriptors = new HashMap<>(2); |
| this.metamodelIdClassMap = new HashMap<>(); |
| this.attributeGroups = new HashMap<>(); |
| } |
| |
| /** |
| * 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: |
| * Get property to Force all queries and relationships to use deferred lock strategy during object building and L2 cache population. |
| */ |
| public boolean isQueryCacheForceDeferredLocks() { |
| return queryCacheForceDeferredLocks; |
| } |
| |
| /** |
| * PUBLIC: |
| * Set property to Force all queries and relationships to use deferred lock strategy during object building and L2 cache population. |
| * By default there is false value - use use mixed object cache locking strategy (depends on relationship and fetch type) */ |
| public void setQueryCacheForceDeferredLocks(boolean queryCacheForceDeferredLocks) { |
| this.queryCacheForceDeferredLocks = queryCacheForceDeferredLocks; |
| } |
| |
| /** |
| * 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: |
| */ |
| 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. |
| */ |
| @Override |
| 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. |
| * @param descriptor The descriptor to be added to the session and the project. |
| * @param session The current database session. |
| */ |
| public void addDescriptor(final ClassDescriptor descriptor, final DatabaseSessionImpl session) { |
| synchronized (this.descriptorsLock) { |
| if (session.isConnected()) { |
| final 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) { |
| @SuppressWarnings({"unchecked"}) |
| final Map<String, ClassDescriptor> aliasDescriptorsClone = getAliasDescriptors() != null |
| ? (Map<String, ClassDescriptor>)((HashMap<String, ClassDescriptor>) getAliasDescriptors()).clone() |
| : 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. |
| @SuppressWarnings({"unchecked"}) |
| final Map<Class<?>, ClassDescriptor> descriptorsClone = (Map<Class<?>, ClassDescriptor>)((HashMap<Class<?>, ClassDescriptor>) getDescriptors()).clone(); |
| descriptorsClone.put(descriptor.getJavaClass(), descriptor); |
| setDescriptors(descriptorsClone); |
| session.copyDescriptorsFromProject(); |
| session.initializeDescriptorIfSessionAlive(descriptor); |
| getOrderedDescriptors().add(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. |
| * @param descriptors The descriptors to be added to the session and the project. |
| * @param session The current database session. |
| */ |
| public void addDescriptors(final Collection descriptors, final 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. |
| @SuppressWarnings({"unchecked"}) |
| final Map<String, ClassDescriptor> aliasDescriptorsClone = getAliasDescriptors() != null |
| ? (Map<String, ClassDescriptor>)((HashMap<String, ClassDescriptor>) getAliasDescriptors()).clone() |
| : new HashMap<>(); |
| // Descriptors may be concurrently accessed by other threads. |
| // Make a clone, add new descriptors to the clone, override original with the clone. |
| @SuppressWarnings({"unchecked"}) |
| final Map<Class<?>, ClassDescriptor> descriptorsClone = (Map<Class<?>, ClassDescriptor>)((HashMap<Class<?>, ClassDescriptor>) getDescriptors()).clone(); |
| for (ClassDescriptor descriptor : (Collection<ClassDescriptor>) descriptors) { |
| descriptorsClone.put(descriptor.getJavaClass(), descriptor); |
| final String alias = descriptor.getAlias(); |
| if (alias != null) { |
| aliasDescriptorsClone.put(alias, descriptor); |
| } |
| } |
| if (!aliasDescriptorsClone.isEmpty()) { |
| setAliasDescriptors(aliasDescriptorsClone); |
| } |
| setDescriptors(descriptorsClone); |
| session.copyDescriptorsFromProject(); |
| session.initializeDescriptors(descriptors); |
| } else { |
| final Map<Class<?>, ClassDescriptor> projectDescriptors = getDescriptors(); |
| for (ClassDescriptor descriptor : (Collection<ClassDescriptor>) descriptors) { |
| final String alias = descriptor.getAlias(); |
| projectDescriptors.put(descriptor.getJavaClass(), descriptor); |
| 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<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = 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. |
| */ |
| @Override |
| public void convertClassNamesToClasses(ClassLoader classLoader){ |
| Iterator<ClassDescriptor> ordered = orderedDescriptors.iterator(); |
| while (ordered.hasNext()){ |
| ClassDescriptor descriptor = 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<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.getQueryManager().assumeExistenceForDoesExist(); |
| } |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to check the cache for existence. |
| */ |
| public void checkCacheForDoesExist() { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.getQueryManager().checkCacheForDoesExist(); |
| } |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to check the database for existence. |
| */ |
| public void checkDatabaseForDoesExist() { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.getQueryManager().checkDatabaseForDoesExist(); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Clones the descriptor |
| */ |
| @Override |
| 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. |
| */ |
| @Override |
| 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<? extends IdentityMap> getDefaultIdentityMapClass() { |
| return this.defaultIdentityMapClass; |
| } |
| |
| /** |
| * PUBLIC: |
| * Return default value descriptor cache size. |
| */ |
| public int getDefaultIdentityMapSize() { |
| return this.defaultIdentityMapSize; |
| } |
| |
| /** |
| * 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. |
| */ |
| @Override |
| 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<ClassDescriptor> iterator = orderedDescriptors.iterator(); iterator.hasNext();) { |
| ClassDescriptor descriptor = iterator.next(); |
| descriptors.put(descriptor.getJavaClass(), descriptor); |
| } |
| } |
| return descriptors; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the descriptors in the order added. |
| * Used to maintain consistent order in XML. |
| */ |
| @Override |
| 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<? extends IdentityMap> defaultIdentityMapClass) { |
| this.defaultIdentityMapClass = defaultIdentityMapClass; |
| } |
| |
| /** |
| * PUBLIC: |
| * Set default value descriptor cache size. |
| */ |
| public void setDefaultIdentityMapSize(int defaultIdentityMapSize) { |
| this.defaultIdentityMapSize = defaultIdentityMapSize; |
| } |
| |
| /** |
| * 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<ClassDescriptor> iterator = descriptors.values().iterator(); iterator.hasNext();) { |
| ClassDescriptor descriptor = 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<ClassDescriptor> iterator = descriptors.values().iterator(); iterator.hasNext();) { |
| ClassDescriptor descriptor = 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 |
| */ |
| 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. |
| */ |
| @Override |
| 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: |
| */ |
| @Override |
| public String toString() { |
| return Helper.getShortClassName(getClass()) + "(" + getName() + ")"; |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to use the cache identity map. |
| */ |
| public void useCacheIdentityMap() { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.useCacheIdentityMap(); |
| } |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to use the cache identity map the size. |
| */ |
| public void useCacheIdentityMap(int cacheSize) { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.useCacheIdentityMap(); |
| descriptor.setIdentityMapSize(cacheSize); |
| } |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to use the full identity map. |
| */ |
| public void useFullIdentityMap() { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.useFullIdentityMap(); |
| } |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to use the full identity map with initial cache size. |
| */ |
| public void useFullIdentityMap(int initialCacheSize) { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.useFullIdentityMap(); |
| descriptor.setIdentityMapSize(initialCacheSize); |
| } |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to use no identity map. |
| */ |
| public void useNoIdentityMap() { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.useNoIdentityMap(); |
| } |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to use the soft cache weak identity map. |
| */ |
| public void useSoftCacheWeakIdentityMap() { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = 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<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.useSoftCacheWeakIdentityMap(); |
| descriptor.setIdentityMapSize(cacheSize); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Asks each descriptor if is uses optimistic locking. |
| */ |
| public boolean usesOptimisticLocking() { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| if (descriptor.usesOptimisticLocking()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * INTERNAL: |
| * Asks each descriptor if is uses sequencing. |
| */ |
| public boolean usesSequencing() { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| if (descriptor.usesSequenceNumbers()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to use the weak identity map. |
| */ |
| public void useWeakIdentityMap() { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = descriptors.next(); |
| descriptor.useWeakIdentityMap(); |
| } |
| } |
| |
| /** |
| * PUBLIC: |
| * Switch all descriptors to use the weak identity map. |
| */ |
| public void useWeakIdentityMap(int initialCacheSize) { |
| Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor descriptor = 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<String, ClassDescriptor> 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; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return true if SQL calls can defer to EOT on this project. |
| */ |
| public boolean allowSQLDeferral() { |
| return this.allowSQLDeferral; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return true is allowed to transform named stored procedure parameters into positional/index based. |
| */ |
| public boolean namingIntoIndexed() { |
| return this.namingIntoIndexed; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return true if extended logging of JPA L2 cache usage is allowed on this project. |
| */ |
| public boolean allowExtendedCacheLogging() { |
| return this.allowExtendedCacheLogging; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return true if extended thread logging is allowed on this project. |
| */ |
| public boolean allowExtendedThreadLogging() { |
| return this.allowExtendedThreadLogging; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return true if thread dumps will be added to extended thread logging. |
| */ |
| public boolean allowExtendedThreadLoggingThreadDump() { |
| return this.allowExtendedThreadLoggingThreadDump; |
| } |
| |
| /** |
| * PUBLIC: |
| * Return the descriptor for the alias |
| */ |
| public ClassDescriptor getDescriptorForAlias(String alias) { |
| ClassDescriptor descriptor = null; |
| if (aliasDescriptors != null) { |
| descriptor = aliasDescriptors.get(alias); |
| } |
| return descriptor; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set the alias descriptors hashtable. |
| */ |
| public void setAliasDescriptors(Map<String, ClassDescriptor> 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: |
| * Set whether sql deferral is allowed on this project |
| */ |
| public void setAllowSQLDeferral(boolean allowSQLDeferral) { |
| this.allowSQLDeferral = allowSQLDeferral; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set whether named stored procedure parameters is allowed to transform into positional/index based. |
| */ |
| public void setNamingIntoIndexed(boolean namingIntoIndexed) { |
| this.namingIntoIndexed = namingIntoIndexed; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set whether extended logging of JPA L2 cache usage is allowed on this project. |
| */ |
| public void setAllowExtendedCacheLogging(boolean allowExtendedCacheLogging) { |
| this.allowExtendedCacheLogging = allowExtendedCacheLogging; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set whether extended thread logging is allowed on this project. |
| */ |
| public void setAllowExtendedThreadLogging(boolean allowExtendedThreadLogging) { |
| this.allowExtendedThreadLogging = allowExtendedThreadLogging; |
| } |
| |
| /** |
| * INTERNAL: |
| * Set if thread dumps will be added to extended thread logging. |
| */ |
| public void setAllowExtendedThreadLoggingThreadDump(boolean allowExtendedThreadLoggingThreadDump) { |
| this.allowExtendedThreadLoggingThreadDump = allowExtendedThreadLoggingThreadDump; |
| } |
| |
| /** |
| * 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. |
| * @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. |
| * @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<>(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<>(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<>(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<>(); |
| 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<>(); |
| } |
| 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); |
| } |
| } |
| |