Search in sources :

Example 41 with Component

use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.

the class AnnotationBinder method mapAsIdClass.

private static boolean mapAsIdClass(Map<XClass, InheritanceState> inheritanceStatePerClass, InheritanceState inheritanceState, PersistentClass persistentClass, EntityBinder entityBinder, PropertyHolder propertyHolder, InheritanceState.ElementsToProcess elementsToProcess, Set<String> idPropertiesIfIdClass, MetadataBuildingContext context) {
    /*
		 * We are looking for @IdClass
		 * In general we map the id class as identifier using the mapping metadata of the main entity's properties
		 * and we create an identifier mapper containing the id properties of the main entity
		 *
		 * In JPA 2, there is a shortcut if the id class is the Pk of the associated class pointed to by the id
		 * it ought to be treated as an embedded and not a real IdClass (at least in the Hibernate's internal way
		 */
    XClass classWithIdClass = inheritanceState.getClassWithIdClass(false);
    if (classWithIdClass != null) {
        IdClass idClass = classWithIdClass.getAnnotation(IdClass.class);
        XClass compositeClass = context.getBuildingOptions().getReflectionManager().toXClass(idClass.value());
        PropertyData inferredData = new PropertyPreloadedData(entityBinder.getPropertyAccessType(), "id", compositeClass);
        PropertyData baseInferredData = new PropertyPreloadedData(entityBinder.getPropertyAccessType(), "id", classWithIdClass);
        AccessType propertyAccessor = entityBinder.getPropertyAccessor(compositeClass);
        //In JPA 2, there is a shortcut if the IdClass is the Pk of the associated class pointed to by the id
        //it ought to be treated as an embedded and not a real IdClass (at least in the Hibernate's internal way
        final boolean isFakeIdClass = isIdClassPkOfTheAssociatedEntity(elementsToProcess, compositeClass, inferredData, baseInferredData, propertyAccessor, inheritanceStatePerClass, context);
        if (isFakeIdClass) {
            return false;
        }
        boolean isComponent = true;
        String generatorType = "assigned";
        String generator = BinderHelper.ANNOTATION_STRING_DEFAULT;
        boolean ignoreIdAnnotations = entityBinder.isIgnoreIdAnnotations();
        entityBinder.setIgnoreIdAnnotations(true);
        propertyHolder.setInIdClass(true);
        bindIdClass(generatorType, generator, inferredData, baseInferredData, null, propertyHolder, isComponent, propertyAccessor, entityBinder, true, false, context, inheritanceStatePerClass);
        propertyHolder.setInIdClass(null);
        inferredData = new PropertyPreloadedData(propertyAccessor, PropertyPath.IDENTIFIER_MAPPER_PROPERTY, compositeClass);
        Component mapper = fillComponent(propertyHolder, inferredData, baseInferredData, propertyAccessor, false, entityBinder, true, true, false, context, inheritanceStatePerClass);
        entityBinder.setIgnoreIdAnnotations(ignoreIdAnnotations);
        persistentClass.setIdentifierMapper(mapper);
        //If id definition is on a mapped superclass, update the mapping
        final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(classWithIdClass, inheritanceStatePerClass, context);
        if (superclass != null) {
            superclass.setDeclaredIdentifierMapper(mapper);
        } else {
            //we are for sure on the entity
            persistentClass.setDeclaredIdentifierMapper(mapper);
        }
        Property property = new Property();
        property.setName(PropertyPath.IDENTIFIER_MAPPER_PROPERTY);
        property.setUpdateable(false);
        property.setInsertable(false);
        property.setValue(mapper);
        property.setPropertyAccessorName("embedded");
        persistentClass.addProperty(property);
        entityBinder.setIgnoreIdAnnotations(true);
        Iterator properties = mapper.getPropertyIterator();
        while (properties.hasNext()) {
            idPropertiesIfIdClass.add(((Property) properties.next()).getName());
        }
        return true;
    } else {
        return false;
    }
}
Also used : XClass(org.hibernate.annotations.common.reflection.XClass) IdClass(javax.persistence.IdClass) Iterator(java.util.Iterator) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty)

Example 42 with Component

use of org.hibernate.mapping.Component 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, 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, buildingContext);
    String subpath = BinderHelper.getPath(propertyHolder, inferredData);
    LOG.tracev("Binding component with path: {0}", subpath);
    PropertyHolder subHolder = PropertyHolderBuilder.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<PropertyData>();
    XClass returnedClassOrElement = inferredData.getClassOrElement();
    List<PropertyData> baseClassElements = null;
    Map<String, PropertyData> orderedBaseClassElements = new HashMap<String, PropertyData>();
    XClass baseReturnedClassOrElement;
    if (baseInferredData != null) {
        baseClassElements = new ArrayList<PropertyData>();
        baseReturnedClassOrElement = baseInferredData.getClassOrElement();
        bindTypeDefs(baseReturnedClassOrElement, buildingContext);
        // might be spread across the subclasses and super classes.
        while (!Object.class.getName().equals(baseReturnedClassOrElement.getName())) {
            PropertyContainer propContainer = new PropertyContainer(baseReturnedClassOrElement, xClassProcessed, propertyAccessor);
            addElementsOfClass(baseClassElements, propContainer, buildingContext);
            for (PropertyData element : baseClassElements) {
                orderedBaseClassElements.put(element.getPropertyName(), element);
            }
            baseReturnedClassOrElement = baseReturnedClassOrElement.getSuperclass();
        }
    }
    //embeddable elements can have type defs
    bindTypeDefs(returnedClassOrElement, buildingContext);
    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 typevariables 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 = entityPropertyData.getProperty().isAnnotationPresent(ManyToOne.class) || entityPropertyData.getProperty().isAnnotationPresent(OneToOne.class);
                    final boolean isOfDifferentType = !entityPropertyData.getClassOrElement().equals(idClassPropertyData.getClassOrElement());
                    if (hasXToOneAnnotation && isOfDifferentType) {
                    //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);
                    }
                } 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<String, IdentifierGeneratorDefinition>(), entityBinder, isIdentifierMapper, isComponentEmbedded, inSecondPass, buildingContext, inheritanceStatePerClass);
        XProperty property = propertyAnnotatedElement.getProperty();
        if (property.isAnnotationPresent(GeneratedValue.class) && property.isAnnotationPresent(Id.class)) {
            //clone classGenerator and override with local values
            Map<String, IdentifierGeneratorDefinition> localGenerators = new HashMap<String, IdentifierGeneratorDefinition>();
            localGenerators.putAll(buildLocalGenerators(property, buildingContext));
            GeneratedValue generatedValue = property.getAnnotation(GeneratedValue.class);
            String generatorType = generatedValue != null ? generatorType(generatedValue.strategy(), buildingContext, property.getType()) : "assigned";
            String generator = generatedValue != null ? generatedValue.generator() : BinderHelper.ANNOTATION_STRING_DEFAULT;
            BinderHelper.makeIdGenerator((SimpleValue) comp.getProperty(property.getName()).getValue(), generatorType, generator, buildingContext, localGenerators);
        }
    }
    return comp;
}
Also used : XProperty(org.hibernate.annotations.common.reflection.XProperty) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) XClass(org.hibernate.annotations.common.reflection.XClass) UniqueConstraint(javax.persistence.UniqueConstraint) Constraint(org.hibernate.mapping.Constraint) ManyToOne(javax.persistence.ManyToOne) GeneratedValue(javax.persistence.GeneratedValue) OneToOne(javax.persistence.OneToOne) MappedSuperclass(javax.persistence.MappedSuperclass) IdentifierGeneratorDefinition(org.hibernate.boot.model.IdentifierGeneratorDefinition) AnnotationException(org.hibernate.AnnotationException) MapsId(javax.persistence.MapsId) NaturalId(org.hibernate.annotations.NaturalId) EmbeddedId(javax.persistence.EmbeddedId) Id(javax.persistence.Id) CollectionId(org.hibernate.annotations.CollectionId) Component(org.hibernate.mapping.Component)

Aggregations

Component (org.hibernate.mapping.Component)42 Property (org.hibernate.mapping.Property)29 PersistentClass (org.hibernate.mapping.PersistentClass)17 Iterator (java.util.Iterator)11 AnnotationException (org.hibernate.AnnotationException)9 SimpleValue (org.hibernate.mapping.SimpleValue)9 XProperty (org.hibernate.annotations.common.reflection.XProperty)8 ManyToOne (org.hibernate.mapping.ManyToOne)8 Value (org.hibernate.mapping.Value)8 HashMap (java.util.HashMap)6 Collection (org.hibernate.mapping.Collection)6 ArrayList (java.util.ArrayList)5 AssertionFailure (org.hibernate.AssertionFailure)5 MappingException (org.hibernate.MappingException)5 Any (org.hibernate.mapping.Any)5 Column (org.hibernate.mapping.Column)5 Join (org.hibernate.mapping.Join)5 XClass (org.hibernate.annotations.common.reflection.XClass)4 SyntheticProperty (org.hibernate.mapping.SyntheticProperty)4 Ejb3Column (org.hibernate.cfg.Ejb3Column)3