Search in sources :

Example 1 with Join

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

the class AuditMetadataGenerator method createJoins.

@SuppressWarnings({ "unchecked" })
private void createJoins(PersistentClass pc, Element parent, ClassAuditingData auditingData) {
    final Iterator<Join> joins = pc.getJoinIterator();
    final Map<Join, Element> joinElements = new HashMap<>();
    entitiesJoins.put(pc.getEntityName(), joinElements);
    while (joins.hasNext()) {
        Join join = joins.next();
        // Checking if all of the join properties are audited
        if (!checkPropertiesAudited(join.getPropertyIterator(), auditingData)) {
            continue;
        }
        // Determining the table name. If there is no entry in the dictionary, just constructing the table name
        // as if it was an entity (by appending/prepending configured strings).
        final String originalTableName = join.getTable().getName();
        String auditTableName = auditingData.getSecondaryTableDictionary().get(originalTableName);
        if (auditTableName == null) {
            auditTableName = verEntCfg.getAuditEntityName(originalTableName);
        }
        final String schema = getSchema(auditingData.getAuditTable().schema(), join.getTable());
        final String catalog = getCatalog(auditingData.getAuditTable().catalog(), join.getTable());
        final Element joinElement = MetadataTools.createJoin(parent, auditTableName, schema, catalog);
        joinElements.put(join, joinElement);
        // HHH-8305 - Fix case when join is considered optional.
        if (join.isOptional()) {
            joinElement.addAttribute("optional", "true");
        }
        // HHH-8305 - Fix case when join is the inverse side of a mapping.
        if (join.isInverse()) {
            joinElement.addAttribute("inverse", "true");
        }
        final Element joinKey = joinElement.addElement("key");
        MetadataTools.addColumns(joinKey, join.getKey().getColumnIterator());
        MetadataTools.addColumn(joinKey, verEntCfg.getRevisionFieldName(), null, null, null, null, null, null);
    }
}
Also used : HashMap(java.util.HashMap) Element(org.dom4j.Element) Join(org.hibernate.mapping.Join)

Example 2 with Join

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

the class ModelBinder method bindAllEntityAttributes.

private void bindAllEntityAttributes(MappingDocument mappingDocument, EntitySource entitySource, PersistentClass entityDescriptor) {
    final EntityTableXref entityTableXref = mappingDocument.getMetadataCollector().getEntityTableXref(entityDescriptor.getEntityName());
    if (entityTableXref == null) {
        throw new AssertionFailure(String.format(Locale.ENGLISH, "Unable to locate EntityTableXref for entity [%s] : %s", entityDescriptor.getEntityName(), mappingDocument.getOrigin()));
    }
    // make sure we bind secondary tables first!
    for (SecondaryTableSource secondaryTableSource : entitySource.getSecondaryTableMap().values()) {
        final Join secondaryTableJoin = new Join();
        secondaryTableJoin.setPersistentClass(entityDescriptor);
        bindSecondaryTable(mappingDocument, secondaryTableSource, secondaryTableJoin, entityTableXref);
        entityDescriptor.addJoin(secondaryTableJoin);
    }
    for (AttributeSource attributeSource : entitySource.attributeSources()) {
        if (PluralAttributeSource.class.isInstance(attributeSource)) {
            // plural attribute
            final Property attribute = createPluralAttribute(mappingDocument, (PluralAttributeSource) attributeSource, entityDescriptor);
            entityDescriptor.addProperty(attribute);
        } else {
            // singular attribute
            if (SingularAttributeSourceBasic.class.isInstance(attributeSource)) {
                final SingularAttributeSourceBasic basicAttributeSource = (SingularAttributeSourceBasic) attributeSource;
                final Identifier tableName = determineTable(mappingDocument, basicAttributeSource.getName(), basicAttributeSource);
                final AttributeContainer attributeContainer;
                final Table table;
                final Join secondaryTableJoin = entityTableXref.locateJoin(tableName);
                if (secondaryTableJoin == null) {
                    table = entityDescriptor.getTable();
                    attributeContainer = entityDescriptor;
                } else {
                    table = secondaryTableJoin.getTable();
                    attributeContainer = secondaryTableJoin;
                }
                final Property attribute = createBasicAttribute(mappingDocument, basicAttributeSource, new SimpleValue(mappingDocument.getMetadataCollector(), table), entityDescriptor.getClassName());
                if (secondaryTableJoin != null) {
                    attribute.setOptional(secondaryTableJoin.isOptional());
                }
                attributeContainer.addProperty(attribute);
                handleNaturalIdBinding(mappingDocument, entityDescriptor, attribute, basicAttributeSource.getNaturalIdMutability());
            } else if (SingularAttributeSourceEmbedded.class.isInstance(attributeSource)) {
                final SingularAttributeSourceEmbedded embeddedAttributeSource = (SingularAttributeSourceEmbedded) attributeSource;
                final Identifier tableName = determineTable(mappingDocument, embeddedAttributeSource);
                final AttributeContainer attributeContainer;
                final Table table;
                final Join secondaryTableJoin = entityTableXref.locateJoin(tableName);
                if (secondaryTableJoin == null) {
                    table = entityDescriptor.getTable();
                    attributeContainer = entityDescriptor;
                } else {
                    table = secondaryTableJoin.getTable();
                    attributeContainer = secondaryTableJoin;
                }
                final Property attribute = createEmbeddedAttribute(mappingDocument, (SingularAttributeSourceEmbedded) attributeSource, new Component(mappingDocument.getMetadataCollector(), table, entityDescriptor), entityDescriptor.getClassName());
                if (secondaryTableJoin != null) {
                    attribute.setOptional(secondaryTableJoin.isOptional());
                }
                attributeContainer.addProperty(attribute);
                handleNaturalIdBinding(mappingDocument, entityDescriptor, attribute, embeddedAttributeSource.getNaturalIdMutability());
            } else if (SingularAttributeSourceManyToOne.class.isInstance(attributeSource)) {
                final SingularAttributeSourceManyToOne manyToOneAttributeSource = (SingularAttributeSourceManyToOne) attributeSource;
                final Identifier tableName = determineTable(mappingDocument, manyToOneAttributeSource.getName(), manyToOneAttributeSource);
                final AttributeContainer attributeContainer;
                final Table table;
                final Join secondaryTableJoin = entityTableXref.locateJoin(tableName);
                if (secondaryTableJoin == null) {
                    table = entityDescriptor.getTable();
                    attributeContainer = entityDescriptor;
                } else {
                    table = secondaryTableJoin.getTable();
                    attributeContainer = secondaryTableJoin;
                }
                final Property attribute = createManyToOneAttribute(mappingDocument, manyToOneAttributeSource, new ManyToOne(mappingDocument.getMetadataCollector(), table), entityDescriptor.getClassName());
                if (secondaryTableJoin != null) {
                    attribute.setOptional(secondaryTableJoin.isOptional());
                }
                attributeContainer.addProperty(attribute);
                handleNaturalIdBinding(mappingDocument, entityDescriptor, attribute, manyToOneAttributeSource.getNaturalIdMutability());
            } else if (SingularAttributeSourceOneToOne.class.isInstance(attributeSource)) {
                final SingularAttributeSourceOneToOne oneToOneAttributeSource = (SingularAttributeSourceOneToOne) attributeSource;
                final Table table = entityDescriptor.getTable();
                final Property attribute = createOneToOneAttribute(mappingDocument, oneToOneAttributeSource, new OneToOne(mappingDocument.getMetadataCollector(), table, entityDescriptor), entityDescriptor.getClassName());
                entityDescriptor.addProperty(attribute);
                handleNaturalIdBinding(mappingDocument, entityDescriptor, attribute, oneToOneAttributeSource.getNaturalIdMutability());
            } else if (SingularAttributeSourceAny.class.isInstance(attributeSource)) {
                final SingularAttributeSourceAny anyAttributeSource = (SingularAttributeSourceAny) attributeSource;
                final Identifier tableName = determineTable(mappingDocument, anyAttributeSource.getName(), anyAttributeSource.getKeySource().getRelationalValueSources());
                final AttributeContainer attributeContainer;
                final Table table;
                final Join secondaryTableJoin = entityTableXref.locateJoin(tableName);
                if (secondaryTableJoin == null) {
                    table = entityDescriptor.getTable();
                    attributeContainer = entityDescriptor;
                } else {
                    table = secondaryTableJoin.getTable();
                    attributeContainer = secondaryTableJoin;
                }
                final Property attribute = createAnyAssociationAttribute(mappingDocument, anyAttributeSource, new Any(mappingDocument.getMetadataCollector(), table), entityDescriptor.getEntityName());
                if (secondaryTableJoin != null) {
                    attribute.setOptional(secondaryTableJoin.isOptional());
                }
                attributeContainer.addProperty(attribute);
                handleNaturalIdBinding(mappingDocument, entityDescriptor, attribute, anyAttributeSource.getNaturalIdMutability());
            }
        }
    }
}
Also used : SingularAttributeSourceBasic(org.hibernate.boot.model.source.spi.SingularAttributeSourceBasic) AssertionFailure(org.hibernate.AssertionFailure) VersionAttributeSource(org.hibernate.boot.model.source.spi.VersionAttributeSource) AttributeSource(org.hibernate.boot.model.source.spi.AttributeSource) PluralAttributeSource(org.hibernate.boot.model.source.spi.PluralAttributeSource) SingularAttributeSource(org.hibernate.boot.model.source.spi.SingularAttributeSource) Table(org.hibernate.mapping.Table) DenormalizedTable(org.hibernate.mapping.DenormalizedTable) SingularAttributeSourceAny(org.hibernate.boot.model.source.spi.SingularAttributeSourceAny) Join(org.hibernate.mapping.Join) SingularAttributeSourceManyToOne(org.hibernate.boot.model.source.spi.SingularAttributeSourceManyToOne) AttributeContainer(org.hibernate.mapping.AttributeContainer) SecondaryTableSource(org.hibernate.boot.model.source.spi.SecondaryTableSource) SingularAttributeSourceOneToOne(org.hibernate.boot.model.source.spi.SingularAttributeSourceOneToOne) PluralAttributeElementSourceManyToAny(org.hibernate.boot.model.source.spi.PluralAttributeElementSourceManyToAny) Any(org.hibernate.mapping.Any) SingularAttributeSourceAny(org.hibernate.boot.model.source.spi.SingularAttributeSourceAny) SingularAttributeSourceEmbedded(org.hibernate.boot.model.source.spi.SingularAttributeSourceEmbedded) SingularAttributeSourceManyToOne(org.hibernate.boot.model.source.spi.SingularAttributeSourceManyToOne) ManyToOne(org.hibernate.mapping.ManyToOne) SimpleValue(org.hibernate.mapping.SimpleValue) OneToOne(org.hibernate.mapping.OneToOne) SingularAttributeSourceOneToOne(org.hibernate.boot.model.source.spi.SingularAttributeSourceOneToOne) Identifier(org.hibernate.boot.model.naming.Identifier) EntityTableXref(org.hibernate.boot.spi.InFlightMetadataCollector.EntityTableXref) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) SyntheticProperty(org.hibernate.mapping.SyntheticProperty)

Example 3 with Join

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

the class BinderHelper method findPropertiesByColumns.

private static List<Property> findPropertiesByColumns(Object columnOwner, Ejb3JoinColumn[] columns, MetadataBuildingContext context) {
    Map<Column, Set<Property>> columnsToProperty = new HashMap<Column, Set<Property>>();
    List<Column> orderedColumns = new ArrayList<Column>(columns.length);
    Table referencedTable = null;
    if (columnOwner instanceof PersistentClass) {
        referencedTable = ((PersistentClass) columnOwner).getTable();
    } else if (columnOwner instanceof Join) {
        referencedTable = ((Join) columnOwner).getTable();
    } else {
        throw new AssertionFailure(columnOwner == null ? "columnOwner is null" : "columnOwner neither PersistentClass nor Join: " + columnOwner.getClass());
    }
    //build the list of column names
    for (Ejb3JoinColumn column1 : columns) {
        Column column = new Column(context.getMetadataCollector().getPhysicalColumnName(referencedTable, column1.getReferencedColumn()));
        orderedColumns.add(column);
        columnsToProperty.put(column, new HashSet<Property>());
    }
    boolean isPersistentClass = columnOwner instanceof PersistentClass;
    Iterator it = isPersistentClass ? ((PersistentClass) columnOwner).getPropertyIterator() : ((Join) columnOwner).getPropertyIterator();
    while (it.hasNext()) {
        matchColumnsByProperty((Property) it.next(), columnsToProperty);
    }
    if (isPersistentClass) {
        matchColumnsByProperty(((PersistentClass) columnOwner).getIdentifierProperty(), columnsToProperty);
    }
    //first naive implementation
    //only check 1 columns properties
    //TODO make it smarter by checking correctly ordered multi column properties
    List<Property> orderedProperties = new ArrayList<Property>();
    for (Column column : orderedColumns) {
        boolean found = false;
        for (Property property : columnsToProperty.get(column)) {
            if (property.getColumnSpan() == 1) {
                orderedProperties.add(property);
                found = true;
                break;
            }
        }
        if (!found) {
            //have to find it the hard way
            return null;
        }
    }
    return orderedProperties;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) Table(org.hibernate.mapping.Table) AssertionFailure(org.hibernate.AssertionFailure) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Join(org.hibernate.mapping.Join) Column(org.hibernate.mapping.Column) Iterator(java.util.Iterator) Property(org.hibernate.mapping.Property) SyntheticProperty(org.hibernate.mapping.SyntheticProperty) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 4 with Join

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

the class BinderHelper method createSyntheticPropertyReference.

// This is sooooooooo close in terms of not generating a synthetic property if we do not have to (where property ref
// refers to a single property).  The sticking point is cases where the `referencedPropertyName` come from subclasses
// or secondary tables.  Part of the problem is in PersistentClass itself during attempts to resolve the referenced
// property; currently it only considers non-subclass and non-joined properties.  Part of the problem is in terms
// of SQL generation.
//	public static void createSyntheticPropertyReference(
//			Ejb3JoinColumn[] columns,
//			PersistentClass ownerEntity,
//			PersistentClass associatedEntity,
//			Value value,
//			boolean inverse,
//			Mappings mappings) {
//		//associated entity only used for more precise exception, yuk!
//		if ( columns[0].isImplicit() || StringHelper.isNotEmpty( columns[0].getMappedBy() ) ) return;
//		int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType( columns, ownerEntity, mappings );
//		PersistentClass associatedClass = columns[0].getPropertyHolder() != null ?
//				columns[0].getPropertyHolder().getPersistentClass() :
//				null;
//		if ( Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum ) {
//			//find properties associated to a certain column
//			Object columnOwner = findColumnOwner( ownerEntity, columns[0].getReferencedColumn(), mappings );
//			List<Property> properties = findPropertiesByColumns( columnOwner, columns, mappings );
//
//			if ( properties == null ) {
//				//TODO use a ToOne type doing a second select
//				StringBuilder columnsList = new StringBuilder();
//				columnsList.append( "referencedColumnNames(" );
//				for (Ejb3JoinColumn column : columns) {
//					columnsList.append( column.getReferencedColumn() ).append( ", " );
//				}
//				columnsList.setLength( columnsList.length() - 2 );
//				columnsList.append( ") " );
//
//				if ( associatedEntity != null ) {
//					//overidden destination
//					columnsList.append( "of " )
//							.append( associatedEntity.getEntityName() )
//							.append( "." )
//							.append( columns[0].getPropertyName() )
//							.append( " " );
//				}
//				else {
//					if ( columns[0].getPropertyHolder() != null ) {
//						columnsList.append( "of " )
//								.append( columns[0].getPropertyHolder().getEntityName() )
//								.append( "." )
//								.append( columns[0].getPropertyName() )
//								.append( " " );
//					}
//				}
//				columnsList.append( "referencing " )
//						.append( ownerEntity.getEntityName() )
//						.append( " not mapped to a single property" );
//				throw new AnnotationException( columnsList.toString() );
//			}
//
//			final String referencedPropertyName;
//
//			if ( properties.size() == 1 ) {
//				referencedPropertyName = properties.get(0).getName();
//			}
//			else {
//				// Create a synthetic (embedded composite) property to use as the referenced property which
//				// contains all the properties mapped to the referenced columns.  We need to make a shallow copy
//				// of the properties to mark them as non-insertable/updatable.
//
//				// todo : what if the columns all match with an existing component?
//
//				StringBuilder propertyNameBuffer = new StringBuilder( "_" );
//				propertyNameBuffer.append( associatedClass.getEntityName().replace( '.', '_' ) );
//				propertyNameBuffer.append( "_" ).append( columns[0].getPropertyName() );
//				String syntheticPropertyName = propertyNameBuffer.toString();
//				//create an embeddable component
//
//				//todo how about properties.size() == 1, this should be much simpler
//				Component embeddedComp = columnOwner instanceof PersistentClass ?
//						new Component( mappings, (PersistentClass) columnOwner ) :
//						new Component( mappings, (Join) columnOwner );
//				embeddedComp.setEmbedded( true );
//				embeddedComp.setNodeName( syntheticPropertyName );
//				embeddedComp.setComponentClassName( embeddedComp.getOwner().getClassName() );
//				for (Property property : properties) {
//					Property clone = BinderHelper.shallowCopy( property );
//					clone.setInsertable( false );
//					clone.setUpdateable( false );
//					clone.setNaturalIdentifier( false );
//					clone.setGeneration( property.getGeneration() );
//					embeddedComp.addProperty( clone );
//				}
//				SyntheticProperty synthProp = new SyntheticProperty();
//				synthProp.setName( syntheticPropertyName );
//				synthProp.setNodeName( syntheticPropertyName );
//				synthProp.setPersistentClass( ownerEntity );
//				synthProp.setUpdateable( false );
//				synthProp.setInsertable( false );
//				synthProp.setValue( embeddedComp );
//				synthProp.setPropertyAccessorName( "embedded" );
//				ownerEntity.addProperty( synthProp );
//				//make it unique
//				TableBinder.createUniqueConstraint( embeddedComp );
//
//				referencedPropertyName = syntheticPropertyName;
//			}
//
//			/**
//			 * creating the property ref to the new synthetic property
//			 */
//			if ( value instanceof ToOne ) {
//				( (ToOne) value ).setReferencedPropertyName( referencedPropertyName );
//				mappings.addUniquePropertyReference( ownerEntity.getEntityName(), referencedPropertyName );
//			}
//			else if ( value instanceof Collection ) {
//				( (Collection) value ).setReferencedPropertyName( referencedPropertyName );
//				//not unique because we could create a mtm wo association table
//				mappings.addPropertyReference( ownerEntity.getEntityName(), referencedPropertyName );
//			}
//			else {
//				throw new AssertionFailure(
//						"Do a property ref on an unexpected Value type: "
//								+ value.getClass().getName()
//				);
//			}
//			mappings.addPropertyReferencedAssociation(
//					( inverse ? "inverse__" : "" ) + associatedClass.getEntityName(),
//					columns[0].getPropertyName(),
//					referencedPropertyName
//			);
//		}
//	}
public static void createSyntheticPropertyReference(Ejb3JoinColumn[] columns, PersistentClass ownerEntity, PersistentClass associatedEntity, Value value, boolean inverse, MetadataBuildingContext context) {
    //associated entity only used for more precise exception, yuk!
    if (columns[0].isImplicit() || StringHelper.isNotEmpty(columns[0].getMappedBy())) {
        return;
    }
    int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType(columns, ownerEntity, context);
    PersistentClass associatedClass = columns[0].getPropertyHolder() != null ? columns[0].getPropertyHolder().getPersistentClass() : null;
    if (Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum) {
        /**
			 * Create a synthetic property to refer to including an
			 * embedded component value containing all the properties
			 * mapped to the referenced columns
			 * We need to shallow copy those properties to mark them
			 * as non insertable / non updatable
			 */
        StringBuilder propertyNameBuffer = new StringBuilder("_");
        propertyNameBuffer.append(associatedClass.getEntityName().replace('.', '_'));
        propertyNameBuffer.append("_").append(columns[0].getPropertyName().replace('.', '_'));
        String syntheticPropertyName = propertyNameBuffer.toString();
        //find properties associated to a certain column
        Object columnOwner = findColumnOwner(ownerEntity, columns[0].getReferencedColumn(), context);
        List<Property> properties = findPropertiesByColumns(columnOwner, columns, context);
        //create an embeddable component
        Property synthProp = null;
        if (properties != null) {
            //todo how about properties.size() == 1, this should be much simpler
            Component embeddedComp = columnOwner instanceof PersistentClass ? new Component(context.getMetadataCollector(), (PersistentClass) columnOwner) : new Component(context.getMetadataCollector(), (Join) columnOwner);
            embeddedComp.setEmbedded(true);
            embeddedComp.setComponentClassName(embeddedComp.getOwner().getClassName());
            for (Property property : properties) {
                Property clone = BinderHelper.shallowCopy(property);
                clone.setInsertable(false);
                clone.setUpdateable(false);
                clone.setNaturalIdentifier(false);
                clone.setValueGenerationStrategy(property.getValueGenerationStrategy());
                embeddedComp.addProperty(clone);
            }
            synthProp = new SyntheticProperty();
            synthProp.setName(syntheticPropertyName);
            synthProp.setPersistentClass(ownerEntity);
            synthProp.setUpdateable(false);
            synthProp.setInsertable(false);
            synthProp.setValue(embeddedComp);
            synthProp.setPropertyAccessorName("embedded");
            ownerEntity.addProperty(synthProp);
            //make it unique
            TableBinder.createUniqueConstraint(embeddedComp);
        } else {
            //TODO use a ToOne type doing a second select
            StringBuilder columnsList = new StringBuilder();
            columnsList.append("referencedColumnNames(");
            for (Ejb3JoinColumn column : columns) {
                columnsList.append(column.getReferencedColumn()).append(", ");
            }
            columnsList.setLength(columnsList.length() - 2);
            columnsList.append(") ");
            if (associatedEntity != null) {
                //overidden destination
                columnsList.append("of ").append(associatedEntity.getEntityName()).append(".").append(columns[0].getPropertyName()).append(" ");
            } else {
                if (columns[0].getPropertyHolder() != null) {
                    columnsList.append("of ").append(columns[0].getPropertyHolder().getEntityName()).append(".").append(columns[0].getPropertyName()).append(" ");
                }
            }
            columnsList.append("referencing ").append(ownerEntity.getEntityName()).append(" not mapped to a single property");
            throw new AnnotationException(columnsList.toString());
        }
        /**
			 * creating the property ref to the new synthetic property
			 */
        if (value instanceof ToOne) {
            ((ToOne) value).setReferencedPropertyName(syntheticPropertyName);
            ((ToOne) value).setReferenceToPrimaryKey(syntheticPropertyName == null);
            context.getMetadataCollector().addUniquePropertyReference(ownerEntity.getEntityName(), syntheticPropertyName);
        } else if (value instanceof Collection) {
            ((Collection) value).setReferencedPropertyName(syntheticPropertyName);
            //not unique because we could create a mtm wo association table
            context.getMetadataCollector().addPropertyReference(ownerEntity.getEntityName(), syntheticPropertyName);
        } else {
            throw new AssertionFailure("Do a property ref on an unexpected Value type: " + value.getClass().getName());
        }
        context.getMetadataCollector().addPropertyReferencedAssociation((inverse ? "inverse__" : "") + associatedClass.getEntityName(), columns[0].getPropertyName(), syntheticPropertyName);
    }
}
Also used : AssertionFailure(org.hibernate.AssertionFailure) SyntheticProperty(org.hibernate.mapping.SyntheticProperty) Join(org.hibernate.mapping.Join) ToOne(org.hibernate.mapping.ToOne) AnnotationException(org.hibernate.AnnotationException) Collection(org.hibernate.mapping.Collection) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) SyntheticProperty(org.hibernate.mapping.SyntheticProperty) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 5 with Join

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

the class AnnotationBinder method processElementAnnotations.

/*
	 * Process annotation of a particular property
	 */
private static void processElementAnnotations(PropertyHolder propertyHolder, Nullability nullability, PropertyData inferredData, HashMap<String, IdentifierGeneratorDefinition> classGenerators, EntityBinder entityBinder, boolean isIdentifierMapper, boolean isComponentEmbedded, boolean inSecondPass, MetadataBuildingContext context, Map<XClass, InheritanceState> inheritanceStatePerClass) throws MappingException {
    if (!propertyHolder.isComponent()) {
        if (entityBinder.isPropertyDefinedInSuperHierarchy(inferredData.getPropertyName())) {
            LOG.debugf("Skipping attribute [%s : %s] as it was already processed as part of super hierarchy", inferredData.getClassOrElementName(), inferredData.getPropertyName());
            return;
        }
    }
    /**
		 * 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
		 */
    final boolean traceEnabled = LOG.isTraceEnabled();
    if (traceEnabled) {
        LOG.tracev("Processing annotations of {0}.{1}", propertyHolder.getEntityName(), inferredData.getPropertyName());
    }
    final XProperty property = inferredData.getProperty();
    if (property.isAnnotationPresent(Parent.class)) {
        if (propertyHolder.isComponent()) {
            propertyHolder.setParentProperty(property.getName());
        } else {
            throw new AnnotationException("@Parent cannot be applied outside an embeddable object: " + BinderHelper.getPath(propertyHolder, inferredData));
        }
        return;
    }
    ColumnsBuilder columnsBuilder = new ColumnsBuilder(propertyHolder, nullability, property, inferredData, entityBinder, context).extractMetadata();
    Ejb3Column[] columns = columnsBuilder.getColumns();
    Ejb3JoinColumn[] joinColumns = columnsBuilder.getJoinColumns();
    final XClass returnedClass = inferredData.getClassOrElement();
    //prepare PropertyBinder
    PropertyBinder propertyBinder = new PropertyBinder();
    propertyBinder.setName(inferredData.getPropertyName());
    propertyBinder.setReturnedClassName(inferredData.getTypeName());
    propertyBinder.setAccessType(inferredData.getDefaultAccess());
    propertyBinder.setHolder(propertyHolder);
    propertyBinder.setProperty(property);
    propertyBinder.setReturnedClass(inferredData.getPropertyClass());
    propertyBinder.setBuildingContext(context);
    if (isIdentifierMapper) {
        propertyBinder.setInsertable(false);
        propertyBinder.setUpdatable(false);
    }
    propertyBinder.setDeclaringClass(inferredData.getDeclaringClass());
    propertyBinder.setEntityBinder(entityBinder);
    propertyBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
    boolean isId = !entityBinder.isIgnoreIdAnnotations() && (property.isAnnotationPresent(Id.class) || property.isAnnotationPresent(EmbeddedId.class));
    propertyBinder.setId(isId);
    final LazyGroup lazyGroupAnnotation = property.getAnnotation(LazyGroup.class);
    if (lazyGroupAnnotation != null) {
        propertyBinder.setLazyGroup(lazyGroupAnnotation.value());
    }
    if (property.isAnnotationPresent(Version.class)) {
        if (isIdentifierMapper) {
            throw new AnnotationException("@IdClass class should not have @Version property");
        }
        if (!(propertyHolder.getPersistentClass() instanceof RootClass)) {
            throw new AnnotationException("Unable to define/override @Version on a subclass: " + propertyHolder.getEntityName());
        }
        if (!propertyHolder.isEntity()) {
            throw new AnnotationException("Unable to define @Version on an embedded class: " + propertyHolder.getEntityName());
        }
        if (traceEnabled) {
            LOG.tracev("{0} is a version property", inferredData.getPropertyName());
        }
        RootClass rootClass = (RootClass) propertyHolder.getPersistentClass();
        propertyBinder.setColumns(columns);
        Property prop = propertyBinder.makePropertyValueAndBind();
        setVersionInformation(property, propertyBinder);
        rootClass.setVersion(prop);
        //If version is on a mapped superclass, update the mapping
        final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(inferredData.getDeclaringClass(), inheritanceStatePerClass, context);
        if (superclass != null) {
            superclass.setDeclaredVersion(prop);
        } else {
            //we know the property is on the actual entity
            rootClass.setDeclaredVersion(prop);
        }
        SimpleValue simpleValue = (SimpleValue) prop.getValue();
        simpleValue.setNullValue("undefined");
        rootClass.setOptimisticLockStyle(OptimisticLockStyle.VERSION);
        if (traceEnabled) {
            LOG.tracev("Version name: {0}, unsavedValue: {1}", rootClass.getVersion().getName(), ((SimpleValue) rootClass.getVersion().getValue()).getNullValue());
        }
    } else {
        final boolean forcePersist = property.isAnnotationPresent(MapsId.class) || property.isAnnotationPresent(Id.class);
        if (property.isAnnotationPresent(ManyToOne.class)) {
            ManyToOne ann = property.getAnnotation(ManyToOne.class);
            //check validity
            if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Columns.class)) {
                throw new AnnotationException("@Column(s) not allowed on a @ManyToOne property: " + BinderHelper.getPath(propertyHolder, inferredData));
            }
            Cascade hibernateCascade = property.getAnnotation(Cascade.class);
            NotFound notFound = property.getAnnotation(NotFound.class);
            boolean ignoreNotFound = notFound != null && notFound.action().equals(NotFoundAction.IGNORE);
            OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
            boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals(onDeleteAnn.action());
            JoinTable assocTable = propertyHolder.getJoinTable(property);
            if (assocTable != null) {
                Join join = propertyHolder.addJoin(assocTable, false);
                for (Ejb3JoinColumn joinColumn : joinColumns) {
                    joinColumn.setExplicitTableName(join.getTable().getName());
                }
            }
            final boolean mandatory = !ann.optional() || forcePersist;
            bindManyToOne(getCascadeStrategy(ann.cascade(), hibernateCascade, false, forcePersist), joinColumns, !mandatory, ignoreNotFound, onDeleteCascade, ToOneBinder.getTargetEntity(inferredData, context), propertyHolder, inferredData, false, isIdentifierMapper, inSecondPass, propertyBinder, context);
        } else if (property.isAnnotationPresent(OneToOne.class)) {
            OneToOne ann = property.getAnnotation(OneToOne.class);
            //check validity
            if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Columns.class)) {
                throw new AnnotationException("@Column(s) not allowed on a @OneToOne property: " + BinderHelper.getPath(propertyHolder, inferredData));
            }
            //FIXME support a proper PKJCs
            boolean trueOneToOne = property.isAnnotationPresent(PrimaryKeyJoinColumn.class) || property.isAnnotationPresent(PrimaryKeyJoinColumns.class);
            Cascade hibernateCascade = property.getAnnotation(Cascade.class);
            NotFound notFound = property.getAnnotation(NotFound.class);
            boolean ignoreNotFound = notFound != null && notFound.action().equals(NotFoundAction.IGNORE);
            OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
            boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals(onDeleteAnn.action());
            JoinTable assocTable = propertyHolder.getJoinTable(property);
            if (assocTable != null) {
                Join join = propertyHolder.addJoin(assocTable, false);
                for (Ejb3JoinColumn joinColumn : joinColumns) {
                    joinColumn.setExplicitTableName(join.getTable().getName());
                }
            }
            //MapsId means the columns belong to the pk => not null
            //@OneToOne with @PKJC can still be optional
            final boolean mandatory = !ann.optional() || forcePersist;
            bindOneToOne(getCascadeStrategy(ann.cascade(), hibernateCascade, ann.orphanRemoval(), forcePersist), joinColumns, !mandatory, getFetchMode(ann.fetch()), ignoreNotFound, onDeleteCascade, ToOneBinder.getTargetEntity(inferredData, context), propertyHolder, inferredData, ann.mappedBy(), trueOneToOne, isIdentifierMapper, inSecondPass, propertyBinder, context);
        } else if (property.isAnnotationPresent(org.hibernate.annotations.Any.class)) {
            //check validity
            if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Columns.class)) {
                throw new AnnotationException("@Column(s) not allowed on a @Any property: " + BinderHelper.getPath(propertyHolder, inferredData));
            }
            Cascade hibernateCascade = property.getAnnotation(Cascade.class);
            OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
            boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals(onDeleteAnn.action());
            JoinTable assocTable = propertyHolder.getJoinTable(property);
            if (assocTable != null) {
                Join join = propertyHolder.addJoin(assocTable, false);
                for (Ejb3JoinColumn joinColumn : joinColumns) {
                    joinColumn.setExplicitTableName(join.getTable().getName());
                }
            }
            bindAny(getCascadeStrategy(null, hibernateCascade, false, forcePersist), //@Any has not cascade attribute
            joinColumns, onDeleteCascade, nullability, propertyHolder, inferredData, entityBinder, isIdentifierMapper, context);
        } else if (property.isAnnotationPresent(OneToMany.class) || property.isAnnotationPresent(ManyToMany.class) || property.isAnnotationPresent(ElementCollection.class) || property.isAnnotationPresent(ManyToAny.class)) {
            OneToMany oneToManyAnn = property.getAnnotation(OneToMany.class);
            ManyToMany manyToManyAnn = property.getAnnotation(ManyToMany.class);
            ElementCollection elementCollectionAnn = property.getAnnotation(ElementCollection.class);
            if ((oneToManyAnn != null || manyToManyAnn != null || elementCollectionAnn != null) && isToManyAssociationWithinEmbeddableCollection(propertyHolder)) {
                throw new AnnotationException("@OneToMany, @ManyToMany or @ElementCollection cannot be used inside an @Embeddable that is also contained within an @ElementCollection: " + BinderHelper.getPath(propertyHolder, inferredData));
            }
            final IndexColumn indexColumn;
            if (property.isAnnotationPresent(OrderColumn.class)) {
                indexColumn = IndexColumn.buildColumnFromAnnotation(property.getAnnotation(OrderColumn.class), propertyHolder, inferredData, entityBinder.getSecondaryTables(), context);
                if (property.isAnnotationPresent(ListIndexBase.class)) {
                    indexColumn.setBase((property.getAnnotation(ListIndexBase.class)).value());
                }
            } else {
                //if @IndexColumn is not there, the generated IndexColumn is an implicit column and not used.
                //so we can leave the legacy processing as the default
                indexColumn = IndexColumn.buildColumnFromAnnotation(property.getAnnotation(org.hibernate.annotations.IndexColumn.class), propertyHolder, inferredData, context);
            }
            CollectionBinder collectionBinder = CollectionBinder.getCollectionBinder(propertyHolder.getEntityName(), property, !indexColumn.isImplicit(), property.isAnnotationPresent(MapKeyType.class), context);
            collectionBinder.setIndexColumn(indexColumn);
            collectionBinder.setMapKey(property.getAnnotation(MapKey.class));
            collectionBinder.setPropertyName(inferredData.getPropertyName());
            collectionBinder.setBatchSize(property.getAnnotation(BatchSize.class));
            collectionBinder.setJpaOrderBy(property.getAnnotation(javax.persistence.OrderBy.class));
            collectionBinder.setSqlOrderBy(property.getAnnotation(OrderBy.class));
            collectionBinder.setSort(property.getAnnotation(Sort.class));
            collectionBinder.setNaturalSort(property.getAnnotation(SortNatural.class));
            collectionBinder.setComparatorSort(property.getAnnotation(SortComparator.class));
            Cache cachAnn = property.getAnnotation(Cache.class);
            collectionBinder.setCache(cachAnn);
            collectionBinder.setPropertyHolder(propertyHolder);
            Cascade hibernateCascade = property.getAnnotation(Cascade.class);
            NotFound notFound = property.getAnnotation(NotFound.class);
            boolean ignoreNotFound = notFound != null && notFound.action().equals(NotFoundAction.IGNORE);
            collectionBinder.setIgnoreNotFound(ignoreNotFound);
            collectionBinder.setCollectionType(inferredData.getProperty().getElementClass());
            collectionBinder.setBuildingContext(context);
            collectionBinder.setAccessType(inferredData.getDefaultAccess());
            Ejb3Column[] elementColumns;
            //do not use "element" if you are a JPA 2 @ElementCollection only for legacy Hibernate mappings
            boolean isJPA2ForValueMapping = property.isAnnotationPresent(ElementCollection.class);
            PropertyData virtualProperty = isJPA2ForValueMapping ? inferredData : new WrappedInferredData(inferredData, "element");
            if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Formula.class)) {
                Column ann = property.getAnnotation(Column.class);
                Formula formulaAnn = property.getAnnotation(Formula.class);
                elementColumns = Ejb3Column.buildColumnFromAnnotation(new Column[] { ann }, formulaAnn, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
            } else if (property.isAnnotationPresent(Columns.class)) {
                Columns anns = property.getAnnotation(Columns.class);
                elementColumns = Ejb3Column.buildColumnFromAnnotation(anns.columns(), null, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
            } else {
                elementColumns = Ejb3Column.buildColumnFromAnnotation(null, null, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
            }
            {
                Column[] keyColumns = null;
                //JPA 2 has priority and has different default column values, differenciate legacy from JPA 2
                Boolean isJPA2 = null;
                if (property.isAnnotationPresent(MapKeyColumn.class)) {
                    isJPA2 = Boolean.TRUE;
                    keyColumns = new Column[] { new MapKeyColumnDelegator(property.getAnnotation(MapKeyColumn.class)) };
                }
                //not explicitly legacy
                if (isJPA2 == null) {
                    isJPA2 = Boolean.TRUE;
                }
                //nullify empty array
                keyColumns = keyColumns != null && keyColumns.length > 0 ? keyColumns : null;
                //"mapkey" is the legacy column name of the key column pre JPA 2
                PropertyData mapKeyVirtualProperty = new WrappedInferredData(inferredData, "mapkey");
                Ejb3Column[] mapColumns = Ejb3Column.buildColumnFromAnnotation(keyColumns, null, Nullability.FORCED_NOT_NULL, propertyHolder, isJPA2 ? inferredData : mapKeyVirtualProperty, isJPA2 ? "_KEY" : null, entityBinder.getSecondaryTables(), context);
                collectionBinder.setMapKeyColumns(mapColumns);
            }
            {
                JoinColumn[] joinKeyColumns = null;
                //JPA 2 has priority and has different default column values, differenciate legacy from JPA 2
                Boolean isJPA2 = null;
                if (property.isAnnotationPresent(MapKeyJoinColumns.class)) {
                    isJPA2 = Boolean.TRUE;
                    final MapKeyJoinColumn[] mapKeyJoinColumns = property.getAnnotation(MapKeyJoinColumns.class).value();
                    joinKeyColumns = new JoinColumn[mapKeyJoinColumns.length];
                    int index = 0;
                    for (MapKeyJoinColumn joinColumn : mapKeyJoinColumns) {
                        joinKeyColumns[index] = new MapKeyJoinColumnDelegator(joinColumn);
                        index++;
                    }
                    if (property.isAnnotationPresent(MapKeyJoinColumn.class)) {
                        throw new AnnotationException("@MapKeyJoinColumn and @MapKeyJoinColumns used on the same property: " + BinderHelper.getPath(propertyHolder, inferredData));
                    }
                } else if (property.isAnnotationPresent(MapKeyJoinColumn.class)) {
                    isJPA2 = Boolean.TRUE;
                    joinKeyColumns = new JoinColumn[] { new MapKeyJoinColumnDelegator(property.getAnnotation(MapKeyJoinColumn.class)) };
                }
                //not explicitly legacy
                if (isJPA2 == null) {
                    isJPA2 = Boolean.TRUE;
                }
                PropertyData mapKeyVirtualProperty = new WrappedInferredData(inferredData, "mapkey");
                Ejb3JoinColumn[] mapJoinColumns = Ejb3JoinColumn.buildJoinColumnsWithDefaultColumnSuffix(joinKeyColumns, null, entityBinder.getSecondaryTables(), propertyHolder, isJPA2 ? inferredData.getPropertyName() : mapKeyVirtualProperty.getPropertyName(), isJPA2 ? "_KEY" : null, context);
                collectionBinder.setMapKeyManyToManyColumns(mapJoinColumns);
            }
            //potential element
            collectionBinder.setEmbedded(property.isAnnotationPresent(Embedded.class));
            collectionBinder.setElementColumns(elementColumns);
            collectionBinder.setProperty(property);
            //TODO enhance exception with @ManyToAny and @CollectionOfElements
            if (oneToManyAnn != null && manyToManyAnn != null) {
                throw new AnnotationException("@OneToMany and @ManyToMany on the same property is not allowed: " + propertyHolder.getEntityName() + "." + inferredData.getPropertyName());
            }
            String mappedBy = null;
            if (oneToManyAnn != null) {
                for (Ejb3JoinColumn column : joinColumns) {
                    if (column.isSecondary()) {
                        throw new NotYetImplementedException("Collections having FK in secondary table");
                    }
                }
                collectionBinder.setFkJoinColumns(joinColumns);
                mappedBy = oneToManyAnn.mappedBy();
                collectionBinder.setTargetEntity(context.getBuildingOptions().getReflectionManager().toXClass(oneToManyAnn.targetEntity()));
                collectionBinder.setCascadeStrategy(getCascadeStrategy(oneToManyAnn.cascade(), hibernateCascade, oneToManyAnn.orphanRemoval(), false));
                collectionBinder.setOneToMany(true);
            } else if (elementCollectionAnn != null) {
                for (Ejb3JoinColumn column : joinColumns) {
                    if (column.isSecondary()) {
                        throw new NotYetImplementedException("Collections having FK in secondary table");
                    }
                }
                collectionBinder.setFkJoinColumns(joinColumns);
                mappedBy = "";
                final Class<?> targetElement = elementCollectionAnn.targetClass();
                collectionBinder.setTargetEntity(context.getBuildingOptions().getReflectionManager().toXClass(targetElement));
                //collectionBinder.setCascadeStrategy( getCascadeStrategy( embeddedCollectionAnn.cascade(), hibernateCascade ) );
                collectionBinder.setOneToMany(true);
            } else if (manyToManyAnn != null) {
                mappedBy = manyToManyAnn.mappedBy();
                collectionBinder.setTargetEntity(context.getBuildingOptions().getReflectionManager().toXClass(manyToManyAnn.targetEntity()));
                collectionBinder.setCascadeStrategy(getCascadeStrategy(manyToManyAnn.cascade(), hibernateCascade, false, false));
                collectionBinder.setOneToMany(false);
            } else if (property.isAnnotationPresent(ManyToAny.class)) {
                mappedBy = "";
                collectionBinder.setTargetEntity(context.getBuildingOptions().getReflectionManager().toXClass(void.class));
                collectionBinder.setCascadeStrategy(getCascadeStrategy(null, hibernateCascade, false, false));
                collectionBinder.setOneToMany(false);
            }
            collectionBinder.setMappedBy(mappedBy);
            bindJoinedTableAssociation(property, context, entityBinder, collectionBinder, propertyHolder, inferredData, mappedBy);
            OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
            boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals(onDeleteAnn.action());
            collectionBinder.setCascadeDeleteEnabled(onDeleteCascade);
            if (isIdentifierMapper) {
                collectionBinder.setInsertable(false);
                collectionBinder.setUpdatable(false);
            }
            if (property.isAnnotationPresent(CollectionId.class)) {
                //do not compute the generators unless necessary
                HashMap<String, IdentifierGeneratorDefinition> localGenerators = (HashMap<String, IdentifierGeneratorDefinition>) classGenerators.clone();
                localGenerators.putAll(buildLocalGenerators(property, context));
                collectionBinder.setLocalGenerators(localGenerators);
            }
            collectionBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
            collectionBinder.setDeclaringClass(inferredData.getDeclaringClass());
            collectionBinder.bind();
        } else //Either a regular property or a basic @Id or @EmbeddedId while not ignoring id annotations
        if (!isId || !entityBinder.isIgnoreIdAnnotations()) {
            //define whether the type is a component or not
            boolean isComponent = false;
            //Overrides from @MapsId if needed
            boolean isOverridden = false;
            if (isId || propertyHolder.isOrWithinEmbeddedId() || propertyHolder.isInIdClass()) {
                //the associated entity could be using an @IdClass making the overridden property a component
                final PropertyData overridingProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(isId, propertyHolder, property.getName(), context);
                if (overridingProperty != null) {
                    isOverridden = true;
                    final InheritanceState state = inheritanceStatePerClass.get(overridingProperty.getClassOrElement());
                    if (state != null) {
                        isComponent = isComponent || state.hasIdClassOrEmbeddedId();
                    }
                    //Get the new column
                    columns = columnsBuilder.overrideColumnFromMapperOrMapsIdProperty(isId);
                }
            }
            isComponent = isComponent || property.isAnnotationPresent(Embedded.class) || property.isAnnotationPresent(EmbeddedId.class) || returnedClass.isAnnotationPresent(Embeddable.class);
            if (isComponent) {
                String referencedEntityName = null;
                if (isOverridden) {
                    final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(isId, propertyHolder, property.getName(), context);
                    referencedEntityName = mapsIdProperty.getClassOrElementName();
                }
                AccessType propertyAccessor = entityBinder.getPropertyAccessor(property);
                propertyBinder = bindComponent(inferredData, propertyHolder, propertyAccessor, entityBinder, isIdentifierMapper, context, isComponentEmbedded, isId, inheritanceStatePerClass, referencedEntityName, isOverridden ? (Ejb3JoinColumn[]) columns : null);
            } else {
                //provide the basic property mapping
                boolean optional = true;
                boolean lazy = false;
                if (property.isAnnotationPresent(Basic.class)) {
                    Basic ann = property.getAnnotation(Basic.class);
                    optional = ann.optional();
                    lazy = ann.fetch() == FetchType.LAZY;
                }
                //implicit type will check basic types and Serializable classes
                if (isId || (!optional && nullability != Nullability.FORCED_NULL)) {
                    //force columns to not null
                    for (Ejb3Column col : columns) {
                        if (isId && col.isFormula()) {
                            throw new CannotForceNonNullableException(String.format(Locale.ROOT, "Identifier property [%s] cannot contain formula mapping [%s]", HCANNHelper.annotatedElementSignature(property), col.getFormulaString()));
                        }
                        col.forceNotNull();
                    }
                }
                propertyBinder.setLazy(lazy);
                propertyBinder.setColumns(columns);
                if (isOverridden) {
                    final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(isId, propertyHolder, property.getName(), context);
                    propertyBinder.setReferencedEntityName(mapsIdProperty.getClassOrElementName());
                }
                propertyBinder.makePropertyValueAndBind();
            }
            if (isOverridden) {
                final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(isId, propertyHolder, property.getName(), context);
                Map<String, IdentifierGeneratorDefinition> localGenerators = (HashMap<String, IdentifierGeneratorDefinition>) classGenerators.clone();
                final IdentifierGeneratorDefinition.Builder foreignGeneratorBuilder = new IdentifierGeneratorDefinition.Builder();
                foreignGeneratorBuilder.setName("Hibernate-local--foreign generator");
                foreignGeneratorBuilder.setStrategy("foreign");
                foreignGeneratorBuilder.addParam("property", mapsIdProperty.getPropertyName());
                final IdentifierGeneratorDefinition foreignGenerator = foreignGeneratorBuilder.build();
                localGenerators.put(foreignGenerator.getName(), foreignGenerator);
                BinderHelper.makeIdGenerator((SimpleValue) propertyBinder.getValue(), foreignGenerator.getStrategy(), foreignGenerator.getName(), context, localGenerators);
            }
            if (isId) {
                //components and regular basic types create SimpleValue objects
                final SimpleValue value = (SimpleValue) propertyBinder.getValue();
                if (!isOverridden) {
                    processId(propertyHolder, inferredData, value, classGenerators, isIdentifierMapper, context);
                }
            }
        }
    }
    //init index
    //process indexes afterQuery everything: in second pass, many to one has to be done beforeQuery indexes
    Index index = property.getAnnotation(Index.class);
    if (index != null) {
        if (joinColumns != null) {
            for (Ejb3Column column : joinColumns) {
                column.addIndex(index, inSecondPass);
            }
        } else {
            if (columns != null) {
                for (Ejb3Column column : columns) {
                    column.addIndex(index, inSecondPass);
                }
            }
        }
    }
    // Natural ID columns must reside in one single UniqueKey within the Table.
    // For now, simply ensure consistent naming.
    // TODO: AFAIK, there really isn't a reason for these UKs to be created
    // on the secondPass.  This whole area should go away...
    NaturalId naturalIdAnn = property.getAnnotation(NaturalId.class);
    if (naturalIdAnn != null) {
        if (joinColumns != null) {
            for (Ejb3Column column : joinColumns) {
                String keyName = "UK_" + Constraint.hashedName(column.getTable().getName() + "_NaturalID");
                column.addUniqueKey(keyName, inSecondPass);
            }
        } else {
            for (Ejb3Column column : columns) {
                String keyName = "UK_" + Constraint.hashedName(column.getTable().getName() + "_NaturalID");
                column.addUniqueKey(keyName, inSecondPass);
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) MapKeyJoinColumnDelegator(org.hibernate.cfg.annotations.MapKeyJoinColumnDelegator) Index(org.hibernate.annotations.Index) XClass(org.hibernate.annotations.common.reflection.XClass) ManyToOne(javax.persistence.ManyToOne) DiscriminatorFormula(org.hibernate.annotations.DiscriminatorFormula) Formula(org.hibernate.annotations.Formula) PrimaryKeyJoinColumn(javax.persistence.PrimaryKeyJoinColumn) MapKeyJoinColumn(javax.persistence.MapKeyJoinColumn) JoinColumn(javax.persistence.JoinColumn) AnnotationException(org.hibernate.AnnotationException) ElementCollection(javax.persistence.ElementCollection) NaturalId(org.hibernate.annotations.NaturalId) RootClass(org.hibernate.mapping.RootClass) OrderColumn(javax.persistence.OrderColumn) EmbeddedId(javax.persistence.EmbeddedId) ListIndexBase(org.hibernate.annotations.ListIndexBase) OneToMany(javax.persistence.OneToMany) CollectionId(org.hibernate.annotations.CollectionId) LazyGroup(org.hibernate.annotations.LazyGroup) MapsId(javax.persistence.MapsId) NaturalId(org.hibernate.annotations.NaturalId) EmbeddedId(javax.persistence.EmbeddedId) Id(javax.persistence.Id) CollectionId(org.hibernate.annotations.CollectionId) CollectionBinder(org.hibernate.cfg.annotations.CollectionBinder) OnDelete(org.hibernate.annotations.OnDelete) Cache(org.hibernate.annotations.Cache) NaturalIdCache(org.hibernate.annotations.NaturalIdCache) Basic(javax.persistence.Basic) MapsId(javax.persistence.MapsId) MapKeyJoinColumns(javax.persistence.MapKeyJoinColumns) OneToOne(javax.persistence.OneToOne) MapKeyColumn(javax.persistence.MapKeyColumn) OrderColumn(javax.persistence.OrderColumn) PrimaryKeyJoinColumn(javax.persistence.PrimaryKeyJoinColumn) MapKeyJoinColumn(javax.persistence.MapKeyJoinColumn) Column(javax.persistence.Column) DiscriminatorColumn(javax.persistence.DiscriminatorColumn) JoinColumn(javax.persistence.JoinColumn) PropertyBinder(org.hibernate.cfg.annotations.PropertyBinder) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty) Cascade(org.hibernate.annotations.Cascade) XProperty(org.hibernate.annotations.common.reflection.XProperty) MapKeyJoinColumns(javax.persistence.MapKeyJoinColumns) Columns(org.hibernate.annotations.Columns) JoinColumns(javax.persistence.JoinColumns) PrimaryKeyJoinColumns(javax.persistence.PrimaryKeyJoinColumns) Join(org.hibernate.mapping.Join) ManyToMany(javax.persistence.ManyToMany) MapKeyColumnDelegator(org.hibernate.cfg.annotations.MapKeyColumnDelegator) UniqueConstraint(javax.persistence.UniqueConstraint) Constraint(org.hibernate.mapping.Constraint) SimpleValue(org.hibernate.mapping.SimpleValue) MapKeyJoinColumn(javax.persistence.MapKeyJoinColumn) IdentifierGeneratorDefinition(org.hibernate.boot.model.IdentifierGeneratorDefinition) NotFound(org.hibernate.annotations.NotFound) JoinTable(javax.persistence.JoinTable)

Aggregations

Join (org.hibernate.mapping.Join)22 Iterator (java.util.Iterator)8 PersistentClass (org.hibernate.mapping.PersistentClass)7 Property (org.hibernate.mapping.Property)7 Column (org.hibernate.mapping.Column)6 AnnotationException (org.hibernate.AnnotationException)5 AssertionFailure (org.hibernate.AssertionFailure)5 Component (org.hibernate.mapping.Component)5 Table (org.hibernate.mapping.Table)5 HashMap (java.util.HashMap)4 ManyToOne (org.hibernate.mapping.ManyToOne)4 SimpleValue (org.hibernate.mapping.SimpleValue)4 JoinTable (javax.persistence.JoinTable)3 XProperty (org.hibernate.annotations.common.reflection.XProperty)3 Ejb3JoinColumn (org.hibernate.cfg.Ejb3JoinColumn)3 SyntheticProperty (org.hibernate.mapping.SyntheticProperty)3 Test (org.junit.Test)3 ElementCollection (javax.persistence.ElementCollection)2 JoinColumn (javax.persistence.JoinColumn)2 MapKeyColumn (javax.persistence.MapKeyColumn)2