use of org.hibernate.metamodel.mapping.AttributeMapping in project hibernate-orm by hibernate.
the class AbstractEmbeddableMapping method finishInitialization.
protected static boolean finishInitialization(NavigableRole navigableRole, Component bootDescriptor, CompositeType compositeType, String rootTableExpression, String[] rootTableKeyColumnNames, EmbeddableMappingType declarer, EmbeddableRepresentationStrategy representationStrategy, AttributeTypeValidator attributeTypeValidator, ConcreteTableResolver concreteTableResolver, Consumer<AttributeMapping> attributeConsumer, SuccessfulCompletionCallback completionCallback, MappingModelCreationProcess creationProcess) {
final SessionFactoryImplementor sessionFactory = creationProcess.getCreationContext().getSessionFactory();
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final Dialect dialect = jdbcEnvironment.getDialect();
final Type[] subtypes = compositeType.getSubtypes();
int attributeIndex = 0;
int columnPosition = 0;
for (Property bootPropertyDescriptor : bootDescriptor.getProperties()) {
final Type subtype = subtypes[attributeIndex];
attributeTypeValidator.check(bootPropertyDescriptor.getName(), subtype);
final PropertyAccess propertyAccess = representationStrategy.resolvePropertyAccess(bootPropertyDescriptor);
final AttributeMapping attributeMapping;
if (subtype instanceof BasicType) {
final BasicValue basicValue = (BasicValue) bootPropertyDescriptor.getValue();
final Selectable selectable = basicValue.getColumn();
final String containingTableExpression;
final String columnExpression;
if (rootTableKeyColumnNames == null) {
if (selectable.isFormula()) {
columnExpression = selectable.getTemplate(dialect, creationProcess.getSqmFunctionRegistry());
} else {
columnExpression = selectable.getText(dialect);
}
if (selectable instanceof Column) {
containingTableExpression = concreteTableResolver.resolve((Column) selectable, jdbcEnvironment);
} else {
containingTableExpression = rootTableExpression;
}
} else {
containingTableExpression = rootTableExpression;
columnExpression = rootTableKeyColumnNames[columnPosition];
}
final String columnDefinition;
final Long length;
final Integer precision;
final Integer scale;
if (selectable instanceof Column) {
Column column = (Column) selectable;
columnDefinition = column.getSqlType();
length = column.getLength();
precision = column.getPrecision();
scale = column.getScale();
} else {
columnDefinition = null;
length = null;
precision = null;
scale = null;
}
attributeMapping = MappingModelCreationHelper.buildBasicAttributeMapping(bootPropertyDescriptor.getName(), navigableRole.append(bootPropertyDescriptor.getName()), attributeIndex, bootPropertyDescriptor, declarer, (BasicType<?>) subtype, containingTableExpression, columnExpression, selectable.isFormula(), selectable.getCustomReadExpression(), selectable.getCustomWriteExpression(), columnDefinition, length, precision, scale, propertyAccess, compositeType.getCascadeStyle(attributeIndex), creationProcess);
columnPosition++;
} else if (subtype instanceof AnyType) {
final Any bootValueMapping = (Any) bootPropertyDescriptor.getValue();
final AnyType anyType = (AnyType) subtype;
final boolean nullable = bootValueMapping.isNullable();
final boolean insertable = bootPropertyDescriptor.isInsertable();
final boolean updateable = bootPropertyDescriptor.isUpdateable();
final boolean includeInOptimisticLocking = bootPropertyDescriptor.isOptimisticLocked();
final CascadeStyle cascadeStyle = compositeType.getCascadeStyle(attributeIndex);
final MutabilityPlan<?> mutabilityPlan;
if (updateable) {
mutabilityPlan = new MutabilityPlan<>() {
@Override
public boolean isMutable() {
return true;
}
@Override
public Object deepCopy(Object value) {
if (value == null) {
return null;
}
return anyType.deepCopy(value, creationProcess.getCreationContext().getSessionFactory());
}
@Override
public Serializable disassemble(Object value, SharedSessionContract session) {
throw new NotYetImplementedFor6Exception(getClass());
}
@Override
public Object assemble(Serializable cached, SharedSessionContract session) {
throw new NotYetImplementedFor6Exception(getClass());
}
};
} else {
mutabilityPlan = ImmutableMutabilityPlan.INSTANCE;
}
final StateArrayContributorMetadataAccess attributeMetadataAccess = entityMappingType -> new StateArrayContributorMetadata() {
@Override
public PropertyAccess getPropertyAccess() {
return propertyAccess;
}
@Override
public MutabilityPlan<?> getMutabilityPlan() {
return mutabilityPlan;
}
@Override
public boolean isNullable() {
return nullable;
}
@Override
public boolean isInsertable() {
return insertable;
}
@Override
public boolean isUpdatable() {
return updateable;
}
@Override
public boolean isIncludedInDirtyChecking() {
// todo (6.0) : do not believe this is correct
return updateable;
}
@Override
public boolean isIncludedInOptimisticLocking() {
return includeInOptimisticLocking;
}
@Override
public CascadeStyle getCascadeStyle() {
return cascadeStyle;
}
};
attributeMapping = new DiscriminatedAssociationAttributeMapping(navigableRole.append(bootPropertyDescriptor.getName()), typeConfiguration.getJavaTypeRegistry().getDescriptor(Object.class), declarer, attributeIndex, attributeMetadataAccess, bootPropertyDescriptor.isLazy() ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE, propertyAccess, bootPropertyDescriptor, anyType, bootValueMapping, creationProcess);
} else if (subtype instanceof CompositeType) {
final CompositeType subCompositeType = (CompositeType) subtype;
final int columnSpan = subCompositeType.getColumnSpan(sessionFactory);
final String subTableExpression;
final String[] subRootTableKeyColumnNames;
if (rootTableKeyColumnNames == null) {
subTableExpression = rootTableExpression;
subRootTableKeyColumnNames = null;
} else {
subTableExpression = rootTableExpression;
subRootTableKeyColumnNames = new String[columnSpan];
System.arraycopy(rootTableKeyColumnNames, columnPosition, subRootTableKeyColumnNames, 0, columnSpan);
}
attributeMapping = MappingModelCreationHelper.buildEmbeddedAttributeMapping(bootPropertyDescriptor.getName(), attributeIndex, bootPropertyDescriptor, declarer, subCompositeType, subTableExpression, subRootTableKeyColumnNames, propertyAccess, compositeType.getCascadeStyle(attributeIndex), creationProcess);
columnPosition += columnSpan;
} else if (subtype instanceof CollectionType) {
final EntityPersister entityPersister = creationProcess.getEntityPersister(bootDescriptor.getOwner().getEntityName());
attributeMapping = MappingModelCreationHelper.buildPluralAttributeMapping(bootPropertyDescriptor.getName(), attributeIndex, bootPropertyDescriptor, entityPersister, propertyAccess, compositeType.getCascadeStyle(attributeIndex), compositeType.getFetchMode(attributeIndex), creationProcess);
} else if (subtype instanceof EntityType) {
final EntityPersister entityPersister = creationProcess.getEntityPersister(bootDescriptor.getOwner().getEntityName());
attributeMapping = MappingModelCreationHelper.buildSingularAssociationAttributeMapping(bootPropertyDescriptor.getName(), navigableRole.append(bootPropertyDescriptor.getName()), attributeIndex, bootPropertyDescriptor, entityPersister, entityPersister, (EntityType) subtype, representationStrategy.resolvePropertyAccess(bootPropertyDescriptor), compositeType.getCascadeStyle(attributeIndex), creationProcess);
columnPosition += bootPropertyDescriptor.getColumnSpan();
} else {
throw new MappingException(String.format(Locale.ROOT, "Unable to determine attribute nature : %s#%s", bootDescriptor.getOwner().getEntityName(), bootPropertyDescriptor.getName()));
}
attributeConsumer.accept(attributeMapping);
attributeIndex++;
}
completionCallback.success();
return true;
}
use of org.hibernate.metamodel.mapping.AttributeMapping in project hibernate-orm by hibernate.
the class AbstractEntityPersister method generateUpdateString.
/**
* Generate the SQL that updates a row by id (and version)
*/
public String generateUpdateString(final boolean[] includeProperty, final int j, final Object[] oldFields, final boolean useRowId) {
final Update update = createUpdate().setTableName(getTableName(j));
boolean hasColumns = false;
for (int index = 0; index < attributeMappings.size(); index++) {
final AttributeMapping attributeMapping = attributeMappings.get(index);
if (isPropertyOfTable(index, j)) {
if (!lobProperties.contains(index)) {
if (includeProperty[index]) {
update.addColumns(getPropertyColumnNames(index), propertyColumnUpdateable[index], propertyColumnWriters[index]);
hasColumns = true;
} else {
final ValueGeneration valueGeneration = attributeMapping.getValueGeneration();
if (valueGeneration.getGenerationTiming().includesUpdate() && valueGeneration.getValueGenerator() == null && valueGeneration.referenceColumnInSql()) {
update.addColumns(getPropertyColumnNames(index), SINGLE_TRUE, new String[] { valueGeneration.getDatabaseGeneratedReferencedColumnValue() });
hasColumns = true;
}
}
}
}
}
// and updates. Insert them at the end.
for (int i : lobProperties) {
if (includeProperty[i] && isPropertyOfTable(i, j)) {
// this property belongs on the table and is to be inserted
update.addColumns(getPropertyColumnNames(i), propertyColumnUpdateable[i], propertyColumnWriters[i]);
hasColumns = true;
}
}
// select the correct row by either pk or row id
if (useRowId) {
// TODO: eventually, rowIdName[j]
update.addPrimaryKeyColumns(new String[] { rowIdName });
} else {
update.addPrimaryKeyColumns(getKeyColumns(j));
}
if (j == 0 && isVersioned() && entityMetamodel.getOptimisticLockStyle().isVersion()) {
// check it (unless this is a "generated" version column)!
if (checkVersion(includeProperty)) {
update.setVersionColumnName(getVersionColumnName());
hasColumns = true;
}
} else if (isAllOrDirtyOptLocking() && oldFields != null) {
// we are using "all" or "dirty" property-based optimistic locking
boolean[] includeInWhere = entityMetamodel.getOptimisticLockStyle().isAll() ? // optimistic-lock="all", include all updatable properties
getPropertyUpdateability() : // optimistic-lock="dirty", include all properties we are updating this time
includeProperty;
boolean[] versionability = getPropertyVersionability();
Type[] types = getPropertyTypes();
for (int i = 0; i < entityMetamodel.getPropertySpan(); i++) {
boolean include = includeInWhere[i] && isPropertyOfTable(i, j) && versionability[i];
if (include) {
// this property belongs to the table, and it is not specifically
// excluded from optimistic locking by optimistic-lock="false"
String[] propertyColumnNames = getPropertyColumnNames(i);
String[] propertyColumnWriters = getPropertyColumnWriters(i);
boolean[] propertyNullness = types[i].toColumnNullness(oldFields[i], getFactory());
for (int k = 0; k < propertyNullness.length; k++) {
if (propertyNullness[k]) {
update.addWhereColumn(propertyColumnNames[k], "=" + propertyColumnWriters[k]);
} else {
update.addWhereColumn(propertyColumnNames[k], " is null");
}
}
}
}
}
if (getFactory().getSessionFactoryOptions().isCommentsEnabled()) {
update.setComment("update " + getEntityName());
}
return hasColumns ? update.toStatementString() : null;
}
use of org.hibernate.metamodel.mapping.AttributeMapping in project hibernate-orm by hibernate.
the class AbstractEntityPersister method generateNonIdAttributeMapping.
private AttributeMapping generateNonIdAttributeMapping(NonIdentifierAttribute tupleAttrDefinition, Property bootProperty, int stateArrayPosition, MappingModelCreationProcess creationProcess) {
final SessionFactoryImplementor sessionFactory = creationProcess.getCreationContext().getSessionFactory();
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final Dialect dialect = jdbcEnvironment.getDialect();
final String attrName = tupleAttrDefinition.getName();
final Type attrType = tupleAttrDefinition.getType();
final int propertyIndex = getPropertyIndex(bootProperty.getName());
final String tableExpression = getTableName(getPropertyTableNumbers()[propertyIndex]);
final String[] attrColumnNames = getPropertyColumnNames(propertyIndex);
final PropertyAccess propertyAccess = getRepresentationStrategy().resolvePropertyAccess(bootProperty);
if (propertyIndex == getVersionProperty()) {
Column column = bootProperty.getValue().getColumns().get(0);
return MappingModelCreationHelper.buildBasicAttributeMapping(attrName, getNavigableRole().append(bootProperty.getName()), stateArrayPosition, bootProperty, this, (BasicType<?>) attrType, tableExpression, attrColumnNames[0], false, null, null, column.getSqlType(), column.getLength(), column.getPrecision(), column.getScale(), propertyAccess, tupleAttrDefinition.getCascadeStyle(), creationProcess);
}
if (attrType instanceof BasicType) {
final Value bootValue = bootProperty.getValue();
final String attrColumnExpression;
final boolean isAttrColumnExpressionFormula;
final String customReadExpr;
final String customWriteExpr;
final String columnDefinition;
final Long length;
final Integer precision;
final Integer scale;
if (bootValue instanceof DependantValue) {
attrColumnExpression = attrColumnNames[0];
isAttrColumnExpressionFormula = false;
customReadExpr = null;
customWriteExpr = null;
Column column = bootValue.getColumns().get(0);
columnDefinition = column.getSqlType();
length = column.getLength();
precision = column.getPrecision();
scale = column.getScale();
} else {
final BasicValue basicBootValue = (BasicValue) bootValue;
if (attrColumnNames[0] != null) {
attrColumnExpression = attrColumnNames[0];
isAttrColumnExpressionFormula = false;
final List<Selectable> selectables = basicBootValue.getSelectables();
assert !selectables.isEmpty();
final Selectable selectable = selectables.get(0);
assert attrColumnExpression.equals(selectable.getText(sessionFactory.getJdbcServices().getDialect()));
customReadExpr = selectable.getTemplate(dialect, sessionFactory.getQueryEngine().getSqmFunctionRegistry());
customWriteExpr = selectable.getCustomWriteExpression();
Column column = bootValue.getColumns().get(0);
columnDefinition = column.getSqlType();
length = column.getLength();
precision = column.getPrecision();
scale = column.getScale();
} else {
final String[] attrColumnFormulaTemplate = propertyColumnFormulaTemplates[propertyIndex];
attrColumnExpression = attrColumnFormulaTemplate[0];
isAttrColumnExpressionFormula = true;
customReadExpr = null;
customWriteExpr = null;
columnDefinition = null;
length = null;
precision = null;
scale = null;
}
}
return MappingModelCreationHelper.buildBasicAttributeMapping(attrName, getNavigableRole().append(bootProperty.getName()), stateArrayPosition, bootProperty, this, (BasicType<?>) attrType, tableExpression, attrColumnExpression, isAttrColumnExpressionFormula, customReadExpr, customWriteExpr, columnDefinition, length, precision, scale, propertyAccess, tupleAttrDefinition.getCascadeStyle(), creationProcess);
} else if (attrType instanceof AnyType) {
final JavaType<Object> baseAssociationJtd = sessionFactory.getTypeConfiguration().getJavaTypeRegistry().getDescriptor(Object.class);
final AnyType anyType = (AnyType) attrType;
return new DiscriminatedAssociationAttributeMapping(navigableRole.append(bootProperty.getName()), baseAssociationJtd, this, stateArrayPosition, entityMappingType -> new StateArrayContributorMetadata() {
private final MutabilityPlan<?> mutabilityPlan = new DiscriminatedAssociationAttributeMapping.MutabilityPlanImpl(anyType);
private final boolean nullable = bootProperty.isOptional();
private final boolean insertable = bootProperty.isInsertable();
private final boolean updateable = bootProperty.isUpdateable();
private final boolean optimisticallyLocked = bootProperty.isOptimisticLocked();
@Override
public PropertyAccess getPropertyAccess() {
return propertyAccess;
}
@Override
public MutabilityPlan<?> getMutabilityPlan() {
return mutabilityPlan;
}
@Override
public boolean isNullable() {
return nullable;
}
@Override
public boolean isInsertable() {
return insertable;
}
@Override
public boolean isUpdatable() {
return updateable;
}
@Override
public boolean isIncludedInDirtyChecking() {
return updateable;
}
@Override
public boolean isIncludedInOptimisticLocking() {
return optimisticallyLocked;
}
}, bootProperty.isLazy() ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE, propertyAccess, bootProperty, (AnyType) attrType, (Any) bootProperty.getValue(), creationProcess);
} else if (attrType instanceof CompositeType) {
return MappingModelCreationHelper.buildEmbeddedAttributeMapping(attrName, stateArrayPosition, bootProperty, this, (CompositeType) attrType, tableExpression, null, propertyAccess, tupleAttrDefinition.getCascadeStyle(), creationProcess);
} else if (attrType instanceof CollectionType) {
return MappingModelCreationHelper.buildPluralAttributeMapping(attrName, stateArrayPosition, bootProperty, this, propertyAccess, tupleAttrDefinition.getCascadeStyle(), getFetchMode(stateArrayPosition), creationProcess);
} else if (attrType instanceof EntityType) {
return MappingModelCreationHelper.buildSingularAssociationAttributeMapping(attrName, getNavigableRole().append(attrName), stateArrayPosition, bootProperty, this, this, (EntityType) attrType, propertyAccess, tupleAttrDefinition.getCascadeStyle(), creationProcess);
}
return null;
}
use of org.hibernate.metamodel.mapping.AttributeMapping in project hibernate-orm by hibernate.
the class AbstractEntityPersister method resolveAttributeIndexes.
@Override
public int[] resolveAttributeIndexes(String[] attributeNames) {
if (attributeNames == null || attributeNames.length == 0) {
return ArrayHelper.EMPTY_INT_ARRAY;
}
final List<Integer> fields = new ArrayList<>(attributeNames.length);
// Sort attribute names so that we can traverse mappings efficiently
Arrays.sort(attributeNames);
int index = 0;
for (final AttributeMapping attributeMapping : attributeMappings) {
final String attributeName = attributeMapping.getAttributeName();
final int nameLength = attributeName.length();
final String currentAttributeName = attributeNames[index];
if (currentAttributeName.startsWith(attributeName) && ((currentAttributeName.length() == nameLength || currentAttributeName.charAt(nameLength) == '.'))) {
fields.add(((StateArrayContributorMapping) attributeMapping).getStateArrayPosition());
index++;
if (index < attributeNames.length) {
// Skip duplicates
do {
if (attributeNames[index].equals(attributeMapping.getAttributeName())) {
index++;
} else {
break;
}
} while (index < attributeNames.length);
} else {
break;
}
}
}
return ArrayHelper.toIntArray(fields);
}
use of org.hibernate.metamodel.mapping.AttributeMapping in project hibernate-orm by hibernate.
the class AbstractEntityPersister method findSubPart.
@Override
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
LOG.tracef("#findSubPart(`%s`)", name);
if (EntityDiscriminatorMapping.matchesRoleName(name)) {
return discriminatorMapping;
}
final AttributeMapping declaredAttribute = declaredAttributeMappings.get(name);
if (declaredAttribute != null) {
return declaredAttribute;
}
if (superMappingType != null) {
final ModelPart superDefinedAttribute = superMappingType.findSubPart(name, superMappingType);
if (superDefinedAttribute != null) {
// Prefer the identifier mapping of the concrete class
if (superDefinedAttribute instanceof EntityIdentifierMapping) {
final ModelPart identifierModelPart = getIdentifierModelPart(name, treatTargetType);
if (identifierModelPart != null) {
return identifierModelPart;
}
}
return superDefinedAttribute;
}
}
if (treatTargetType != null) {
if (!treatTargetType.isTypeOrSuperType(this)) {
return null;
}
if (subclassMappingTypes != null && !subclassMappingTypes.isEmpty()) {
for (EntityMappingType subMappingType : subclassMappingTypes.values()) {
if (!treatTargetType.isTypeOrSuperType(subMappingType)) {
continue;
}
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart(name, treatTargetType);
if (subDefinedAttribute != null) {
return subDefinedAttribute;
}
}
}
} else {
if (subclassMappingTypes != null && !subclassMappingTypes.isEmpty()) {
ModelPart attribute = null;
for (EntityMappingType subMappingType : subclassMappingTypes.values()) {
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart(name, treatTargetType);
if (subDefinedAttribute != null) {
if (attribute != null && !MappingModelHelper.isCompatibleModelPart(attribute, subDefinedAttribute)) {
throw new IllegalArgumentException(new SemanticException(String.format(Locale.ROOT, "Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple sub types: ['%s', '%s']", name, getJavaType().getJavaType().getTypeName(), ((AttributeMapping) attribute).getDeclaringType().getJavaType().getJavaType().getTypeName(), ((AttributeMapping) subDefinedAttribute).getDeclaringType().getJavaType().getJavaType().getTypeName())));
}
attribute = subDefinedAttribute;
}
}
if (attribute != null) {
return attribute;
}
}
}
final ModelPart identifierModelPart = getIdentifierModelPart(name, treatTargetType);
if (identifierModelPart != null) {
return identifierModelPart;
}
for (AttributeMapping attribute : declaredAttributeMappings.values()) {
if (attribute instanceof EmbeddableValuedModelPart && attribute instanceof VirtualModelPart) {
final ModelPart subPart = ((EmbeddableValuedModelPart) attribute).findSubPart(name, null);
if (subPart != null) {
return subPart;
}
}
}
return null;
}
Aggregations