Search in sources :

Example 36 with XClass

use of org.hibernate.annotations.common.reflection.XClass in project hibernate-orm by hibernate.

the class AnnotationBinder method buildInheritanceStates.

/**
 * For the mapped entities build some temporary data-structure containing information about the
 * inheritance status of a class.
 *
 * @param orderedClasses Order list of all annotated entities and their mapped superclasses
 *
 * @return A map of {@code InheritanceState}s keyed against their {@code XClass}.
 */
public static Map<XClass, InheritanceState> buildInheritanceStates(List<XClass> orderedClasses, MetadataBuildingContext buildingContext) {
    Map<XClass, InheritanceState> inheritanceStatePerClass = new HashMap<>(orderedClasses.size());
    for (XClass clazz : orderedClasses) {
        InheritanceState superclassState = InheritanceState.getSuperclassInheritanceState(clazz, inheritanceStatePerClass);
        InheritanceState state = new InheritanceState(clazz, inheritanceStatePerClass, buildingContext);
        if (superclassState != null) {
            // the classes are ordered thus preventing an NPE
            // FIXME if an entity has subclasses annotated @MappedSperclass wo sub @Entity this is wrong
            superclassState.setHasSiblings(true);
            InheritanceState superEntityState = InheritanceState.getInheritanceStateOfSuperEntity(clazz, inheritanceStatePerClass);
            state.setHasParents(superEntityState != null);
            final boolean nonDefault = state.getType() != null && !InheritanceType.SINGLE_TABLE.equals(state.getType());
            if (superclassState.getType() != null) {
                final boolean mixingStrategy = state.getType() != null && !state.getType().equals(superclassState.getType());
                if (nonDefault && mixingStrategy) {
                    LOG.invalidSubStrategy(clazz.getName());
                }
                state.setType(superclassState.getType());
            }
        }
        inheritanceStatePerClass.put(clazz, state);
    }
    return inheritanceStatePerClass;
}
Also used : HashMap(java.util.HashMap) XClass(org.hibernate.annotations.common.reflection.XClass)

Example 37 with XClass

use of org.hibernate.annotations.common.reflection.XClass 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.getBootstrapContext().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 38 with XClass

use of org.hibernate.annotations.common.reflection.XClass in project hibernate-orm by hibernate.

the class ClassPropertyHolder method addPropertyToMappedSuperclass.

private void addPropertyToMappedSuperclass(Property prop, XClass declaringClass) {
    final Class type = getContext().getBootstrapContext().getReflectionManager().toClass(declaringClass);
    MappedSuperclass superclass = getContext().getMetadataCollector().getMappedSuperclass(type);
    superclass.addDeclaredProperty(prop);
}
Also used : MappedSuperclass(org.hibernate.mapping.MappedSuperclass) XClass(org.hibernate.annotations.common.reflection.XClass) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 39 with XClass

use of org.hibernate.annotations.common.reflection.XClass in project hibernate-orm by hibernate.

the class CollectionBinder method bind.

public void bind() {
    this.collection = createCollection(propertyHolder.getPersistentClass());
    String role = StringHelper.qualify(propertyHolder.getPath(), propertyName);
    LOG.debugf("Collection role: %s", role);
    collection.setRole(role);
    collection.setMappedByProperty(mappedBy);
    if (property.isAnnotationPresent(MapKeyColumn.class) && mapKeyPropertyName != null) {
        throw new AnnotationException("Cannot mix @javax.persistence.MapKey and @MapKeyColumn or @org.hibernate.annotations.MapKey " + "on the same collection: " + StringHelper.qualify(propertyHolder.getPath(), propertyName));
    }
    // set explicit type information
    if (explicitType != null) {
        final TypeDefinition typeDef = buildingContext.getMetadataCollector().getTypeDefinition(explicitType);
        if (typeDef == null) {
            collection.setTypeName(explicitType);
            collection.setTypeParameters(explicitTypeParameters);
        } else {
            collection.setTypeName(typeDef.getTypeImplementorClass().getName());
            collection.setTypeParameters(typeDef.getParameters());
        }
    }
    // set laziness
    defineFetchingStrategy();
    collection.setBatchSize(batchSize);
    collection.setMutable(!property.isAnnotationPresent(Immutable.class));
    // work on association
    boolean isMappedBy = !BinderHelper.isEmptyAnnotationValue(mappedBy);
    final OptimisticLock lockAnn = property.getAnnotation(OptimisticLock.class);
    final boolean includeInOptimisticLockChecks = (lockAnn != null) ? !lockAnn.excluded() : !isMappedBy;
    collection.setOptimisticLocked(includeInOptimisticLockChecks);
    Persister persisterAnn = property.getAnnotation(Persister.class);
    if (persisterAnn != null) {
        collection.setCollectionPersisterClass(persisterAnn.impl());
    }
    applySortingAndOrdering(collection);
    // set cache
    if (StringHelper.isNotEmpty(cacheConcurrencyStrategy)) {
        collection.setCacheConcurrencyStrategy(cacheConcurrencyStrategy);
        collection.setCacheRegionName(cacheRegionName);
    }
    // SQL overriding
    SQLInsert sqlInsert = property.getAnnotation(SQLInsert.class);
    SQLUpdate sqlUpdate = property.getAnnotation(SQLUpdate.class);
    SQLDelete sqlDelete = property.getAnnotation(SQLDelete.class);
    SQLDeleteAll sqlDeleteAll = property.getAnnotation(SQLDeleteAll.class);
    Loader loader = property.getAnnotation(Loader.class);
    if (sqlInsert != null) {
        collection.setCustomSQLInsert(sqlInsert.sql().trim(), sqlInsert.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlInsert.check().toString().toLowerCase(Locale.ROOT)));
    }
    if (sqlUpdate != null) {
        collection.setCustomSQLUpdate(sqlUpdate.sql(), sqlUpdate.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlUpdate.check().toString().toLowerCase(Locale.ROOT)));
    }
    if (sqlDelete != null) {
        collection.setCustomSQLDelete(sqlDelete.sql(), sqlDelete.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlDelete.check().toString().toLowerCase(Locale.ROOT)));
    }
    if (sqlDeleteAll != null) {
        collection.setCustomSQLDeleteAll(sqlDeleteAll.sql(), sqlDeleteAll.callable(), ExecuteUpdateResultCheckStyle.fromExternalName(sqlDeleteAll.check().toString().toLowerCase(Locale.ROOT)));
    }
    if (loader != null) {
        collection.setLoaderName(loader.namedQuery());
    }
    if (isMappedBy && (property.isAnnotationPresent(JoinColumn.class) || property.isAnnotationPresent(JoinColumns.class) || propertyHolder.getJoinTable(property) != null)) {
        String message = "Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: ";
        message += StringHelper.qualify(propertyHolder.getPath(), propertyName);
        throw new AnnotationException(message);
    }
    if (!isMappedBy && oneToMany && property.isAnnotationPresent(OnDelete.class) && !property.isAnnotationPresent(JoinColumn.class)) {
        String message = "Unidirectional one-to-many associations annotated with @OnDelete must define @JoinColumn: ";
        message += StringHelper.qualify(propertyHolder.getPath(), propertyName);
        throw new AnnotationException(message);
    }
    collection.setInverse(isMappedBy);
    // many to many may need some second pass informations
    if (!oneToMany && isMappedBy) {
        buildingContext.getMetadataCollector().addMappedBy(getCollectionType().getName(), mappedBy, propertyName);
    }
    // TODO reducce tableBinder != null and oneToMany
    XClass collectionType = getCollectionType();
    if (inheritanceStatePerClass == null)
        throw new AssertionFailure("inheritanceStatePerClass not set");
    SecondPass sp = getSecondPass(fkJoinColumns, joinColumns, inverseJoinColumns, elementColumns, mapKeyColumns, mapKeyManyToManyColumns, isEmbedded, property, collectionType, ignoreNotFound, oneToMany, tableBinder, buildingContext);
    if (collectionType.isAnnotationPresent(Embeddable.class) || // JPA 2
    property.isAnnotationPresent(ElementCollection.class)) {
        // do it right away, otherwise @ManyToOne on composite element call addSecondPass
        // and raise a ConcurrentModificationException
        // sp.doSecondPass( CollectionHelper.EMPTY_MAP );
        buildingContext.getMetadataCollector().addSecondPass(sp, !isMappedBy);
    } else {
        buildingContext.getMetadataCollector().addSecondPass(sp, !isMappedBy);
    }
    buildingContext.getMetadataCollector().addCollectionBinding(collection);
    // property building
    PropertyBinder binder = new PropertyBinder();
    binder.setName(propertyName);
    binder.setValue(collection);
    binder.setCascade(cascadeStrategy);
    if (cascadeStrategy != null && cascadeStrategy.contains("delete-orphan")) {
        collection.setOrphanDelete(true);
    }
    binder.setLazy(collection.isLazy());
    final LazyGroup lazyGroupAnnotation = property.getAnnotation(LazyGroup.class);
    if (lazyGroupAnnotation != null) {
        binder.setLazyGroup(lazyGroupAnnotation.value());
    }
    binder.setAccessType(accessType);
    binder.setProperty(property);
    binder.setInsertable(insertable);
    binder.setUpdatable(updatable);
    Property prop = binder.makeProperty();
    // we don't care about the join stuffs because the column is on the association table.
    if (!declaringClassSet)
        throw new AssertionFailure("DeclaringClass is not set in CollectionBinder while binding");
    propertyHolder.addProperty(prop, declaringClass);
}
Also used : AssertionFailure(org.hibernate.annotations.common.AssertionFailure) MapKeyColumn(javax.persistence.MapKeyColumn) Loader(org.hibernate.annotations.Loader) SQLDelete(org.hibernate.annotations.SQLDelete) XClass(org.hibernate.annotations.common.reflection.XClass) TypeDefinition(org.hibernate.boot.model.TypeDefinition) Embeddable(javax.persistence.Embeddable) SecondPass(org.hibernate.cfg.SecondPass) CollectionSecondPass(org.hibernate.cfg.CollectionSecondPass) LazyGroup(org.hibernate.annotations.LazyGroup) AnnotationException(org.hibernate.AnnotationException) SQLInsert(org.hibernate.annotations.SQLInsert) SQLUpdate(org.hibernate.annotations.SQLUpdate) SQLDeleteAll(org.hibernate.annotations.SQLDeleteAll) Persister(org.hibernate.annotations.Persister) ElementCollection(javax.persistence.ElementCollection) OptimisticLock(org.hibernate.annotations.OptimisticLock) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty)

Aggregations

XClass (org.hibernate.annotations.common.reflection.XClass)39 XProperty (org.hibernate.annotations.common.reflection.XProperty)11 AnnotationException (org.hibernate.AnnotationException)10 HashMap (java.util.HashMap)8 MappingException (org.hibernate.MappingException)7 ArrayList (java.util.ArrayList)6 ClassLoadingException (org.hibernate.annotations.common.reflection.ClassLoadingException)6 PersistentClass (org.hibernate.mapping.PersistentClass)5 Property (org.hibernate.mapping.Property)5 Column (javax.persistence.Column)4 ElementCollection (javax.persistence.ElementCollection)4 EmbeddedId (javax.persistence.EmbeddedId)4 JoinColumn (javax.persistence.JoinColumn)4 CollectionId (org.hibernate.annotations.CollectionId)4 Component (org.hibernate.mapping.Component)4 Date (java.util.Date)3 Map (java.util.Map)3 Embeddable (javax.persistence.Embeddable)3 EntityListeners (javax.persistence.EntityListeners)3 JoinTable (javax.persistence.JoinTable)3