Search in sources :

Example 1 with PropertyAccessStrategyCompositeUserTypeImpl

use of org.hibernate.property.access.internal.PropertyAccessStrategyCompositeUserTypeImpl in project hibernate-orm by hibernate.

the class AnnotationBinder method fillComponent.

public static Component fillComponent(PropertyHolder propertyHolder, PropertyData inferredData, // base inferred data correspond to the entity reproducing inferredData's properties (ie IdClass)
PropertyData baseInferredData, AccessType propertyAccessor, boolean isNullable, EntityBinder entityBinder, boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass, Class<? extends EmbeddableInstantiator> customInstantiatorImpl, Class<? extends CompositeUserType<?>> compositeUserTypeClass, MetadataBuildingContext buildingContext, Map<XClass, InheritanceState> inheritanceStatePerClass) {
    /*
		 * inSecondPass can only be used to apply right away the second pass of a composite-element
		 * Because it's a value type, there is no bidirectional association, hence second pass
		 * ordering does not matter
		 */
    Component comp = createComponent(propertyHolder, inferredData, isComponentEmbedded, isIdentifierMapper, customInstantiatorImpl, buildingContext);
    String subpath = BinderHelper.getPath(propertyHolder, inferredData);
    LOG.tracev("Binding component with path: {0}", subpath);
    PropertyHolder subHolder = buildPropertyHolder(comp, subpath, inferredData, propertyHolder, buildingContext);
    // propertyHolder here is the owner of the component property.  Tell it we are about to start the component...
    propertyHolder.startingProperty(inferredData.getProperty());
    final XClass xClassProcessed = inferredData.getPropertyClass();
    List<PropertyData> classElements = new ArrayList<>();
    final CompositeUserType<?> compositeUserType;
    XClass returnedClassOrElement;
    if (compositeUserTypeClass == null) {
        compositeUserType = null;
        returnedClassOrElement = inferredData.getClassOrElement();
    } else {
        compositeUserType = buildingContext.getBootstrapContext().getServiceRegistry().getService(ManagedBeanRegistry.class).getBean(compositeUserTypeClass).getBeanInstance();
        comp.setTypeName(compositeUserTypeClass.getName());
        returnedClassOrElement = buildingContext.getBootstrapContext().getReflectionManager().toXClass(compositeUserType.embeddable());
    }
    List<PropertyData> baseClassElements = null;
    Map<String, PropertyData> orderedBaseClassElements = new HashMap<>();
    XClass baseReturnedClassOrElement;
    if (baseInferredData != null) {
        baseClassElements = new ArrayList<>();
        baseReturnedClassOrElement = baseInferredData.getClassOrElement();
        // might be spread across the subclasses and super classes.
        while (!Object.class.getName().equals(baseReturnedClassOrElement.getName())) {
            addElementsOfClass(baseClassElements, new PropertyContainer(baseReturnedClassOrElement, xClassProcessed, propertyAccessor), buildingContext);
            for (PropertyData element : baseClassElements) {
                orderedBaseClassElements.put(element.getPropertyName(), element);
            }
            baseReturnedClassOrElement = baseReturnedClassOrElement.getSuperclass();
        }
    }
    // embeddable elements can have type defs
    PropertyContainer propContainer = new PropertyContainer(returnedClassOrElement, xClassProcessed, propertyAccessor);
    addElementsOfClass(classElements, propContainer, buildingContext);
    // add elements of the embeddable superclass
    XClass superClass = xClassProcessed.getSuperclass();
    while (superClass != null && superClass.isAnnotationPresent(MappedSuperclass.class)) {
        // FIXME: proper support of type variables incl var resolved at upper levels
        propContainer = new PropertyContainer(superClass, xClassProcessed, propertyAccessor);
        addElementsOfClass(classElements, propContainer, buildingContext);
        superClass = superClass.getSuperclass();
    }
    if (baseClassElements != null) {
        // useful to avoid breaking pre JPA 2 mappings
        if (!hasAnnotationsOnIdClass(xClassProcessed)) {
            for (int i = 0; i < classElements.size(); i++) {
                final PropertyData idClassPropertyData = classElements.get(i);
                final PropertyData entityPropertyData = orderedBaseClassElements.get(idClassPropertyData.getPropertyName());
                if (propertyHolder.isInIdClass()) {
                    if (entityPropertyData == null) {
                        throw new AnnotationException("Property of @IdClass not found in entity " + baseInferredData.getPropertyClass().getName() + ": " + idClassPropertyData.getPropertyName());
                    }
                    final boolean hasXToOneAnnotation = hasToOneAnnotation(entityPropertyData.getProperty());
                    final boolean isOfDifferentType = !entityPropertyData.getClassOrElement().equals(idClassPropertyData.getClassOrElement());
                    if (!hasXToOneAnnotation || !isOfDifferentType) {
                        // this works since they are in the same order
                        classElements.set(i, entityPropertyData);
                    }
                // else {
                // don't replace here as we need to use the actual original return type
                // the annotation overriding will be dealt with by a mechanism similar to @MapsId
                // }
                } else {
                    // this works since they are in the same order
                    classElements.set(i, entityPropertyData);
                }
            }
        }
    }
    for (PropertyData propertyAnnotatedElement : classElements) {
        processElementAnnotations(subHolder, isNullable ? Nullability.NO_CONSTRAINT : Nullability.FORCED_NOT_NULL, propertyAnnotatedElement, new HashMap<>(), entityBinder, isIdentifierMapper, isComponentEmbedded, inSecondPass, buildingContext, inheritanceStatePerClass);
        XProperty property = propertyAnnotatedElement.getProperty();
        if (property.isAnnotationPresent(GeneratedValue.class) && property.isAnnotationPresent(Id.class)) {
            GeneratedValue generatedValue = property.getAnnotation(GeneratedValue.class);
            String generatorType = generatedValue != null ? generatorType(generatedValue, buildingContext, property.getType()) : DEFAULT_ID_GEN_STRATEGY;
            String generator = generatedValue != null ? generatedValue.generator() : "";
            if (isGlobalGeneratorNameGlobal(buildingContext)) {
                buildGenerators(property, buildingContext);
                SecondPass secondPass = new IdGeneratorResolverSecondPass((SimpleValue) comp.getProperty(property.getName()).getValue(), property, generatorType, generator, buildingContext);
                buildingContext.getMetadataCollector().addSecondPass(secondPass);
                handleTypeDescriptorRegistrations(property, buildingContext);
                bindEmbeddableInstantiatorRegistrations(property, buildingContext);
                bindCompositeUserTypeRegistrations(property, buildingContext);
            } else {
                Map<String, IdentifierGeneratorDefinition> localGenerators = new HashMap<>(buildGenerators(property, buildingContext));
                makeIdGenerator((SimpleValue) comp.getProperty(property.getName()).getValue(), property, generatorType, generator, buildingContext, localGenerators);
            }
        }
    }
    if (compositeUserType != null) {
        comp.sortProperties();
        final List<String> sortedPropertyNames = new ArrayList<>(comp.getPropertySpan());
        final List<Type> sortedPropertyTypes = new ArrayList<>(comp.getPropertySpan());
        final PropertyAccessStrategy strategy = new PropertyAccessStrategyCompositeUserTypeImpl(compositeUserType, sortedPropertyNames, sortedPropertyTypes);
        for (Property property : comp.getProperties()) {
            sortedPropertyNames.add(property.getName());
            sortedPropertyTypes.add(PropertyAccessStrategyMixedImpl.INSTANCE.buildPropertyAccess(compositeUserType.embeddable(), property.getName(), false).getGetter().getReturnType());
            property.setPropertyAccessStrategy(strategy);
        }
    }
    return comp;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) XClass(org.hibernate.annotations.common.reflection.XClass) GeneratedValue(jakarta.persistence.GeneratedValue) PropertyAccessStrategyCompositeUserTypeImpl(org.hibernate.property.access.internal.PropertyAccessStrategyCompositeUserTypeImpl) ManagedBeanRegistry(org.hibernate.resource.beans.spi.ManagedBeanRegistry) NullableDiscriminatorColumnSecondPass(org.hibernate.cfg.internal.NullableDiscriminatorColumnSecondPass) AnnotationException(org.hibernate.AnnotationException) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty) PropertyAccessStrategy(org.hibernate.property.access.spi.PropertyAccessStrategy) XProperty(org.hibernate.annotations.common.reflection.XProperty) UniqueConstraint(jakarta.persistence.UniqueConstraint) Constraint(org.hibernate.mapping.Constraint) DiscriminatorType(jakarta.persistence.DiscriminatorType) FetchType(jakarta.persistence.FetchType) JdbcType(org.hibernate.type.descriptor.jdbc.JdbcType) CustomType(org.hibernate.type.CustomType) CompositeType(org.hibernate.annotations.CompositeType) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) CompositeUserType(org.hibernate.usertype.CompositeUserType) IdGeneratorType(org.hibernate.annotations.IdGeneratorType) MapKeyJavaType(org.hibernate.annotations.MapKeyJavaType) CallbackType(org.hibernate.jpa.event.spi.CallbackType) InheritanceType(jakarta.persistence.InheritanceType) MapKeyJdbcType(org.hibernate.annotations.MapKeyJdbcType) JavaType(org.hibernate.type.descriptor.java.JavaType) UserType(org.hibernate.usertype.UserType) MapKeyCustomType(org.hibernate.annotations.MapKeyCustomType) Type(java.lang.reflect.Type) CascadeType(org.hibernate.annotations.CascadeType) PropertyHolderBuilder.buildPropertyHolder(org.hibernate.cfg.PropertyHolderBuilder.buildPropertyHolder) MappedSuperclass(jakarta.persistence.MappedSuperclass) IdentifierGeneratorDefinition(org.hibernate.boot.model.IdentifierGeneratorDefinition) BinderHelper.getPropertyOverriddenByMapperOrMapsId(org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId) Id(jakarta.persistence.Id) NaturalId(org.hibernate.annotations.NaturalId) EmbeddedId(jakarta.persistence.EmbeddedId) MapsId(jakarta.persistence.MapsId) CollectionId(org.hibernate.annotations.CollectionId)

Aggregations

DiscriminatorType (jakarta.persistence.DiscriminatorType)1 EmbeddedId (jakarta.persistence.EmbeddedId)1 FetchType (jakarta.persistence.FetchType)1 GeneratedValue (jakarta.persistence.GeneratedValue)1 Id (jakarta.persistence.Id)1 InheritanceType (jakarta.persistence.InheritanceType)1 MappedSuperclass (jakarta.persistence.MappedSuperclass)1 MapsId (jakarta.persistence.MapsId)1 UniqueConstraint (jakarta.persistence.UniqueConstraint)1 Type (java.lang.reflect.Type)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 AnnotationException (org.hibernate.AnnotationException)1 CascadeType (org.hibernate.annotations.CascadeType)1 CollectionId (org.hibernate.annotations.CollectionId)1 CompositeType (org.hibernate.annotations.CompositeType)1 IdGeneratorType (org.hibernate.annotations.IdGeneratorType)1 MapKeyCustomType (org.hibernate.annotations.MapKeyCustomType)1 MapKeyJavaType (org.hibernate.annotations.MapKeyJavaType)1 MapKeyJdbcType (org.hibernate.annotations.MapKeyJdbcType)1