Search in sources :

Example 1 with AnnotatedColumn

use of org.hibernate.cfg.AnnotatedColumn in project hibernate-orm by hibernate.

the class CollectionBinder method handleManyToAny.

private void handleManyToAny(Collection collValue, AnnotatedJoinColumn[] inverseJoinColumns, boolean cascadeDeleteEnabled, XProperty property, MetadataBuildingContext buildingContext) {
    // @ManyToAny
    // Make sure that collTyp is never used during the @ManyToAny branch: it will be set to void.class
    final PropertyData inferredData = new PropertyInferredData(null, property, "unsupported", buildingContext.getBootstrapContext().getReflectionManager());
    XProperty prop = inferredData.getProperty();
    final jakarta.persistence.Column discriminatorColumnAnn = prop.getAnnotation(jakarta.persistence.Column.class);
    final Formula discriminatorFormulaAnn = getOverridableAnnotation(prop, Formula.class, buildingContext);
    // override the table
    for (AnnotatedColumn column : inverseJoinColumns) {
        column.setTable(collValue.getCollectionTable());
    }
    ManyToAny anyAnn = property.getAnnotation(ManyToAny.class);
    final Any any = BinderHelper.buildAnyValue(discriminatorColumnAnn, discriminatorFormulaAnn, inverseJoinColumns, inferredData, cascadeDeleteEnabled, anyAnn.fetch() == FetchType.LAZY, Nullability.NO_CONSTRAINT, propertyHolder, new EntityBinder(), true, buildingContext);
    collValue.setElement(any);
}
Also used : ManyToAny(org.hibernate.annotations.ManyToAny) Formula(org.hibernate.annotations.Formula) PropertyData(org.hibernate.cfg.PropertyData) XProperty(org.hibernate.annotations.common.reflection.XProperty) AnnotatedColumn(org.hibernate.cfg.AnnotatedColumn) PropertyInferredData(org.hibernate.cfg.PropertyInferredData) Any(org.hibernate.mapping.Any) ManyToAny(org.hibernate.annotations.ManyToAny)

Example 2 with AnnotatedColumn

use of org.hibernate.cfg.AnnotatedColumn in project hibernate-orm by hibernate.

the class IdBagBinder method bindStarToManySecondPass.

@Override
protected boolean bindStarToManySecondPass(Map<String, PersistentClass> persistentClasses, XClass collType, AnnotatedJoinColumn[] fkJoinColumns, AnnotatedJoinColumn[] keyColumns, AnnotatedJoinColumn[] inverseColumns, AnnotatedColumn[] elementColumns, boolean isEmbedded, XProperty property, boolean unique, TableBinder associationTableBinder, boolean ignoreNotFound, MetadataBuildingContext buildingContext) {
    boolean result = super.bindStarToManySecondPass(persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns, elementColumns, isEmbedded, property, unique, associationTableBinder, ignoreNotFound, getBuildingContext());
    final CollectionId collectionIdAnn = property.getAnnotation(CollectionId.class);
    if (collectionIdAnn == null) {
        throw new MappingException("idbag mapping missing @CollectionId");
    }
    final PropertyData propertyData = new WrappedInferredData(new PropertyInferredData(null, property, // default access should not be useful
    null, buildingContext.getBootstrapContext().getReflectionManager()), "id");
    final AnnotatedColumn[] idColumns = AnnotatedColumn.buildColumnsFromAnnotations(new Column[] { collectionIdAnn.column() }, null, Nullability.FORCED_NOT_NULL, propertyHolder, propertyData, Collections.emptyMap(), buildingContext);
    // we need to make sure all id columns must be not-null.
    for (AnnotatedColumn idColumn : idColumns) {
        idColumn.setNullable(false);
    }
    final BasicValueBinder valueBinder = new BasicValueBinder(BasicValueBinder.Kind.COLLECTION_ID, buildingContext);
    final Table table = collection.getCollectionTable();
    valueBinder.setTable(table);
    valueBinder.setColumns(idColumns);
    valueBinder.setType(property, collType, null, null);
    final BasicValue id = valueBinder.make();
    ((IdentifierCollection) collection).setIdentifier(id);
    final String namedGenerator = collectionIdAnn.generator();
    if ("identity".equals(namedGenerator)) {
        throw new MappingException("IDENTITY generation not supported for CollectionId");
    }
    if ("assigned".equals(namedGenerator)) {
        throw new MappingException("Assigned generation not supported for CollectionId");
    }
    if ("native".equals(namedGenerator)) {
        throw new MappingException("Native generation not supported for CollectionId");
    }
    final String generatorName;
    final String generatorType;
    if ("sequence".equals(namedGenerator)) {
        generatorType = namedGenerator;
        generatorName = "";
    } else if ("increment".equals(namedGenerator)) {
        generatorType = namedGenerator;
        generatorName = "";
    } else {
        generatorType = namedGenerator;
        generatorName = namedGenerator;
    }
    id.setIdentifierGeneratorStrategy(generatorType);
    if (buildingContext.getBootstrapContext().getJpaCompliance().isGlobalGeneratorScopeEnabled()) {
        SecondPass secondPass = new IdGeneratorResolverSecondPass(id, property, generatorType, generatorName, getBuildingContext());
        buildingContext.getMetadataCollector().addSecondPass(secondPass);
    } else {
        BinderHelper.makeIdGenerator(id, property, generatorType, generatorName, getBuildingContext(), localGenerators);
    }
    return result;
}
Also used : IdGeneratorResolverSecondPass(org.hibernate.cfg.IdGeneratorResolverSecondPass) WrappedInferredData(org.hibernate.cfg.WrappedInferredData) PropertyData(org.hibernate.cfg.PropertyData) Table(org.hibernate.mapping.Table) PropertyInferredData(org.hibernate.cfg.PropertyInferredData) MappingException(org.hibernate.MappingException) BasicValue(org.hibernate.mapping.BasicValue) IdentifierCollection(org.hibernate.mapping.IdentifierCollection) CollectionId(org.hibernate.annotations.CollectionId) IdGeneratorResolverSecondPass(org.hibernate.cfg.IdGeneratorResolverSecondPass) SecondPass(org.hibernate.cfg.SecondPass) AnnotatedColumn(org.hibernate.cfg.AnnotatedColumn)

Example 3 with AnnotatedColumn

use of org.hibernate.cfg.AnnotatedColumn in project hibernate-orm by hibernate.

the class CollectionBinder method handleElementCollection.

private void handleElementCollection(Collection collValue, AnnotatedColumn[] elementColumns, boolean isEmbedded, XClass collType, XProperty property, PropertyHolder parentPropertyHolder, MetadataBuildingContext buildingContext, String hqlOrderBy) {
    XClass elementClass;
    AnnotatedClassType classType;
    CollectionPropertyHolder holder;
    if (BinderHelper.PRIMITIVE_NAMES.contains(collType.getName())) {
        classType = AnnotatedClassType.NONE;
        elementClass = null;
        holder = PropertyHolderBuilder.buildPropertyHolder(collValue, collValue.getRole(), null, property, parentPropertyHolder, buildingContext);
    } else {
        elementClass = collType;
        classType = buildingContext.getMetadataCollector().getClassType(elementClass);
        holder = PropertyHolderBuilder.buildPropertyHolder(collValue, collValue.getRole(), elementClass, property, parentPropertyHolder, buildingContext);
        // 'parentPropertyHolder' is the PropertyHolder for the owner of the collection
        // 'holder' is the CollectionPropertyHolder.
        // 'property' is the collection XProperty
        parentPropertyHolder.startingProperty(property);
        // force in case of attribute override
        boolean attributeOverride = property.isAnnotationPresent(AttributeOverride.class) || property.isAnnotationPresent(AttributeOverrides.class);
        // todo : force in the case of Convert annotation(s) with embedded paths (beyond key/value prefixes)?
        if (isEmbedded || attributeOverride) {
            classType = AnnotatedClassType.EMBEDDABLE;
        }
    }
    final Class<? extends CompositeUserType<?>> compositeUserType = resolveCompositeUserType(property, elementClass, buildingContext);
    if (AnnotatedClassType.EMBEDDABLE == classType || compositeUserType != null) {
        holder.prepare(property);
        EntityBinder entityBinder = new EntityBinder();
        PersistentClass owner = collValue.getOwner();
        final AccessType baseAccessType;
        final Access accessAnn = property.getAnnotation(Access.class);
        if (accessAnn != null) {
            // the attribute is locally annotated with `@Access`, use that
            baseAccessType = accessAnn.value() == PROPERTY ? AccessType.PROPERTY : AccessType.FIELD;
        } else if (owner.getIdentifierProperty() != null) {
            // use the access for the owning entity's id attribute, if one
            baseAccessType = owner.getIdentifierProperty().getPropertyAccessorName().equals("property") ? AccessType.PROPERTY : AccessType.FIELD;
        } else if (owner.getIdentifierMapper() != null && owner.getIdentifierMapper().getPropertySpan() > 0) {
            // use the access for the owning entity's "id mapper", if one
            Property prop = owner.getIdentifierMapper().getProperties().get(0);
            baseAccessType = prop.getPropertyAccessorName().equals("property") ? AccessType.PROPERTY : AccessType.FIELD;
        } else {
            // otherwise...
            throw new AssertionFailure("Unable to guess collection property accessor name");
        }
        // TODO be smart with isNullable
        Component component = fillComponent(holder, getSpecialMembers(elementClass), baseAccessType, true, entityBinder, false, false, true, resolveCustomInstantiator(property, elementClass, buildingContext), compositeUserType, buildingContext, inheritanceStatePerClass);
        collValue.setElement(component);
        if (StringHelper.isNotEmpty(hqlOrderBy)) {
            String orderBy = adjustUserSuppliedValueCollectionOrderingFragment(hqlOrderBy);
            if (orderBy != null) {
                collValue.setOrderBy(orderBy);
            }
        }
    } else {
        holder.prepare(property);
        final BasicValueBinder elementBinder = new BasicValueBinder(BasicValueBinder.Kind.COLLECTION_ELEMENT, buildingContext);
        elementBinder.setReturnedClassName(collType.getName());
        if (elementColumns == null || elementColumns.length == 0) {
            elementColumns = new AnnotatedColumn[1];
            AnnotatedColumn column = new AnnotatedColumn();
            column.setImplicit(false);
            // not following the spec but more clean
            column.setNullable(true);
            column.setLogicalColumnName(Collection.DEFAULT_ELEMENT_COLUMN_NAME);
            // TODO create an EMPTY_JOINS collection
            column.setJoins(new HashMap<>());
            column.setBuildingContext(buildingContext);
            column.bind();
            elementColumns[0] = column;
        }
        // override the table
        for (AnnotatedColumn column : elementColumns) {
            column.setTable(collValue.getCollectionTable());
        }
        elementBinder.setColumns(elementColumns);
        elementBinder.setType(property, elementClass, collValue.getOwnerEntityName(), holder.resolveElementAttributeConverterDescriptor(property, elementClass));
        elementBinder.setPersistentClassName(propertyHolder.getEntityName());
        elementBinder.setAccessType(accessType);
        collValue.setElement(elementBinder.make());
        String orderBy = adjustUserSuppliedValueCollectionOrderingFragment(hqlOrderBy);
        if (orderBy != null) {
            collValue.setOrderBy(orderBy);
        }
    }
}
Also used : CollectionPropertyHolder(org.hibernate.cfg.CollectionPropertyHolder) AssertionFailure(org.hibernate.AssertionFailure) Access(jakarta.persistence.Access) XClass(org.hibernate.annotations.common.reflection.XClass) AttributeOverride(jakarta.persistence.AttributeOverride) AttributeOverrides(jakarta.persistence.AttributeOverrides) AnnotatedColumn(org.hibernate.cfg.AnnotatedColumn) AnnotationBinder.fillComponent(org.hibernate.cfg.AnnotationBinder.fillComponent) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty) AnnotatedClassType(org.hibernate.cfg.AnnotatedClassType) AccessType(org.hibernate.cfg.AccessType) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 4 with AnnotatedColumn

use of org.hibernate.cfg.AnnotatedColumn in project hibernate-orm by hibernate.

the class MapBinder method bindKeyFromAssociationTable.

private void bindKeyFromAssociationTable(XClass collType, Map<String, PersistentClass> persistentClasses, String mapKeyPropertyName, XProperty property, boolean isEmbedded, MetadataBuildingContext buildingContext, AnnotatedColumn[] mapKeyColumns, AnnotatedJoinColumn[] mapKeyManyToManyColumns, String targetPropertyName) {
    if (mapKeyPropertyName != null) {
        // this is an EJB3 @MapKey
        PersistentClass associatedClass = persistentClasses.get(collType.getName());
        if (associatedClass == null)
            throw new AnnotationException("Associated class not found: " + collType);
        Property mapProperty = BinderHelper.findPropertyByName(associatedClass, mapKeyPropertyName);
        if (mapProperty == null) {
            throw new AnnotationException("Map key property not found: " + collType + "." + mapKeyPropertyName);
        }
        org.hibernate.mapping.Map map = (org.hibernate.mapping.Map) this.collection;
        // HHH-11005 - if InheritanceType.JOINED then need to find class defining the column
        InheritanceState inheritanceState = inheritanceStatePerClass.get(collType);
        PersistentClass targetPropertyPersistentClass = InheritanceType.JOINED.equals(inheritanceState.getType()) ? mapProperty.getPersistentClass() : associatedClass;
        Value indexValue = createFormulatedValue(mapProperty.getValue(), map, targetPropertyName, associatedClass, targetPropertyPersistentClass, buildingContext);
        map.setIndex(indexValue);
        map.setMapKeyPropertyName(mapKeyPropertyName);
    } else {
        // this is a true Map mapping
        // TODO ugly copy/paste from CollectionBinder.bindManyToManySecondPass
        String mapKeyType;
        Class<?> target = void.class;
        /*
			 * target has priority over reflection for the map key type
			 * JPA 2 has priority
			 */
        if (property.isAnnotationPresent(MapKeyClass.class)) {
            target = property.getAnnotation(MapKeyClass.class).value();
        }
        if (!void.class.equals(target)) {
            mapKeyType = target.getName();
        } else {
            mapKeyType = property.getMapKey().getName();
        }
        PersistentClass collectionEntity = persistentClasses.get(mapKeyType);
        boolean isIndexOfEntities = collectionEntity != null;
        ManyToOne element = null;
        org.hibernate.mapping.Map mapValue = (org.hibernate.mapping.Map) this.collection;
        if (isIndexOfEntities) {
            element = new ManyToOne(buildingContext, mapValue.getCollectionTable());
            mapValue.setIndex(element);
            element.setReferencedEntityName(mapKeyType);
            // element.setFetchMode( fetchMode );
            // element.setLazy( fetchMode != FetchMode.JOIN );
            // make the second join non lazy
            element.setFetchMode(FetchMode.JOIN);
            element.setLazy(false);
        // does not make sense for a map key element.setIgnoreNotFound( ignoreNotFound );
        } else {
            final XClass keyXClass;
            AnnotatedClassType classType;
            if (BinderHelper.PRIMITIVE_NAMES.contains(mapKeyType)) {
                classType = AnnotatedClassType.NONE;
                keyXClass = null;
            } else {
                final BootstrapContext bootstrapContext = buildingContext.getBootstrapContext();
                final Class<Object> mapKeyClass = bootstrapContext.getClassLoaderAccess().classForName(mapKeyType);
                keyXClass = bootstrapContext.getReflectionManager().toXClass(mapKeyClass);
                classType = buildingContext.getMetadataCollector().getClassType(keyXClass);
                // force in case of attribute override naming the key
                if (isEmbedded || mappingDefinedAttributeOverrideOnMapKey(property)) {
                    classType = AnnotatedClassType.EMBEDDABLE;
                }
            }
            CollectionPropertyHolder holder = buildPropertyHolder(mapValue, StringHelper.qualify(mapValue.getRole(), "mapkey"), keyXClass, property, propertyHolder, buildingContext);
            // 'propertyHolder' is the PropertyHolder for the owner of the collection
            // 'holder' is the CollectionPropertyHolder.
            // 'property' is the collection XProperty
            propertyHolder.startingProperty(property);
            holder.prepare(property);
            PersistentClass owner = mapValue.getOwner();
            AccessType accessType;
            // String accessType = access != null ? access.value() : null;
            if (owner.getIdentifierProperty() != null) {
                accessType = owner.getIdentifierProperty().getPropertyAccessorName().equals("property") ? AccessType.PROPERTY : AccessType.FIELD;
            } else if (owner.getIdentifierMapper() != null && owner.getIdentifierMapper().getPropertySpan() > 0) {
                Property prop = owner.getIdentifierMapper().getProperties().get(0);
                accessType = prop.getPropertyAccessorName().equals("property") ? AccessType.PROPERTY : AccessType.FIELD;
            } else {
                throw new AssertionFailure("Unable to guess collection property accessor name");
            }
            final Class<? extends CompositeUserType<?>> compositeUserType = resolveCompositeUserType(property, keyXClass, buildingContext);
            if (AnnotatedClassType.EMBEDDABLE.equals(classType) || compositeUserType != null) {
                EntityBinder entityBinder = new EntityBinder();
                PropertyData inferredData = isHibernateExtensionMapping() ? new PropertyPreloadedData(AccessType.PROPERTY, "index", keyXClass) : new PropertyPreloadedData(AccessType.PROPERTY, "key", keyXClass);
                // "key" is the JPA 2 prefix for map keys
                // TODO be smart with isNullable
                Component component = AnnotationBinder.fillComponent(holder, inferredData, accessType, true, entityBinder, false, false, true, null, compositeUserType, buildingContext, inheritanceStatePerClass);
                mapValue.setIndex(component);
            } else {
                final BasicValueBinder elementBinder = new BasicValueBinder(BasicValueBinder.Kind.MAP_KEY, buildingContext);
                elementBinder.setReturnedClassName(mapKeyType);
                AnnotatedColumn[] elementColumns = mapKeyColumns;
                if (elementColumns == null || elementColumns.length == 0) {
                    elementColumns = new AnnotatedColumn[1];
                    AnnotatedColumn column = new AnnotatedColumn();
                    column.setImplicit(false);
                    column.setNullable(true);
                    column.setLength(Size.DEFAULT_LENGTH);
                    column.setLogicalColumnName(Collection.DEFAULT_KEY_COLUMN_NAME);
                    // TODO create an EMPTY_JOINS collection
                    column.setJoins(new HashMap<>());
                    column.setBuildingContext(buildingContext);
                    column.bind();
                    elementColumns[0] = column;
                }
                // override the table
                for (AnnotatedColumn column : elementColumns) {
                    column.setTable(mapValue.getCollectionTable());
                }
                elementBinder.setColumns(elementColumns);
                // do not call setType as it extracts the type from @Type
                // the algorithm generally does not apply for map key anyway
                elementBinder.setType(property, keyXClass, this.collection.getOwnerEntityName(), holder.mapKeyAttributeConverterDescriptor(property, keyXClass));
                elementBinder.setPersistentClassName(propertyHolder.getEntityName());
                elementBinder.setAccessType(accessType);
                mapValue.setIndex(elementBinder.make());
            }
        }
        // FIXME pass the Index Entity JoinColumns
        if (!collection.isOneToMany()) {
            // index column should not be null
            for (AnnotatedJoinColumn col : mapKeyManyToManyColumns) {
                col.forceNotNull();
            }
        }
        if (element != null) {
            final jakarta.persistence.ForeignKey foreignKey = getMapKeyForeignKey(property);
            if (foreignKey != null) {
                if (foreignKey.value() == ConstraintMode.NO_CONSTRAINT || foreignKey.value() == ConstraintMode.PROVIDER_DEFAULT && getBuildingContext().getBuildingOptions().isNoConstraintByDefault()) {
                    element.disableForeignKey();
                } else {
                    element.setForeignKeyName(StringHelper.nullIfEmpty(foreignKey.name()));
                    element.setForeignKeyDefinition(StringHelper.nullIfEmpty(foreignKey.foreignKeyDefinition()));
                }
            }
        }
        if (isIndexOfEntities) {
            bindManytoManyInverseFk(collectionEntity, mapKeyManyToManyColumns, element, // a map key column has no unique constraint
            false, buildingContext);
        }
    }
}
Also used : PropertyData(org.hibernate.cfg.PropertyData) BootstrapContext(org.hibernate.boot.spi.BootstrapContext) PropertyPreloadedData(org.hibernate.cfg.PropertyPreloadedData) XClass(org.hibernate.annotations.common.reflection.XClass) ManyToOne(org.hibernate.mapping.ManyToOne) AnnotatedColumn(org.hibernate.cfg.AnnotatedColumn) AnnotationException(org.hibernate.AnnotationException) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty) AccessType(org.hibernate.cfg.AccessType) PersistentClass(org.hibernate.mapping.PersistentClass) CollectionPropertyHolder(org.hibernate.cfg.CollectionPropertyHolder) AssertionFailure(org.hibernate.AssertionFailure) InheritanceState(org.hibernate.cfg.InheritanceState) SimpleValue(org.hibernate.mapping.SimpleValue) Value(org.hibernate.mapping.Value) BasicValue(org.hibernate.mapping.BasicValue) DependantBasicValue(org.hibernate.mapping.DependantBasicValue) AnnotatedJoinColumn(org.hibernate.cfg.AnnotatedJoinColumn) Map(java.util.Map) HashMap(java.util.HashMap) AnnotatedClassType(org.hibernate.cfg.AnnotatedClassType)

Aggregations

AnnotatedColumn (org.hibernate.cfg.AnnotatedColumn)4 XProperty (org.hibernate.annotations.common.reflection.XProperty)3 PropertyData (org.hibernate.cfg.PropertyData)3 AssertionFailure (org.hibernate.AssertionFailure)2 XClass (org.hibernate.annotations.common.reflection.XClass)2 AccessType (org.hibernate.cfg.AccessType)2 AnnotatedClassType (org.hibernate.cfg.AnnotatedClassType)2 CollectionPropertyHolder (org.hibernate.cfg.CollectionPropertyHolder)2 PropertyInferredData (org.hibernate.cfg.PropertyInferredData)2 BasicValue (org.hibernate.mapping.BasicValue)2 Component (org.hibernate.mapping.Component)2 PersistentClass (org.hibernate.mapping.PersistentClass)2 Property (org.hibernate.mapping.Property)2 Access (jakarta.persistence.Access)1 AttributeOverride (jakarta.persistence.AttributeOverride)1 AttributeOverrides (jakarta.persistence.AttributeOverrides)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 AnnotationException (org.hibernate.AnnotationException)1 MappingException (org.hibernate.MappingException)1