Search in sources :

Example 1 with GeneratedValue

use of jakarta.persistence.GeneratedValue in project hibernate-orm by hibernate.

the class AnnotationBinder method processId.

private static void processId(PropertyHolder propertyHolder, PropertyData inferredData, SimpleValue idValue, Map<String, IdentifierGeneratorDefinition> classGenerators, boolean isIdentifierMapper, MetadataBuildingContext buildingContext) {
    if (isIdentifierMapper) {
        throw new AnnotationException("@IdClass class should not have @Id nor @EmbeddedId properties: " + BinderHelper.getPath(propertyHolder, inferredData));
    }
    XClass entityXClass = inferredData.getClassOrElement();
    XProperty idXProperty = inferredData.getProperty();
    final Annotation generatorAnnotation = HCANNHelper.findContainingAnnotation(idXProperty, IdGeneratorType.class);
    if (generatorAnnotation != null) {
        idValue.setCustomIdGeneratorCreator(new CustomIdGeneratorCreator(generatorAnnotation, idXProperty));
    } else {
        // manage composite related metadata
        // guess if its a component and find id data access (property, field etc)
        final boolean isComponent = entityXClass.isAnnotationPresent(Embeddable.class) || idXProperty.isAnnotationPresent(EmbeddedId.class);
        GeneratedValue generatedValue = idXProperty.getAnnotation(GeneratedValue.class);
        String generatorType = generatedValue != null ? generatorType(generatedValue, buildingContext, entityXClass) : "assigned";
        String generatorName = generatedValue != null ? generatedValue.generator() : "";
        if (isComponent) {
            // a component must not have any generator
            generatorType = "assigned";
        }
        if (isGlobalGeneratorNameGlobal(buildingContext)) {
            buildGenerators(idXProperty, buildingContext);
            SecondPass secondPass = new IdGeneratorResolverSecondPass(idValue, idXProperty, generatorType, generatorName, buildingContext);
            buildingContext.getMetadataCollector().addSecondPass(secondPass);
        } else {
            // clone classGenerator and override with local values
            HashMap<String, IdentifierGeneratorDefinition> localGenerators = new HashMap<>(classGenerators);
            localGenerators.putAll(buildGenerators(idXProperty, buildingContext));
            makeIdGenerator(idValue, idXProperty, generatorType, generatorName, buildingContext, localGenerators);
        }
        if (LOG.isTraceEnabled()) {
            LOG.tracev("Bind {0} on {1}", (isComponent ? "@EmbeddedId" : "@Id"), inferredData.getPropertyName());
        }
    }
}
Also used : XProperty(org.hibernate.annotations.common.reflection.XProperty) HashMap(java.util.HashMap) EmbeddedId(jakarta.persistence.EmbeddedId) XClass(org.hibernate.annotations.common.reflection.XClass) AnnotatedColumn.buildColumnFromAnnotation(org.hibernate.cfg.AnnotatedColumn.buildColumnFromAnnotation) OverridesAnnotation(org.hibernate.annotations.DialectOverride.OverridesAnnotation) Annotation(java.lang.annotation.Annotation) AnnotatedColumn.buildFormulaFromAnnotation(org.hibernate.cfg.AnnotatedColumn.buildFormulaFromAnnotation) AnnotatedColumn.buildColumnFromNoAnnotation(org.hibernate.cfg.AnnotatedColumn.buildColumnFromNoAnnotation) Embeddable(jakarta.persistence.Embeddable) GeneratedValue(jakarta.persistence.GeneratedValue) NullableDiscriminatorColumnSecondPass(org.hibernate.cfg.internal.NullableDiscriminatorColumnSecondPass) IdentifierGeneratorDefinition(org.hibernate.boot.model.IdentifierGeneratorDefinition) AnnotationException(org.hibernate.AnnotationException)

Example 2 with GeneratedValue

use of jakarta.persistence.GeneratedValue 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)

Example 3 with GeneratedValue

use of jakarta.persistence.GeneratedValue in project hibernate-orm by hibernate.

the class BinderHelper method getIdentifierGenerator.

private static IdentifierGeneratorDefinition getIdentifierGenerator(String name, XProperty idXProperty, Map<String, IdentifierGeneratorDefinition> localGenerators, MetadataBuildingContext buildingContext) {
    if (localGenerators != null) {
        final IdentifierGeneratorDefinition result = localGenerators.get(name);
        if (result != null) {
            return result;
        }
    }
    final IdentifierGeneratorDefinition globalDefinition = buildingContext.getMetadataCollector().getIdentifierGenerator(name);
    if (globalDefinition != null) {
        return globalDefinition;
    }
    log.debugf("Could not resolve explicit IdentifierGeneratorDefinition - using implicit interpretation (%s)", name);
    // If we were unable to locate an actual matching named generator assume a sequence/table of the given name.
    // this really needs access to the `jakarta.persistence.GenerationType` to work completely properly
    // 
    // (the crux of HHH-12122)
    // temporarily, in lieu of having access to GenerationType, assume the EnhancedSequenceGenerator
    // for the purpose of testing the feasibility of the approach
    final GeneratedValue generatedValueAnn = idXProperty.getAnnotation(GeneratedValue.class);
    if (generatedValueAnn == null) {
        // this should really never happen, but its easy to protect against it...
        return new IdentifierGeneratorDefinition("assigned", "assigned");
    }
    final IdGeneratorStrategyInterpreter generationInterpreter = buildingContext.getBuildingOptions().getIdGenerationTypeInterpreter();
    final GenerationType generationType = interpretGenerationType(generatedValueAnn);
    if (generationType == null || generationType == GenerationType.SEQUENCE) {
        // NOTE : `null` will ultimately be interpreted as "hibernate_sequence"
        log.debugf("Building implicit sequence-based IdentifierGeneratorDefinition (%s)", name);
        final IdentifierGeneratorDefinition.Builder builder = new IdentifierGeneratorDefinition.Builder();
        generationInterpreter.interpretSequenceGenerator(new SequenceGenerator() {

            @Override
            public String name() {
                return name;
            }

            @Override
            public String sequenceName() {
                return "";
            }

            @Override
            public String catalog() {
                return "";
            }

            @Override
            public String schema() {
                return "";
            }

            @Override
            public int initialValue() {
                return 1;
            }

            @Override
            public int allocationSize() {
                return 50;
            }

            @Override
            public Class<? extends Annotation> annotationType() {
                return SequenceGenerator.class;
            }
        }, builder);
        return builder.build();
    } else if (generationType == GenerationType.TABLE) {
        // NOTE : `null` will ultimately be interpreted as "hibernate_sequence"
        log.debugf("Building implicit table-based IdentifierGeneratorDefinition (%s)", name);
        final IdentifierGeneratorDefinition.Builder builder = new IdentifierGeneratorDefinition.Builder();
        generationInterpreter.interpretTableGenerator(new TableGenerator() {

            @Override
            public String name() {
                return name;
            }

            @Override
            public String table() {
                return "";
            }

            @Override
            public int initialValue() {
                return 0;
            }

            @Override
            public int allocationSize() {
                return 50;
            }

            @Override
            public String catalog() {
                return "";
            }

            @Override
            public String schema() {
                return "";
            }

            @Override
            public String pkColumnName() {
                return "";
            }

            @Override
            public String valueColumnName() {
                return "";
            }

            @Override
            public String pkColumnValue() {
                return "";
            }

            @Override
            public UniqueConstraint[] uniqueConstraints() {
                return new UniqueConstraint[0];
            }

            @Override
            public Index[] indexes() {
                return new Index[0];
            }

            @Override
            public Class<? extends Annotation> annotationType() {
                return TableGenerator.class;
            }
        }, builder);
        return builder.build();
    }
    // really AUTO and IDENTITY work the same in this respect, aside from the actual strategy name
    final String strategyName;
    if (generationType == GenerationType.IDENTITY) {
        strategyName = "identity";
    } else {
        strategyName = generationInterpreter.determineGeneratorName(generationType, new GeneratorNameDeterminationContext() {

            @Override
            public Class<?> getIdType() {
                return buildingContext.getBootstrapContext().getReflectionManager().toClass(idXProperty.getType());
            }

            @Override
            public String getGeneratedValueGeneratorName() {
                return generatedValueAnn.generator();
            }
        });
    }
    log.debugf("Building implicit generic IdentifierGeneratorDefinition (%s) : %s", name, strategyName);
    return new IdentifierGeneratorDefinition(name, strategyName, Collections.singletonMap(IdentifierGenerator.GENERATOR_NAME, name));
}
Also used : SequenceGenerator(jakarta.persistence.SequenceGenerator) IdGeneratorStrategyInterpreter(org.hibernate.boot.model.IdGeneratorStrategyInterpreter) UniqueConstraint(jakarta.persistence.UniqueConstraint) Index(jakarta.persistence.Index) TableGenerator(jakarta.persistence.TableGenerator) AnnotatedColumn.buildColumnOrFormulaFromAnnotation(org.hibernate.cfg.AnnotatedColumn.buildColumnOrFormulaFromAnnotation) Annotation(java.lang.annotation.Annotation) GenerationType(jakarta.persistence.GenerationType) GeneratedValue(jakarta.persistence.GeneratedValue) GeneratorNameDeterminationContext(org.hibernate.boot.model.IdGeneratorStrategyInterpreter.GeneratorNameDeterminationContext) IdentifierGeneratorDefinition(org.hibernate.boot.model.IdentifierGeneratorDefinition) PersistentClass(org.hibernate.mapping.PersistentClass) XClass(org.hibernate.annotations.common.reflection.XClass)

Aggregations

GeneratedValue (jakarta.persistence.GeneratedValue)3 XClass (org.hibernate.annotations.common.reflection.XClass)3 IdentifierGeneratorDefinition (org.hibernate.boot.model.IdentifierGeneratorDefinition)3 EmbeddedId (jakarta.persistence.EmbeddedId)2 UniqueConstraint (jakarta.persistence.UniqueConstraint)2 Annotation (java.lang.annotation.Annotation)2 HashMap (java.util.HashMap)2 AnnotationException (org.hibernate.AnnotationException)2 XProperty (org.hibernate.annotations.common.reflection.XProperty)2 NullableDiscriminatorColumnSecondPass (org.hibernate.cfg.internal.NullableDiscriminatorColumnSecondPass)2 DiscriminatorType (jakarta.persistence.DiscriminatorType)1 Embeddable (jakarta.persistence.Embeddable)1 FetchType (jakarta.persistence.FetchType)1 GenerationType (jakarta.persistence.GenerationType)1 Id (jakarta.persistence.Id)1 Index (jakarta.persistence.Index)1 InheritanceType (jakarta.persistence.InheritanceType)1 MappedSuperclass (jakarta.persistence.MappedSuperclass)1 MapsId (jakarta.persistence.MapsId)1 SequenceGenerator (jakarta.persistence.SequenceGenerator)1