/** * INTERNAL: * Assumes a call to hasSingleTableMultitenant has been made before hand. */ public Map<String, List<DatabaseField>> getSingleTableMultitenantFields() { return ((SingleTableMultitenantPolicy) m_descriptor.getMultitenantPolicy()).getTenantDiscriminatorFieldsKeyedOnContext(); }
/** * PUBLIC * @return true if this descriptor is configured with a table per tenant policy. */ public boolean hasTablePerMultitenantPolicy() { return hasMultitenantPolicy() && getMultitenantPolicy().isTablePerMultitenantPolicy(); }
/** * PUBLIC * @return true if this descriptor is configured with a table per tenant policy. */ public boolean hasTablePerMultitenantPolicy() { return hasMultitenantPolicy() && getMultitenantPolicy().isTablePerMultitenantPolicy(); }
/** * INTERNAL: * Indicates if single table multitenant metadata has been processed for * this descriptor. */ public boolean hasSingleTableMultitenant() { return hasMultitenant() && m_descriptor.getMultitenantPolicy().isSingleTableMultitenantPolicy(); }
/** * INTERNAL: * Aggregate and Interface descriptors do not require initialization as they are cloned and * initialized by each mapping. Descriptors with table per tenant policies are cloned per * client session (per tenant) so do not initialize the original descriptor. */ public boolean requiresInitialization(AbstractSession session) { // If we are an aggregate or interface descriptor we do not require initialization. if (isDescriptorTypeAggregate() || isDescriptorForInterface()) { return false; } // If we have a table per tenant policy then check for our tenant // context property. If it is available from the session, set it and // return true to initialize. Otherwise do not initialize the // descriptor (it will be initialized per client session). if (hasTablePerMultitenantPolicy()) { return ((TablePerMultitenantPolicy) getMultitenantPolicy()).shouldInitialize(session); } // By default it should be initialized. return true; }
/** * INTERNAL: * Aggregate and Interface descriptors do not require initialization as they are cloned and * initialized by each mapping. Descriptors with table per tenant policies are cloned per * client session (per tenant) so do not initialize the original descriptor. */ public boolean requiresInitialization(AbstractSession session) { // If we are an aggregate or interface descriptor we do not require initialization. if (isDescriptorTypeAggregate() || isDescriptorForInterface()) { return false; } // If we have a table per tenant policy then check for our tenant // context property. If it is available from the session, set it and // return true to initialize. Otherwise do not initialize the // descriptor (it will be initialized per client session). if (hasTablePerMultitenantPolicy()) { return ((TablePerMultitenantPolicy) getMultitenantPolicy()).shouldInitialize(session); } // By default it should be initialized. return true; }
/** * INTERNAL: * All the target relation key field names are converted to DatabaseField and stored. */ protected void initializeTargetRelationKeys(ForeignReferenceMapping mapping) { if (getTargetRelationKeyFields().size() == 0) { throw DescriptorException.noTargetRelationKeysSpecified(mapping); } for (Enumeration targetEnum = getTargetRelationKeyFields().elements(); targetEnum.hasMoreElements();) { DatabaseField field = (DatabaseField)targetEnum.nextElement(); // Update the fields table first if the mapping is from a table per tenant entity. ClassDescriptor referenceDescriptor = mapping.getReferenceDescriptor(); if (referenceDescriptor.hasTablePerMultitenantPolicy()) { field.setTable(((TablePerMultitenantPolicy) referenceDescriptor.getMultitenantPolicy()).getTable(field.getTable())); } if (field.hasTableName() && (!(field.getTableName().equals(getRelationTable().getName())))) { throw DescriptorException.relationKeyFieldNotProperlySpecified(field, mapping); } field.setTable(getRelationTable()); } }
/** * INTERNAL: * All the source relation key field names are converted to DatabaseField and stored. */ protected void initializeSourceRelationKeys(ForeignReferenceMapping mapping) throws DescriptorException { if (getSourceRelationKeyFields().size() == 0) { throw DescriptorException.noSourceRelationKeysSpecified(mapping); } for (Enumeration entry = getSourceRelationKeyFields().elements(); entry.hasMoreElements();) { DatabaseField field = (DatabaseField)entry.nextElement(); // Update the fields table first if the mapping is from a table per tenant entity. ClassDescriptor sourceDescriptor = mapping.getDescriptor(); if (sourceDescriptor.hasTablePerMultitenantPolicy()) { field.setTable(((TablePerMultitenantPolicy) sourceDescriptor.getMultitenantPolicy()).getTable(field.getTable())); } if (field.hasTableName() && (!(field.getTableName().equals(getRelationTable().getName())))) { throw DescriptorException.relationKeyFieldNotProperlySpecified(field, mapping); } field.setTable(getRelationTable()); } }
/** * INTERNAL: * All the source relation key field names are converted to DatabaseField and stored. */ protected void initializeSourceRelationKeys(ForeignReferenceMapping mapping) throws DescriptorException { if (getSourceRelationKeyFields().size() == 0) { throw DescriptorException.noSourceRelationKeysSpecified(mapping); } for (Enumeration entry = getSourceRelationKeyFields().elements(); entry.hasMoreElements();) { DatabaseField field = (DatabaseField)entry.nextElement(); // Update the fields table first if the mapping is from a table per tenant entity. ClassDescriptor sourceDescriptor = mapping.getDescriptor(); if (sourceDescriptor.hasTablePerMultitenantPolicy()) { field.setTable(((TablePerMultitenantPolicy) sourceDescriptor.getMultitenantPolicy()).getTable(field.getTable())); } if (field.hasTableName() && (!(field.getTableName().equals(getRelationTable().getName())))) { throw DescriptorException.relationKeyFieldNotProperlySpecified(field, mapping); } field.setTable(getRelationTable()); } }
/** * The reference keys on the reference table are initialized */ protected void initializeReferenceKeys(AbstractSession session) throws DescriptorException { if (getReferenceKeyFields().size() == 0) { throw DescriptorException.noReferenceKeyIsSpecified(this); } for (Enumeration referenceEnum = getReferenceKeyFields().elements(); referenceEnum.hasMoreElements();) { DatabaseField field = (DatabaseField)referenceEnum.nextElement(); // Update the field first if the mapping is on a table per tenant entity. if (getDescriptor().hasTablePerMultitenantPolicy()) { field.setTable(((TablePerMultitenantPolicy) getDescriptor().getMultitenantPolicy()).getTable(field.getTable())); } if (field.hasTableName() && (!(field.getTableName().equals(getReferenceTable().getName())))) { throw DescriptorException.referenceKeyFieldNotProperlySpecified(field, this); } field.setTable(getReferenceTable()); } }
/** * INTERNAL: * All the target relation key field names are converted to DatabaseField and stored. */ protected void initializeTargetRelationKeys(ForeignReferenceMapping mapping) { if (getTargetRelationKeyFields().size() == 0) { throw DescriptorException.noTargetRelationKeysSpecified(mapping); } for (Enumeration targetEnum = getTargetRelationKeyFields().elements(); targetEnum.hasMoreElements();) { DatabaseField field = (DatabaseField)targetEnum.nextElement(); // Update the fields table first if the mapping is from a table per tenant entity. ClassDescriptor referenceDescriptor = mapping.getReferenceDescriptor(); if (referenceDescriptor.hasTablePerMultitenantPolicy()) { field.setTable(((TablePerMultitenantPolicy) referenceDescriptor.getMultitenantPolicy()).getTable(field.getTable())); } if (field.hasTableName() && (!(field.getTableName().equals(getRelationTable().getName())))) { throw DescriptorException.relationKeyFieldNotProperlySpecified(field, mapping); } field.setTable(getRelationTable()); } }
/** * The reference keys on the reference table are initialized */ protected void initializeReferenceKeys(AbstractSession session) throws DescriptorException { if (getReferenceKeyFields().size() == 0) { throw DescriptorException.noReferenceKeyIsSpecified(this); } for (Enumeration referenceEnum = getReferenceKeyFields().elements(); referenceEnum.hasMoreElements();) { DatabaseField field = (DatabaseField)referenceEnum.nextElement(); // Update the field first if the mapping is on a table per tenant entity. if (getDescriptor().hasTablePerMultitenantPolicy()) { field.setTable(((TablePerMultitenantPolicy) getDescriptor().getMultitenantPolicy()).getTable(field.getTable())); } if (field.hasTableName() && (!(field.getTableName().equals(getReferenceTable().getName())))) { throw DescriptorException.referenceKeyFieldNotProperlySpecified(field, this); } field.setTable(getReferenceTable()); } }
/** * INTERNAL: * Prepare the receiver for execution in a session. */ @Override public void prepareForExecution() throws QueryException { super.prepareForExecution(); this.containerPolicy.prepareForExecution(); // Modifying the translation row here will modify it on the original // query which is not good. So we have to clone the translation row if // we are going to append tenant discriminator fields to it. if (descriptor.hasMultitenantPolicy()) { translationRow = translationRow.clone(); descriptor.getMultitenantPolicy().addFieldsToRow(translationRow, getSession()); } }
/** * INTERNAL: * Prepare the receiver for execution in a session. */ @Override public void prepareForExecution() throws QueryException { super.prepareForExecution(); this.containerPolicy.prepareForExecution(); // Modifying the translation row here will modify it on the original // query which is not good. So we have to clone the translation row if // we are going to append tenant discriminator fields to it. if (descriptor.hasMultitenantPolicy()) { translationRow = translationRow.clone(); descriptor.getMultitenantPolicy().addFieldsToRow(translationRow, getSession()); } }
/** * Build the row representation of an object. * This is only used for aggregates. */ public AbstractRecord buildRowWithChangeSet(AbstractRecord databaseRow, ObjectChangeSet objectChangeSet, AbstractSession session, WriteType writeType) { List<ChangeRecord> changes = (List)objectChangeSet.getChanges(); int size = changes.size(); for (int index = 0; index < size; index++) { ChangeRecord changeRecord = changes.get(index); DatabaseMapping mapping = changeRecord.getMapping(); mapping.writeFromObjectIntoRowWithChangeRecord(changeRecord, databaseRow, session, writeType); } // If this descriptor is involved in inheritance add the class type. if (this.descriptor.hasInheritance()) { this.descriptor.getInheritancePolicy().addClassIndicatorFieldToRow(databaseRow); } // If the session uses multi-tenancy, add the tenant id field. if (getDescriptor().hasMultitenantPolicy()) { getDescriptor().getMultitenantPolicy().addFieldsToRow(databaseRow, session); } return databaseRow; }
/** * Build the row representation of an object. * This is only used for aggregates. */ public AbstractRecord buildRowWithChangeSet(AbstractRecord databaseRow, ObjectChangeSet objectChangeSet, AbstractSession session, WriteType writeType) { List<ChangeRecord> changes = (List)objectChangeSet.getChanges(); int size = changes.size(); for (int index = 0; index < size; index++) { ChangeRecord changeRecord = changes.get(index); DatabaseMapping mapping = changeRecord.getMapping(); mapping.writeFromObjectIntoRowWithChangeRecord(changeRecord, databaseRow, session, writeType); } // If this descriptor is involved in inheritance add the class type. if (this.descriptor.hasInheritance()) { this.descriptor.getInheritancePolicy().addClassIndicatorFieldToRow(databaseRow); } // If the session uses multi-tenancy, add the tenant id field. if (getDescriptor().hasMultitenantPolicy()) { getDescriptor().getMultitenantPolicy().addFieldsToRow(databaseRow, session); } return databaseRow; }
/** * INTERNAL: * Set the table qualifier on the relation table if required */ protected void initializeRelationTable(AbstractSession session, ForeignReferenceMapping mapping) throws DescriptorException { Platform platform = session.getDatasourcePlatform(); // We need to look up the relation table name from the reference // descriptor if we are the non owning side of a bidirectional mapping // to a table per tenant descriptor. if (mapping.isReadOnly() && mapping.getReferenceDescriptor().hasTablePerMultitenantPolicy()) { setRelationTable(((TablePerMultitenantPolicy) mapping.getReferenceDescriptor().getMultitenantPolicy()).getTable(getRelationTable())); } if (!hasRelationTable()) { throw DescriptorException.noRelationTable(mapping); } if (platform.getTableQualifier().length() > 0) { if (getRelationTable().getTableQualifier().length() == 0) { getRelationTable().setTableQualifier(platform.getTableQualifier()); } } } /**
/** * INTERNAL: * Set the table qualifier on the relation table if required */ protected void initializeRelationTable(AbstractSession session, ForeignReferenceMapping mapping) throws DescriptorException { Platform platform = session.getDatasourcePlatform(); // We need to look up the relation table name from the reference // descriptor if we are the non owning side of a bidirectional mapping // to a table per tenant descriptor. if (mapping.isReadOnly() && mapping.getReferenceDescriptor().hasTablePerMultitenantPolicy()) { setRelationTable(((TablePerMultitenantPolicy) mapping.getReferenceDescriptor().getMultitenantPolicy()).getTable(getRelationTable())); } if (!hasRelationTable()) { throw DescriptorException.noRelationTable(mapping); } if (platform.getTableQualifier().length() > 0) { if (getRelationTable().getTableQualifier().length() == 0) { getRelationTable().setTableQualifier(platform.getTableQualifier()); } } } /**
/** * INTERNAL: * Add the query the session. Table per tenant queries should not be added * to the regular query list as these queries may need to be initialized * per EM. */ protected void addJPAQuery(JPAQuery query, AbstractSession session) { if (query.isJPQLQuery()) { List<ClassDescriptor> descriptors = new JPQLQueryHelper().getClassDescriptors(query.getJPQLString(), session); for (ClassDescriptor descriptor : descriptors) { // If we find one descriptor that has table per tenant multitenancy, // then add it to the multitenant query list. These queries may // need to be initialized per EM rather than straight up at the // EMF level. if (descriptor.hasMultitenantPolicy() && descriptor.getMultitenantPolicy().isTablePerMultitenantPolicy()) { // Store the descriptors so we don't have to parse them again. query.setDescriptors(descriptors); session.addJPATablePerTenantQuery(query); return; } } } session.addJPAQuery(query); }
/** * INTERNAL: * Prepare the receiver for execution in a session. */ public void prepareForExecution() throws QueryException { super.prepareForExecution(); // For bug 2989998 the translation row now sometimes set earlier in prepare. if (shouldPrepare()) { if (this.selectionId != null) { // Row must come from the key. this.translationRow = this.descriptor.getObjectBuilder().buildRowFromPrimaryKeyValues(this.selectionId, getSession()); } else if (this.selectionObject != null) { // The expression is set in the prepare as params. this.translationRow = this.descriptor.getObjectBuilder().buildRowForTranslation(this.selectionObject, getSession()); } } // If we have tenant discriminator fields we need to add them to the // database row when doing a primary key query. // Modifying the translation row here will modify it on the original // query which is not good (will append the tenant field to the sql call // for subsequent queries) The translation row must be cloned to isolate // this. if (getDescriptor().hasMultitenantPolicy()) { this.translationRow = this.translationRow.clone(); getDescriptor().getMultitenantPolicy().addFieldsToRow(this.translationRow, getSession()); } }