Search in sources :

Example 26 with AnnotationException

use of org.hibernate.AnnotationException in project hibernate-orm by hibernate.

the class CollectionBinder method bindManyToManySecondPass.

private void bindManyToManySecondPass(Collection collValue, Map persistentClasses, Ejb3JoinColumn[] joinColumns, Ejb3JoinColumn[] inverseJoinColumns, Ejb3Column[] elementColumns, boolean isEmbedded, XClass collType, boolean ignoreNotFound, boolean unique, boolean cascadeDeleteEnabled, TableBinder associationTableBinder, XProperty property, PropertyHolder parentPropertyHolder, MetadataBuildingContext buildingContext) throws MappingException {
    if (property == null) {
        throw new IllegalArgumentException("null was passed for argument property");
    }
    final PersistentClass collectionEntity = (PersistentClass) persistentClasses.get(collType.getName());
    final String hqlOrderBy = extractHqlOrderBy(jpaOrderBy);
    boolean isCollectionOfEntities = collectionEntity != null;
    ManyToAny anyAnn = property.getAnnotation(ManyToAny.class);
    if (LOG.isDebugEnabled()) {
        String path = collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName();
        if (isCollectionOfEntities && unique) {
            LOG.debugf("Binding a OneToMany: %s through an association table", path);
        } else if (isCollectionOfEntities) {
            LOG.debugf("Binding as ManyToMany: %s", path);
        } else if (anyAnn != null) {
            LOG.debugf("Binding a ManyToAny: %s", path);
        } else {
            LOG.debugf("Binding a collection of element: %s", path);
        }
    }
    // check for user error
    if (!isCollectionOfEntities) {
        if (property.isAnnotationPresent(ManyToMany.class) || property.isAnnotationPresent(OneToMany.class)) {
            String path = collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName();
            throw new AnnotationException("Use of @OneToMany or @ManyToMany targeting an unmapped class: " + path + "[" + collType + "]");
        } else if (anyAnn != null) {
            if (parentPropertyHolder.getJoinTable(property) == null) {
                String path = collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName();
                throw new AnnotationException("@JoinTable is mandatory when @ManyToAny is used: " + path);
            }
        } else {
            JoinTable joinTableAnn = parentPropertyHolder.getJoinTable(property);
            if (joinTableAnn != null && joinTableAnn.inverseJoinColumns().length > 0) {
                String path = collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName();
                throw new AnnotationException("Use of @JoinTable.inverseJoinColumns targeting an unmapped class: " + path + "[" + collType + "]");
            }
        }
    }
    boolean mappedBy = !BinderHelper.isEmptyAnnotationValue(joinColumns[0].getMappedBy());
    if (mappedBy) {
        if (!isCollectionOfEntities) {
            throw new AnnotationException("Collection of elements must not have mappedBy or association reference an unmapped entity: " + collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName());
        }
        Property otherSideProperty;
        try {
            otherSideProperty = collectionEntity.getRecursiveProperty(joinColumns[0].getMappedBy());
        } catch (MappingException e) {
            throw new AnnotationException("mappedBy reference an unknown target entity property: " + collType + "." + joinColumns[0].getMappedBy() + " in " + collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName());
        }
        Table table;
        if (otherSideProperty.getValue() instanceof Collection) {
            // this is a collection on the other side
            table = ((Collection) otherSideProperty.getValue()).getCollectionTable();
        } else {
            // This is a ToOne with a @JoinTable or a regular property
            table = otherSideProperty.getValue().getTable();
        }
        collValue.setCollectionTable(table);
        String entityName = collectionEntity.getEntityName();
        for (Ejb3JoinColumn column : joinColumns) {
            // column.setDefaultColumnHeader( joinColumns[0].getMappedBy() ); //seems not to be used, make sense
            column.setManyToManyOwnerSideEntityName(entityName);
        }
    } else {
        // FIXME NamingStrategy
        for (Ejb3JoinColumn column : joinColumns) {
            String mappedByProperty = buildingContext.getMetadataCollector().getFromMappedBy(collValue.getOwnerEntityName(), column.getPropertyName());
            Table ownerTable = collValue.getOwner().getTable();
            column.setMappedBy(collValue.getOwner().getEntityName(), collValue.getOwner().getJpaEntityName(), buildingContext.getMetadataCollector().getLogicalTableName(ownerTable), mappedByProperty);
        // String header = ( mappedByProperty == null ) ? mappings.getLogicalTableName( ownerTable ) : mappedByProperty;
        // column.setDefaultColumnHeader( header );
        }
        if (StringHelper.isEmpty(associationTableBinder.getName())) {
            // default value
            associationTableBinder.setDefaultName(collValue.getOwner().getClassName(), collValue.getOwner().getEntityName(), collValue.getOwner().getJpaEntityName(), buildingContext.getMetadataCollector().getLogicalTableName(collValue.getOwner().getTable()), collectionEntity != null ? collectionEntity.getClassName() : null, collectionEntity != null ? collectionEntity.getEntityName() : null, collectionEntity != null ? collectionEntity.getJpaEntityName() : null, collectionEntity != null ? buildingContext.getMetadataCollector().getLogicalTableName(collectionEntity.getTable()) : null, joinColumns[0].getPropertyName());
        }
        associationTableBinder.setJPA2ElementCollection(!isCollectionOfEntities && property.isAnnotationPresent(ElementCollection.class));
        collValue.setCollectionTable(associationTableBinder.bind());
    }
    bindFilters(isCollectionOfEntities);
    bindCollectionSecondPass(collValue, collectionEntity, joinColumns, cascadeDeleteEnabled, property, propertyHolder, buildingContext);
    ManyToOne element = null;
    if (isCollectionOfEntities) {
        element = new ManyToOne(buildingContext, collValue.getCollectionTable());
        collValue.setElement(element);
        element.setReferencedEntityName(collType.getName());
        // element.setFetchMode( fetchMode );
        // element.setLazy( fetchMode != FetchMode.JOIN );
        // make the second join non lazy
        element.setFetchMode(FetchMode.JOIN);
        element.setLazy(false);
        element.setIgnoreNotFound(ignoreNotFound);
        // as per 11.1.38 of JPA 2.0 spec, default to primary key if no column is specified by @OrderBy.
        if (hqlOrderBy != null) {
            collValue.setManyToManyOrdering(buildOrderByClauseFromHql(hqlOrderBy, collectionEntity, collValue.getRole()));
        }
        final ForeignKey fk = property.getAnnotation(ForeignKey.class);
        if (fk != null && !BinderHelper.isEmptyAnnotationValue(fk.name())) {
            element.setForeignKeyName(fk.name());
        } else {
            final JoinTable joinTableAnn = property.getAnnotation(JoinTable.class);
            if (joinTableAnn != null) {
                String foreignKeyName = joinTableAnn.inverseForeignKey().name();
                String foreignKeyDefinition = joinTableAnn.inverseForeignKey().foreignKeyDefinition();
                ConstraintMode foreignKeyValue = joinTableAnn.inverseForeignKey().value();
                if (joinTableAnn.inverseJoinColumns().length != 0) {
                    final JoinColumn joinColumnAnn = joinTableAnn.inverseJoinColumns()[0];
                    if ("".equals(foreignKeyName)) {
                        foreignKeyName = joinColumnAnn.foreignKey().name();
                        foreignKeyDefinition = joinColumnAnn.foreignKey().foreignKeyDefinition();
                    }
                    if (foreignKeyValue != ConstraintMode.NO_CONSTRAINT) {
                        foreignKeyValue = joinColumnAnn.foreignKey().value();
                    }
                }
                if (joinTableAnn.inverseForeignKey().value() == ConstraintMode.NO_CONSTRAINT) {
                    element.setForeignKeyName("none");
                } else {
                    element.setForeignKeyName(StringHelper.nullIfEmpty(foreignKeyName));
                    element.setForeignKeyDefinition(StringHelper.nullIfEmpty(foreignKeyDefinition));
                }
            }
        }
    } else if (anyAnn != null) {
        // @ManyToAny
        // Make sure that collTyp is never used during the @ManyToAny branch: it will be set to void.class
        PropertyData inferredData = new PropertyInferredData(null, property, "unsupported", buildingContext.getBootstrapContext().getReflectionManager());
        // override the table
        for (Ejb3Column column : inverseJoinColumns) {
            column.setTable(collValue.getCollectionTable());
        }
        Any any = BinderHelper.buildAnyValue(anyAnn.metaDef(), inverseJoinColumns, anyAnn.metaColumn(), inferredData, cascadeDeleteEnabled, Nullability.NO_CONSTRAINT, propertyHolder, new EntityBinder(), true, buildingContext);
        collValue.setElement(any);
    } else {
        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;
            }
        }
        if (AnnotatedClassType.EMBEDDABLE.equals(classType)) {
            holder.prepare(property);
            EntityBinder entityBinder = new EntityBinder();
            PersistentClass owner = collValue.getOwner();
            boolean isPropertyAnnotated;
            // String accessType = access != null ? access.value() : null;
            if (owner.getIdentifierProperty() != null) {
                isPropertyAnnotated = owner.getIdentifierProperty().getPropertyAccessorName().equals("property");
            } else if (owner.getIdentifierMapper() != null && owner.getIdentifierMapper().getPropertySpan() > 0) {
                Property prop = (Property) owner.getIdentifierMapper().getPropertyIterator().next();
                isPropertyAnnotated = prop.getPropertyAccessorName().equals("property");
            } else {
                throw new AssertionFailure("Unable to guess collection property accessor name");
            }
            PropertyData inferredData;
            if (isMap()) {
                // "value" is the JPA 2 prefix for map values (used to be "element")
                if (isHibernateExtensionMapping()) {
                    inferredData = new PropertyPreloadedData(AccessType.PROPERTY, "element", elementClass);
                } else {
                    inferredData = new PropertyPreloadedData(AccessType.PROPERTY, "value", elementClass);
                }
            } else {
                if (isHibernateExtensionMapping()) {
                    inferredData = new PropertyPreloadedData(AccessType.PROPERTY, "element", elementClass);
                } else {
                    // "collection&&element" is not a valid property name => placeholder
                    inferredData = new PropertyPreloadedData(AccessType.PROPERTY, "collection&&element", elementClass);
                }
            }
            // TODO be smart with isNullable
            boolean isNullable = true;
            Component component = AnnotationBinder.fillComponent(holder, inferredData, isPropertyAnnotated ? AccessType.PROPERTY : AccessType.FIELD, isNullable, entityBinder, false, false, true, buildingContext, inheritanceStatePerClass);
            collValue.setElement(component);
            if (StringHelper.isNotEmpty(hqlOrderBy)) {
                String orderBy = adjustUserSuppliedValueCollectionOrderingFragment(hqlOrderBy);
                if (orderBy != null) {
                    collValue.setOrderBy(orderBy);
                }
            }
        } else {
            holder.prepare(property);
            SimpleValueBinder elementBinder = new SimpleValueBinder();
            elementBinder.setBuildingContext(buildingContext);
            elementBinder.setReturnedClassName(collType.getName());
            if (elementColumns == null || elementColumns.length == 0) {
                elementColumns = new Ejb3Column[1];
                Ejb3Column column = new Ejb3Column();
                column.setImplicit(false);
                // not following the spec but more clean
                column.setNullable(true);
                column.setLength(Ejb3Column.DEFAULT_COLUMN_LENGTH);
                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 (Ejb3Column 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);
            }
        }
    }
    checkFilterConditions(collValue);
    // FIXME: do optional = false
    if (isCollectionOfEntities) {
        bindManytoManyInverseFk(collectionEntity, inverseJoinColumns, element, unique, buildingContext);
    }
}
Also used : PropertyData(org.hibernate.cfg.PropertyData) HashMap(java.util.HashMap) PropertyInferredData(org.hibernate.cfg.PropertyInferredData) PropertyPreloadedData(org.hibernate.cfg.PropertyPreloadedData) Any(org.hibernate.mapping.Any) ManyToAny(org.hibernate.annotations.ManyToAny) XClass(org.hibernate.annotations.common.reflection.XClass) ManyToOne(org.hibernate.mapping.ManyToOne) MappingException(org.hibernate.MappingException) ManyToAny(org.hibernate.annotations.ManyToAny) JoinColumn(javax.persistence.JoinColumn) Ejb3JoinColumn(org.hibernate.cfg.Ejb3JoinColumn) AnnotationException(org.hibernate.AnnotationException) Ejb3Column(org.hibernate.cfg.Ejb3Column) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty) PersistentClass(org.hibernate.mapping.PersistentClass) JoinTable(javax.persistence.JoinTable) CollectionTable(javax.persistence.CollectionTable) WhereJoinTable(org.hibernate.annotations.WhereJoinTable) Table(org.hibernate.mapping.Table) FilterJoinTable(org.hibernate.annotations.FilterJoinTable) CollectionPropertyHolder(org.hibernate.cfg.CollectionPropertyHolder) AssertionFailure(org.hibernate.annotations.common.AssertionFailure) ManyToMany(javax.persistence.ManyToMany) ConstraintMode(javax.persistence.ConstraintMode) OneToMany(javax.persistence.OneToMany) ForeignKey(org.hibernate.annotations.ForeignKey) LazyCollection(org.hibernate.annotations.LazyCollection) Collection(org.hibernate.mapping.Collection) ElementCollection(javax.persistence.ElementCollection) Ejb3JoinColumn(org.hibernate.cfg.Ejb3JoinColumn) AnnotatedClassType(org.hibernate.cfg.AnnotatedClassType) JoinTable(javax.persistence.JoinTable) WhereJoinTable(org.hibernate.annotations.WhereJoinTable) FilterJoinTable(org.hibernate.annotations.FilterJoinTable)

Example 27 with AnnotationException

use of org.hibernate.AnnotationException in project hibernate-orm by hibernate.

the class PropertyBinder method getValueGenerationFromAnnotation.

/**
 * In case the given annotation is a value generator annotation, the corresponding value generation strategy to be
 * applied to the given property is returned, {@code null} otherwise.
 */
private <A extends Annotation> AnnotationValueGeneration<A> getValueGenerationFromAnnotation(XProperty property, A annotation) {
    ValueGenerationType generatorAnnotation = annotation.annotationType().getAnnotation(ValueGenerationType.class);
    if (generatorAnnotation == null) {
        return null;
    }
    Class<? extends AnnotationValueGeneration<?>> generationType = generatorAnnotation.generatedBy();
    AnnotationValueGeneration<A> valueGeneration = instantiateAndInitializeValueGeneration(annotation, generationType, property);
    if (annotation.annotationType() == Generated.class && property.isAnnotationPresent(javax.persistence.Version.class) && valueGeneration.getGenerationTiming() == GenerationTiming.INSERT) {
        throw new AnnotationException("@Generated(INSERT) on a @Version property not allowed, use ALWAYS (or NEVER): " + StringHelper.qualify(holder.getPath(), name));
    }
    return valueGeneration;
}
Also used : ValueGenerationType(org.hibernate.annotations.ValueGenerationType) AnnotationException(org.hibernate.AnnotationException)

Example 28 with AnnotationException

use of org.hibernate.AnnotationException in project hibernate-orm by hibernate.

the class PropertyBinder method makeProperty.

// used when the value is provided and the binding is done elsewhere
public Property makeProperty() {
    validateMake();
    LOG.debugf("Building property %s", name);
    Property prop = new Property();
    prop.setName(name);
    prop.setValue(value);
    prop.setLazy(lazy);
    prop.setLazyGroup(lazyGroup);
    prop.setCascade(cascade);
    prop.setPropertyAccessorName(accessType.getType());
    if (property != null) {
        prop.setValueGenerationStrategy(determineValueGenerationStrategy(property));
        if (property.isAnnotationPresent(AttributeAccessor.class)) {
            final AttributeAccessor accessor = property.getAnnotation(AttributeAccessor.class);
            prop.setPropertyAccessorName(accessor.value());
        }
    }
    NaturalId naturalId = property != null ? property.getAnnotation(NaturalId.class) : null;
    if (naturalId != null) {
        if (!entityBinder.isRootEntity()) {
            throw new AnnotationException("@NaturalId only valid on root entity (or its @MappedSuperclasses)");
        }
        if (!naturalId.mutable()) {
            updatable = false;
        }
        prop.setNaturalIdentifier(true);
    }
    // HHH-4635 -- needed for dialect-specific property ordering
    Lob lob = property != null ? property.getAnnotation(Lob.class) : null;
    prop.setLob(lob != null);
    prop.setInsertable(insertable);
    prop.setUpdateable(updatable);
    // this is already handled for collections in CollectionBinder...
    if (Collection.class.isInstance(value)) {
        prop.setOptimisticLocked(((Collection) value).isOptimisticLocked());
    } else {
        final OptimisticLock lockAnn = property != null ? property.getAnnotation(OptimisticLock.class) : null;
        if (lockAnn != null) {
            // TODO this should go to the core as a mapping validation checking
            if (lockAnn.excluded() && (property.isAnnotationPresent(javax.persistence.Version.class) || property.isAnnotationPresent(Id.class) || property.isAnnotationPresent(EmbeddedId.class))) {
                throw new AnnotationException("@OptimisticLock.exclude=true incompatible with @Id, @EmbeddedId and @Version: " + StringHelper.qualify(holder.getPath(), name));
            }
        }
        // && updatable as well???
        final boolean isOwnedValue = !isToOneValue(value) || insertable;
        final boolean includeInOptimisticLockChecks = (lockAnn != null) ? !lockAnn.excluded() : isOwnedValue;
        prop.setOptimisticLocked(includeInOptimisticLockChecks);
    }
    LOG.tracev("Cascading {0} with {1}", name, cascade);
    this.mappingProperty = prop;
    return prop;
}
Also used : AnnotationException(org.hibernate.AnnotationException) EmbeddedId(javax.persistence.EmbeddedId) AttributeAccessor(org.hibernate.annotations.AttributeAccessor) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty) NaturalId(org.hibernate.annotations.NaturalId) OptimisticLock(org.hibernate.annotations.OptimisticLock) Lob(javax.persistence.Lob)

Example 29 with AnnotationException

use of org.hibernate.AnnotationException in project hibernate-orm by hibernate.

the class TableBinder method bindFk.

public static void bindFk(PersistentClass referencedEntity, PersistentClass destinationEntity, Ejb3JoinColumn[] columns, SimpleValue value, boolean unique, MetadataBuildingContext buildingContext) {
    PersistentClass associatedClass;
    if (destinationEntity != null) {
        // overridden destination
        associatedClass = destinationEntity;
    } else {
        associatedClass = columns[0].getPropertyHolder() == null ? null : columns[0].getPropertyHolder().getPersistentClass();
    }
    final String mappedByProperty = columns[0].getMappedBy();
    if (StringHelper.isNotEmpty(mappedByProperty)) {
        /**
         * Get the columns of the mapped-by property
         * copy them and link the copy to the actual value
         */
        LOG.debugf("Retrieving property %s.%s", associatedClass.getEntityName(), mappedByProperty);
        final Property property = associatedClass.getRecursiveProperty(columns[0].getMappedBy());
        Iterator mappedByColumns;
        if (property.getValue() instanceof Collection) {
            Collection collection = ((Collection) property.getValue());
            Value element = collection.getElement();
            if (element == null) {
                throw new AnnotationException("Illegal use of mappedBy on both sides of the relationship: " + associatedClass.getEntityName() + "." + mappedByProperty);
            }
            mappedByColumns = element.getColumnIterator();
        } else {
            mappedByColumns = property.getValue().getColumnIterator();
        }
        while (mappedByColumns.hasNext()) {
            Column column = (Column) mappedByColumns.next();
            columns[0].overrideFromReferencedColumnIfNecessary(column);
            columns[0].linkValueUsingAColumnCopy(column, value);
        }
    } else if (columns[0].isImplicit()) {
        /**
         * if columns are implicit, then create the columns based on the
         * referenced entity id columns
         */
        Iterator idColumns;
        if (referencedEntity instanceof JoinedSubclass) {
            idColumns = referencedEntity.getKey().getColumnIterator();
        } else {
            idColumns = referencedEntity.getIdentifier().getColumnIterator();
        }
        while (idColumns.hasNext()) {
            Column column = (Column) idColumns.next();
            columns[0].linkValueUsingDefaultColumnNaming(column, referencedEntity, value);
            columns[0].overrideFromReferencedColumnIfNecessary(column);
        }
    } else {
        int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType(columns, referencedEntity, buildingContext);
        if (Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum) {
            String referencedPropertyName;
            if (value instanceof ToOne) {
                referencedPropertyName = ((ToOne) value).getReferencedPropertyName();
            } else if (value instanceof DependantValue) {
                String propertyName = columns[0].getPropertyName();
                if (propertyName != null) {
                    Collection collection = (Collection) referencedEntity.getRecursiveProperty(propertyName).getValue();
                    referencedPropertyName = collection.getReferencedPropertyName();
                } else {
                    throw new AnnotationException("SecondaryTable JoinColumn cannot reference a non primary key");
                }
            } else {
                throw new AssertionFailure("Do a property ref on an unexpected Value type: " + value.getClass().getName());
            }
            if (referencedPropertyName == null) {
                throw new AssertionFailure("No property ref found while expected");
            }
            Property synthProp = referencedEntity.getReferencedProperty(referencedPropertyName);
            if (synthProp == null) {
                throw new AssertionFailure("Cannot find synthProp: " + referencedEntity.getEntityName() + "." + referencedPropertyName);
            }
            linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, synthProp.getColumnIterator(), columns, value);
        } else {
            if (Ejb3JoinColumn.NO_REFERENCE == fkEnum) {
                // implicit case, we hope PK and FK columns are in the same order
                if (columns.length != referencedEntity.getIdentifier().getColumnSpan()) {
                    throw new AnnotationException("A Foreign key refering " + referencedEntity.getEntityName() + " from " + associatedClass.getEntityName() + " has the wrong number of column. should be " + referencedEntity.getIdentifier().getColumnSpan());
                }
                linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, referencedEntity.getIdentifier().getColumnIterator(), columns, value);
            } else {
                // explicit referencedColumnName
                Iterator idColItr = referencedEntity.getKey().getColumnIterator();
                org.hibernate.mapping.Column col;
                // works cause the pk has to be on the primary table
                Table table = referencedEntity.getTable();
                if (!idColItr.hasNext()) {
                    LOG.debug("No column in the identifier!");
                }
                while (idColItr.hasNext()) {
                    boolean match = false;
                    // for each PK column, find the associated FK column.
                    col = (org.hibernate.mapping.Column) idColItr.next();
                    for (Ejb3JoinColumn joinCol : columns) {
                        String referencedColumn = joinCol.getReferencedColumn();
                        referencedColumn = buildingContext.getMetadataCollector().getPhysicalColumnName(table, referencedColumn);
                        // In JPA 2 referencedColumnName is case insensitive
                        if (referencedColumn.equalsIgnoreCase(col.getQuotedName(buildingContext.getMetadataCollector().getDatabase().getJdbcEnvironment().getDialect()))) {
                            // proper join column
                            if (joinCol.isNameDeferred()) {
                                joinCol.linkValueUsingDefaultColumnNaming(col, referencedEntity, value);
                            } else {
                                joinCol.linkWithValue(value);
                            }
                            joinCol.overrideFromReferencedColumnIfNecessary(col);
                            match = true;
                            break;
                        }
                    }
                    if (!match) {
                        throw new AnnotationException("Column name " + col.getName() + " of " + referencedEntity.getEntityName() + " not found in JoinColumns.referencedColumnName");
                    }
                }
            }
        }
    }
    value.createForeignKey();
    if (unique) {
        createUniqueConstraint(value);
    }
}
Also used : AssertionFailure(org.hibernate.AssertionFailure) Table(org.hibernate.mapping.Table) DependantValue(org.hibernate.mapping.DependantValue) Column(org.hibernate.mapping.Column) Ejb3JoinColumn(org.hibernate.cfg.Ejb3JoinColumn) Iterator(java.util.Iterator) SimpleValue(org.hibernate.mapping.SimpleValue) DependantValue(org.hibernate.mapping.DependantValue) Value(org.hibernate.mapping.Value) ToOne(org.hibernate.mapping.ToOne) Collection(org.hibernate.mapping.Collection) AnnotationException(org.hibernate.AnnotationException) Ejb3JoinColumn(org.hibernate.cfg.Ejb3JoinColumn) JoinedSubclass(org.hibernate.mapping.JoinedSubclass) Property(org.hibernate.mapping.Property) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 30 with AnnotationException

use of org.hibernate.AnnotationException in project hibernate-orm by hibernate.

the class CopyIdentifierComponentSecondPass method doSecondPass.

@SuppressWarnings({ "unchecked" })
public void doSecondPass(Map persistentClasses) throws MappingException {
    PersistentClass referencedPersistentClass = (PersistentClass) persistentClasses.get(referencedEntityName);
    // TODO better error names
    if (referencedPersistentClass == null) {
        throw new AnnotationException("Unknown entity name: " + referencedEntityName);
    }
    if (!(referencedPersistentClass.getIdentifier() instanceof Component)) {
        throw new AssertionFailure("Unexpected identifier type on the referenced entity when mapping a @MapsId: " + referencedEntityName);
    }
    Component referencedComponent = (Component) referencedPersistentClass.getIdentifier();
    Iterator<Property> properties = referencedComponent.getPropertyIterator();
    // prepare column name structure
    boolean isExplicitReference = true;
    Map<String, Ejb3JoinColumn> columnByReferencedName = new HashMap<>(joinColumns.length);
    for (Ejb3JoinColumn joinColumn : joinColumns) {
        final String referencedColumnName = joinColumn.getReferencedColumn();
        if (referencedColumnName == null || BinderHelper.isEmptyAnnotationValue(referencedColumnName)) {
            break;
        }
        // JPA 2 requires referencedColumnNames to be case insensitive
        columnByReferencedName.put(referencedColumnName.toLowerCase(Locale.ROOT), joinColumn);
    }
    // try default column orientation
    AtomicInteger index = new AtomicInteger(0);
    if (columnByReferencedName.isEmpty()) {
        isExplicitReference = false;
        for (Ejb3JoinColumn joinColumn : joinColumns) {
            columnByReferencedName.put("" + index.get(), joinColumn);
            index.getAndIncrement();
        }
        index.set(0);
    }
    while (properties.hasNext()) {
        Property referencedProperty = properties.next();
        if (referencedProperty.isComposite()) {
            Property property = createComponentProperty(referencedPersistentClass, isExplicitReference, columnByReferencedName, index, referencedProperty);
            component.addProperty(property);
        } else {
            Property property = createSimpleProperty(referencedPersistentClass, isExplicitReference, columnByReferencedName, index, referencedProperty);
            component.addProperty(property);
        }
    }
}
Also used : AssertionFailure(org.hibernate.AssertionFailure) HashMap(java.util.HashMap) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AnnotationException(org.hibernate.AnnotationException) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) PersistentClass(org.hibernate.mapping.PersistentClass)

Aggregations

AnnotationException (org.hibernate.AnnotationException)85 AnnotationDescriptor (org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor)15 PersistentClass (org.hibernate.mapping.PersistentClass)14 AnnotatedElement (java.lang.reflect.AnnotatedElement)12 Element (org.dom4j.Element)12 XClass (org.hibernate.annotations.common.reflection.XClass)12 HashMap (java.util.HashMap)11 MappingException (org.hibernate.MappingException)11 XProperty (org.hibernate.annotations.common.reflection.XProperty)11 Property (org.hibernate.mapping.Property)11 SimpleValue (org.hibernate.mapping.SimpleValue)11 Test (org.junit.Test)10 AssertionFailure (org.hibernate.AssertionFailure)9 ArrayList (java.util.ArrayList)8 ClassLoadingException (org.hibernate.boot.registry.classloading.spi.ClassLoadingException)8 Column (org.hibernate.mapping.Column)8 IdClass (javax.persistence.IdClass)7 MapKeyClass (javax.persistence.MapKeyClass)7 Component (org.hibernate.mapping.Component)7 Properties (java.util.Properties)6