use of org.hibernate.metamodel.mapping.SelectableMapping in project hibernate-orm by hibernate.
the class MappingModelCreationHelper method interpretPluralAttributeMappingKeyDescriptor.
private static void interpretPluralAttributeMappingKeyDescriptor(PluralAttributeMappingImpl attributeMapping, Collection bootValueMapping, CollectionPersister collectionDescriptor, ManagedMappingType declaringType, Dialect dialect, MappingModelCreationProcess creationProcess) {
ModelPart attributeMappingSubPart = null;
if (!StringHelper.isEmpty(collectionDescriptor.getMappedByProperty())) {
attributeMappingSubPart = ((ModelPartContainer) attributeMapping.getElementDescriptor().getPartMappingType()).findSubPart(collectionDescriptor.getMappedByProperty(), null);
}
if (attributeMappingSubPart instanceof ToOneAttributeMapping) {
final ToOneAttributeMapping referencedAttributeMapping = (ToOneAttributeMapping) attributeMappingSubPart;
setReferencedAttributeForeignKeyDescriptor(attributeMapping, referencedAttributeMapping, referencedAttributeMapping.findContainingEntityMapping().getEntityPersister(), collectionDescriptor.getMappedByProperty(), dialect, creationProcess);
return;
}
final KeyValue bootValueMappingKey = bootValueMapping.getKey();
final Type keyType = bootValueMappingKey.getType();
final ModelPart fkTarget;
final String lhsPropertyName = collectionDescriptor.getCollectionType().getLHSPropertyName();
final boolean isReferenceToPrimaryKey = lhsPropertyName == null;
final ManagedMappingType keyDeclaringType;
if (collectionDescriptor.getElementType().isEntityType()) {
keyDeclaringType = ((QueryableCollection) collectionDescriptor).getElementPersister();
} else {
// This is not "really correct" but it is as good as it gets.
// The key declaring type serves as declaring type for the inverse model part of a FK.
// Most of the time, there is a proper managed type, but not for basic collections.
// Since the declaring type is needed for certain operations, we use the one from the target side of the FK
keyDeclaringType = declaringType;
}
if (isReferenceToPrimaryKey) {
fkTarget = collectionDescriptor.getOwnerEntityPersister().getIdentifierMapping();
} else {
fkTarget = declaringType.findAttributeMapping(lhsPropertyName);
}
if (keyType instanceof BasicType) {
assert bootValueMappingKey.getColumnSpan() == 1;
assert fkTarget instanceof BasicValuedModelPart;
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final String tableExpression = getTableIdentifierExpression(bootValueMappingKey.getTable(), creationProcess);
final SelectableMapping keySelectableMapping = SelectableMappingImpl.from(tableExpression, bootValueMappingKey.getSelectables().get(0), (JdbcMapping) keyType, dialect, creationProcess.getSqmFunctionRegistry());
attributeMapping.setForeignKeyDescriptor(new SimpleForeignKeyDescriptor(keyDeclaringType, simpleFkTarget, null, keySelectableMapping, simpleFkTarget, isReferenceToPrimaryKey, ((SimpleValue) bootValueMappingKey).isConstrained()));
} else if (fkTarget instanceof EmbeddableValuedModelPart) {
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = buildEmbeddableForeignKeyDescriptor((EmbeddableValuedModelPart) fkTarget, bootValueMapping, keyDeclaringType, collectionDescriptor.getAttributeMapping(), false, dialect, creationProcess);
attributeMapping.setForeignKeyDescriptor(embeddedForeignKeyDescriptor);
} else {
throw new NotYetImplementedFor6Exception("Support for " + fkTarget.getClass() + " foreign keys not yet implemented: " + bootValueMapping.getRole());
}
}
use of org.hibernate.metamodel.mapping.SelectableMapping in project hibernate-orm by hibernate.
the class MappingModelCreationHelper method interpretMapKey.
private static CollectionPart interpretMapKey(Collection bootValueMapping, CollectionPersister collectionDescriptor, String tableExpression, String sqlAliasStem, Dialect dialect, MappingModelCreationProcess creationProcess) {
assert bootValueMapping instanceof IndexedCollection;
final IndexedCollection indexedCollection = (IndexedCollection) bootValueMapping;
final Value bootMapKeyDescriptor = indexedCollection.getIndex();
if (bootMapKeyDescriptor instanceof BasicValue) {
final BasicValue basicValue = (BasicValue) bootMapKeyDescriptor;
final SelectableMapping selectableMapping = SelectableMappingImpl.from(tableExpression, basicValue.getSelectables().get(0), basicValue.resolve().getJdbcMapping(), dialect, creationProcess.getSqmFunctionRegistry());
return new BasicValuedCollectionPart(collectionDescriptor, CollectionPart.Nature.INDEX, basicValue.resolve().getValueConverter(), selectableMapping);
}
if (bootMapKeyDescriptor instanceof Component) {
final Component component = (Component) bootMapKeyDescriptor;
final CompositeType compositeType = (CompositeType) component.getType();
final EmbeddableMappingTypeImpl mappingType = EmbeddableMappingTypeImpl.from(component, compositeType, inflightDescriptor -> new EmbeddedCollectionPart(collectionDescriptor, CollectionPart.Nature.INDEX, inflightDescriptor, // parent-injection
component.getParentProperty(), tableExpression, sqlAliasStem), creationProcess);
return (CollectionPart) mappingType.getEmbeddedValueMapping();
}
if (bootMapKeyDescriptor instanceof OneToMany || bootMapKeyDescriptor instanceof ToOne) {
final EntityType indexEntityType = (EntityType) collectionDescriptor.getIndexType();
final EntityPersister associatedEntity = creationProcess.getEntityPersister(indexEntityType.getAssociatedEntityName());
final EntityCollectionPart indexDescriptor = new EntityCollectionPart(collectionDescriptor, CollectionPart.Nature.INDEX, bootMapKeyDescriptor, associatedEntity, creationProcess);
creationProcess.registerInitializationCallback("PluralAttributeMapping( " + bootValueMapping.getRole() + ") - index descriptor", () -> {
indexDescriptor.finishInitialization(collectionDescriptor, bootValueMapping, indexEntityType.getRHSUniqueKeyPropertyName(), creationProcess);
return true;
});
return indexDescriptor;
}
throw new NotYetImplementedFor6Exception("Support for plural attributes with index type [" + bootMapKeyDescriptor + "] not yet implemented");
}
use of org.hibernate.metamodel.mapping.SelectableMapping in project hibernate-orm by hibernate.
the class MappingModelCreationHelper method interpretElement.
private static CollectionPart interpretElement(Collection bootDescriptor, String tableExpression, CollectionPersister collectionDescriptor, String sqlAliasStem, Dialect dialect, MappingModelCreationProcess creationProcess) {
final Value element = bootDescriptor.getElement();
if (element instanceof BasicValue) {
final BasicValue basicElement = (BasicValue) element;
final SelectableMapping selectableMapping = SelectableMappingImpl.from(tableExpression, basicElement.getSelectables().get(0), basicElement.resolve().getJdbcMapping(), dialect, creationProcess.getSqmFunctionRegistry());
return new BasicValuedCollectionPart(collectionDescriptor, CollectionPart.Nature.ELEMENT, basicElement.resolve().getValueConverter(), selectableMapping);
}
if (element instanceof Component) {
final Component component = (Component) element;
final CompositeType compositeType = (CompositeType) collectionDescriptor.getElementType();
final EmbeddableMappingTypeImpl mappingType = EmbeddableMappingTypeImpl.from(component, compositeType, embeddableMappingType -> new EmbeddedCollectionPart(collectionDescriptor, CollectionPart.Nature.ELEMENT, embeddableMappingType, // parent-injection
component.getParentProperty(), tableExpression, sqlAliasStem), creationProcess);
return (CollectionPart) mappingType.getEmbeddedValueMapping();
}
if (element instanceof Any) {
final Any anyBootMapping = (Any) element;
final SessionFactoryImplementor sessionFactory = creationProcess.getCreationContext().getSessionFactory();
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry();
final JavaType<Object> baseJtd = jtdRegistry.getDescriptor(Object.class);
return new DiscriminatedCollectionPart(CollectionPart.Nature.ELEMENT, collectionDescriptor, baseJtd, anyBootMapping, anyBootMapping.getType(), creationProcess);
}
if (element instanceof OneToMany || element instanceof ToOne) {
final EntityType elementEntityType = (EntityType) collectionDescriptor.getElementType();
final EntityPersister associatedEntity = creationProcess.getEntityPersister(elementEntityType.getAssociatedEntityName());
final EntityCollectionPart elementDescriptor = new EntityCollectionPart(collectionDescriptor, CollectionPart.Nature.ELEMENT, bootDescriptor.getElement(), associatedEntity, creationProcess);
creationProcess.registerInitializationCallback("PluralAttributeMapping( " + elementDescriptor.getNavigableRole() + ") - index descriptor", () -> {
elementDescriptor.finishInitialization(collectionDescriptor, bootDescriptor, elementEntityType.getRHSUniqueKeyPropertyName(), creationProcess);
return true;
});
return elementDescriptor;
}
throw new NotYetImplementedFor6Exception("Support for plural attributes with element type [" + element + "] not yet implemented");
}
use of org.hibernate.metamodel.mapping.SelectableMapping in project hibernate-orm by hibernate.
the class MappingModelCreationHelper method interpretToOneKeyDescriptor.
/**
* Tries to {@link ToOneAttributeMapping#setForeignKeyDescriptor}
* to the given attribute {@code attributeMapping}.
*
* @param attributeMapping The attribute for which we try to set the foreign key
* @param bootProperty The property
* @param bootValueMapping The value mapping
* @param inversePropertyAccess Access to the inverse property
* @param dialect Current dialect
* @param creationProcess Current creation process
* @return true if the foreign key is actually set
*/
public static boolean interpretToOneKeyDescriptor(ToOneAttributeMapping attributeMapping, Property bootProperty, ToOne bootValueMapping, PropertyAccess inversePropertyAccess, Dialect dialect, MappingModelCreationProcess creationProcess) {
if (attributeMapping.getForeignKeyDescriptor() != null) {
// already built/known
return true;
}
final String tableName = getTableIdentifierExpression(bootValueMapping.getTable(), creationProcess);
attributeMapping.setIdentifyingColumnsTableExpression(tableName);
final EntityPersister referencedEntityDescriptor = creationProcess.getEntityPersister(bootValueMapping.getReferencedEntityName());
String referencedPropertyName;
boolean swapDirection = false;
if (bootValueMapping instanceof OneToOne) {
OneToOne oneToOne = (OneToOne) bootValueMapping;
swapDirection = oneToOne.getForeignKeyType() == ForeignKeyDirection.TO_PARENT;
referencedPropertyName = oneToOne.getMappedByProperty();
if (referencedPropertyName == null) {
referencedPropertyName = oneToOne.getReferencedPropertyName();
}
} else {
referencedPropertyName = null;
}
if (referencedPropertyName != null) {
if (referencedPropertyName.indexOf(".") > 0) {
return interpretNestedToOneKeyDescriptor(referencedEntityDescriptor, referencedPropertyName, attributeMapping);
}
final ModelPart modelPart = referencedEntityDescriptor.findByPath(referencedPropertyName);
if (modelPart instanceof ToOneAttributeMapping) {
setReferencedAttributeForeignKeyDescriptor(attributeMapping, (ToOneAttributeMapping) modelPart, referencedEntityDescriptor, referencedPropertyName, dialect, creationProcess);
} else if (modelPart instanceof EmbeddableValuedModelPart) {
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = buildEmbeddableForeignKeyDescriptor((EmbeddableValuedModelPart) modelPart, bootValueMapping, attributeMapping.getDeclaringType(), attributeMapping.findContainingEntityMapping(), true, dialect, creationProcess);
attributeMapping.setForeignKeyDescriptor(embeddedForeignKeyDescriptor);
} else if (modelPart == null) {
throw new IllegalArgumentException("Unable to find attribute " + bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName());
} else {
throw new NotYetImplementedFor6Exception("Support for foreign-keys based on `" + modelPart + "` not yet implemented: " + bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName());
}
return true;
}
final ModelPart fkTarget;
if (bootValueMapping.isReferenceToPrimaryKey()) {
fkTarget = referencedEntityDescriptor.getIdentifierMapping();
} else {
fkTarget = referencedEntityDescriptor.findByPath(bootValueMapping.getReferencedPropertyName());
}
if (fkTarget instanceof BasicValuedModelPart) {
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final Iterator<Selectable> columnIterator = bootValueMapping.getColumnIterator();
final Table table = bootValueMapping.getTable();
final String tableExpression = getTableIdentifierExpression(table, creationProcess);
final BasicValuedModelPart declaringKeyPart;
final PropertyAccess declaringKeyPropertyAccess;
if (inversePropertyAccess == null) {
// So far, OneToOne mappings are only supported based on the owner's PK
if (bootValueMapping instanceof OneToOne) {
declaringKeyPart = simpleFkTarget;
final EntityIdentifierMapping identifierMapping = attributeMapping.findContainingEntityMapping().getIdentifierMapping();
declaringKeyPropertyAccess = ((PropertyBasedMapping) identifierMapping).getPropertyAccess();
} else {
declaringKeyPart = simpleFkTarget;
// declaringKeyPropertyAccess = ( (PropertyBasedMapping) declaringKeyPart ).getPropertyAccess();
declaringKeyPropertyAccess = new ChainedPropertyAccessImpl(attributeMapping.getPropertyAccess(), ((PropertyBasedMapping) declaringKeyPart).getPropertyAccess());
}
} else {
declaringKeyPart = simpleFkTarget;
declaringKeyPropertyAccess = new ChainedPropertyAccessImpl(inversePropertyAccess, ((PropertyBasedMapping) simpleFkTarget).getPropertyAccess());
}
final SelectableMapping keySelectableMapping;
if (columnIterator.hasNext()) {
keySelectableMapping = SelectableMappingImpl.from(tableExpression, columnIterator.next(), simpleFkTarget.getJdbcMapping(), dialect, creationProcess.getSqmFunctionRegistry());
} else {
// case of ToOne with @PrimaryKeyJoinColumn
keySelectableMapping = SelectableMappingImpl.from(tableExpression, table.getColumn(0), simpleFkTarget.getJdbcMapping(), dialect, creationProcess.getSqmFunctionRegistry());
}
final ForeignKeyDescriptor foreignKeyDescriptor = new SimpleForeignKeyDescriptor(attributeMapping.getDeclaringType(), declaringKeyPart, declaringKeyPropertyAccess, keySelectableMapping, simpleFkTarget, bootValueMapping.isReferenceToPrimaryKey(), bootValueMapping.isConstrained(), swapDirection);
attributeMapping.setForeignKeyDescriptor(foreignKeyDescriptor);
} else if (fkTarget instanceof EmbeddableValuedModelPart) {
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = buildEmbeddableForeignKeyDescriptor((EmbeddableValuedModelPart) fkTarget, bootValueMapping, attributeMapping.getDeclaringType(), attributeMapping.findContainingEntityMapping(), swapDirection, dialect, creationProcess);
attributeMapping.setForeignKeyDescriptor(embeddedForeignKeyDescriptor);
} else {
throw new NotYetImplementedFor6Exception("Support for " + fkTarget.getClass() + " foreign-keys not yet implemented: " + bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName());
}
return true;
}
use of org.hibernate.metamodel.mapping.SelectableMapping in project hibernate-orm by hibernate.
the class MappingModelCreationHelper method buildPluralAttributeMapping.
@SuppressWarnings("rawtypes")
public static PluralAttributeMapping buildPluralAttributeMapping(String attrName, int stateArrayPosition, Property bootProperty, ManagedMappingType declaringType, PropertyAccess propertyAccess, CascadeStyle cascadeStyle, FetchMode fetchMode, MappingModelCreationProcess creationProcess) {
final Collection bootValueMapping = (Collection) bootProperty.getValue();
final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext();
final SessionFactoryImplementor sessionFactory = creationContext.getSessionFactory();
final SqlStringGenerationContext sqlStringGenerationContext = sessionFactory.getSqlStringGenerationContext();
final Dialect dialect = sqlStringGenerationContext.getDialect();
final MappingMetamodel domainModel = creationContext.getDomainModel();
final CollectionPersister collectionDescriptor = domainModel.findCollectionDescriptor(bootValueMapping.getRole());
assert collectionDescriptor != null;
final String tableExpression = ((Joinable) collectionDescriptor).getTableName();
final String sqlAliasStem = SqlAliasStemHelper.INSTANCE.generateStemFromAttributeName(bootProperty.getName());
final CollectionMappingType<?> collectionMappingType;
final JavaTypeRegistry jtdRegistry = creationContext.getJavaTypeRegistry();
final CollectionPart elementDescriptor = interpretElement(bootValueMapping, tableExpression, collectionDescriptor, sqlAliasStem, dialect, creationProcess);
final CollectionPart indexDescriptor;
CollectionIdentifierDescriptor identifierDescriptor = null;
final CollectionSemantics<?, ?> collectionSemantics = collectionDescriptor.getCollectionSemantics();
switch(collectionSemantics.getCollectionClassification()) {
case ARRAY:
{
collectionMappingType = new CollectionMappingTypeImpl(jtdRegistry.getDescriptor(Object[].class), StandardArraySemantics.INSTANCE);
final BasicValue index = (BasicValue) ((IndexedCollection) bootValueMapping).getIndex();
final SelectableMapping selectableMapping = SelectableMappingImpl.from(tableExpression, index.getSelectables().get(0), creationContext.getTypeConfiguration().getBasicTypeForJavaType(Integer.class), dialect, creationProcess.getSqmFunctionRegistry());
indexDescriptor = new BasicValuedCollectionPart(collectionDescriptor, CollectionPart.Nature.INDEX, // no converter
null, selectableMapping);
break;
}
case BAG:
{
collectionMappingType = new CollectionMappingTypeImpl(jtdRegistry.getDescriptor(java.util.Collection.class), StandardBagSemantics.INSTANCE);
indexDescriptor = null;
break;
}
case ID_BAG:
{
collectionMappingType = new CollectionMappingTypeImpl(jtdRegistry.getDescriptor(java.util.Collection.class), StandardIdentifierBagSemantics.INSTANCE);
indexDescriptor = null;
assert collectionDescriptor instanceof SQLLoadableCollection;
final SQLLoadableCollection loadableCollection = (SQLLoadableCollection) collectionDescriptor;
final String identifierColumnName = loadableCollection.getIdentifierColumnName();
assert identifierColumnName != null;
identifierDescriptor = new CollectionIdentifierDescriptorImpl(collectionDescriptor, tableExpression, identifierColumnName, (BasicType) loadableCollection.getIdentifierType());
break;
}
case LIST:
{
final BasicValue index = (BasicValue) ((IndexedCollection) bootValueMapping).getIndex();
final SelectableMapping selectableMapping = SelectableMappingImpl.from(tableExpression, index.getSelectables().get(0), creationContext.getTypeConfiguration().getBasicTypeForJavaType(Integer.class), dialect, creationProcess.getSqmFunctionRegistry());
indexDescriptor = new BasicValuedCollectionPart(collectionDescriptor, CollectionPart.Nature.INDEX, // no converter
null, selectableMapping);
collectionMappingType = new CollectionMappingTypeImpl(jtdRegistry.getDescriptor(List.class), StandardListSemantics.INSTANCE);
break;
}
case MAP:
case ORDERED_MAP:
case SORTED_MAP:
{
final Class<? extends java.util.Map> mapJavaType = collectionSemantics.getCollectionClassification() == CollectionClassification.SORTED_MAP ? SortedMap.class : java.util.Map.class;
collectionMappingType = new CollectionMappingTypeImpl(jtdRegistry.getDescriptor(mapJavaType), collectionSemantics);
final String mapKeyTableExpression;
if (bootValueMapping instanceof Map && ((Map) bootValueMapping).getMapKeyPropertyName() != null) {
mapKeyTableExpression = getTableIdentifierExpression(((Map) bootValueMapping).getIndex().getTable(), creationProcess);
} else {
mapKeyTableExpression = tableExpression;
}
indexDescriptor = interpretMapKey(bootValueMapping, collectionDescriptor, mapKeyTableExpression, sqlAliasStem, dialect, creationProcess);
break;
}
case SET:
case ORDERED_SET:
case SORTED_SET:
{
final Class<? extends java.util.Set> setJavaType = collectionSemantics.getCollectionClassification() == CollectionClassification.SORTED_MAP ? SortedSet.class : java.util.Set.class;
collectionMappingType = new CollectionMappingTypeImpl(jtdRegistry.getDescriptor(setJavaType), collectionSemantics);
indexDescriptor = null;
break;
}
default:
{
throw new MappingException("Unexpected CollectionClassification : " + collectionSemantics.getCollectionClassification());
}
}
final StateArrayContributorMetadata contributorMetadata = new StateArrayContributorMetadata() {
@Override
public PropertyAccess getPropertyAccess() {
return propertyAccess;
}
@Override
public MutabilityPlan getMutabilityPlan() {
return ImmutableMutabilityPlan.instance();
}
@Override
public boolean isNullable() {
return bootProperty.isOptional();
}
@Override
public boolean isInsertable() {
return bootProperty.isInsertable();
}
@Override
public boolean isUpdatable() {
return bootProperty.isUpdateable();
}
@Override
public boolean isIncludedInDirtyChecking() {
return false;
}
@Override
public boolean isIncludedInOptimisticLocking() {
return bootProperty.isOptimisticLocked();
}
@Override
public CascadeStyle getCascadeStyle() {
return cascadeStyle;
}
};
final FetchStyle style = FetchOptionsHelper.determineFetchStyleByMetadata(fetchMode, collectionDescriptor.getCollectionType(), sessionFactory);
final FetchTiming timing = FetchOptionsHelper.determineFetchTiming(style, collectionDescriptor.getCollectionType(), collectionDescriptor.isLazy(), collectionDescriptor.getRole(), sessionFactory);
final PluralAttributeMappingImpl pluralAttributeMapping = new PluralAttributeMappingImpl(attrName, bootValueMapping, propertyAccess, entityMappingType -> contributorMetadata, collectionMappingType, stateArrayPosition, elementDescriptor, indexDescriptor, identifierDescriptor, timing, style, cascadeStyle, declaringType, collectionDescriptor);
creationProcess.registerInitializationCallback("PluralAttributeMapping(" + bootValueMapping.getRole() + ")#finishInitialization", () -> {
pluralAttributeMapping.finishInitialization(bootProperty, bootValueMapping, creationProcess);
return true;
});
creationProcess.registerInitializationCallback("PluralAttributeMapping(" + bootValueMapping.getRole() + ") - key descriptor", () -> {
interpretPluralAttributeMappingKeyDescriptor(pluralAttributeMapping, bootValueMapping, collectionDescriptor, declaringType, dialect, creationProcess);
return true;
});
return pluralAttributeMapping;
}
Aggregations