Search in sources :

Example 6 with Component

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

the class ModelBinder method bindNonAggregatedCompositeEntityIdentifier.

private void bindNonAggregatedCompositeEntityIdentifier(MappingDocument mappingDocument, EntityHierarchySourceImpl hierarchySource, RootClass rootEntityDescriptor) {
    final IdentifierSourceNonAggregatedComposite identifierSource = (IdentifierSourceNonAggregatedComposite) hierarchySource.getIdentifierSource();
    final Component cid = new Component(mappingDocument.getMetadataCollector(), rootEntityDescriptor);
    cid.setKey(true);
    rootEntityDescriptor.setIdentifier(cid);
    final String idClassName = extractIdClassName(identifierSource);
    bindComponent(mappingDocument, hierarchySource.getRoot().getAttributeRoleBase().append("<id>").getFullPath(), identifierSource.getEmbeddableSource(), cid, idClassName, rootEntityDescriptor.getClassName(), null, idClassName == null, false, null);
    if (idClassName != null) {
        // we also need to bind the "id mapper".  ugh, terrible name.  Basically we need to
        // create a virtual (embedded) composite for the non-aggregated attributes on the entity
        // itself.
        final Component mapper = new Component(mappingDocument.getMetadataCollector(), rootEntityDescriptor);
        bindComponent(mappingDocument, hierarchySource.getRoot().getAttributeRoleBase().append(ID_MAPPER_PATH_PART).getFullPath(), identifierSource.getEmbeddableSource(), mapper, rootEntityDescriptor.getClassName(), null, null, true, false, null);
        rootEntityDescriptor.setIdentifierMapper(mapper);
        Property property = new Property();
        property.setName(PropertyPath.IDENTIFIER_MAPPER_PROPERTY);
        property.setUpdateable(false);
        property.setInsertable(false);
        property.setValue(mapper);
        property.setPropertyAccessorName("embedded");
        rootEntityDescriptor.addProperty(property);
    }
    finishBindingCompositeIdentifier(mappingDocument, rootEntityDescriptor, identifierSource, cid, null);
}
Also used : IdentifierSourceNonAggregatedComposite(org.hibernate.boot.model.source.spi.IdentifierSourceNonAggregatedComposite) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) SyntheticProperty(org.hibernate.mapping.SyntheticProperty)

Example 7 with Component

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

the class ModelBinder method bindAggregatedCompositeEntityIdentifier.

private void bindAggregatedCompositeEntityIdentifier(MappingDocument mappingDocument, EntityHierarchySourceImpl hierarchySource, RootClass rootEntityDescriptor) {
    // an aggregated composite-id is a composite-id that defines a singular
    // (composite) attribute as part of the entity to represent the id.
    final IdentifierSourceAggregatedComposite identifierSource = (IdentifierSourceAggregatedComposite) hierarchySource.getIdentifierSource();
    final Component cid = new Component(mappingDocument.getMetadataCollector(), rootEntityDescriptor);
    cid.setKey(true);
    rootEntityDescriptor.setIdentifier(cid);
    final String idClassName = extractIdClassName(identifierSource);
    final String idPropertyName = identifierSource.getIdentifierAttributeSource().getName();
    final String pathPart = idPropertyName == null ? "<id>" : idPropertyName;
    bindComponent(mappingDocument, hierarchySource.getRoot().getAttributeRoleBase().append(pathPart).getFullPath(), identifierSource.getEmbeddableSource(), cid, idClassName, rootEntityDescriptor.getClassName(), idPropertyName, idClassName == null && idPropertyName == null, identifierSource.getEmbeddableSource().isDynamic(), identifierSource.getIdentifierAttributeSource().getXmlNodeName());
    finishBindingCompositeIdentifier(mappingDocument, rootEntityDescriptor, identifierSource, cid, idPropertyName);
}
Also used : Component(org.hibernate.mapping.Component) IdentifierSourceAggregatedComposite(org.hibernate.boot.model.source.spi.IdentifierSourceAggregatedComposite)

Example 8 with Component

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

the class BinderHelper method findPropertyByName.

/**
	 * Retrieve the property by path in a recursive way, including IndetifierProperty in the loop
	 * If propertyName is null or empty, the IdentifierProperty is returned
	 */
public static Property findPropertyByName(PersistentClass associatedClass, String propertyName) {
    Property property = null;
    Property idProperty = associatedClass.getIdentifierProperty();
    String idName = idProperty != null ? idProperty.getName() : null;
    try {
        if (propertyName == null || propertyName.length() == 0 || propertyName.equals(idName)) {
            //default to id
            property = idProperty;
        } else {
            if (propertyName.indexOf(idName + ".") == 0) {
                property = idProperty;
                propertyName = propertyName.substring(idName.length() + 1);
            }
            StringTokenizer st = new StringTokenizer(propertyName, ".", false);
            while (st.hasMoreElements()) {
                String element = (String) st.nextElement();
                if (property == null) {
                    property = associatedClass.getProperty(element);
                } else {
                    if (!property.isComposite()) {
                        return null;
                    }
                    property = ((Component) property.getValue()).getProperty(element);
                }
            }
        }
    } catch (MappingException e) {
        try {
            //if we do not find it try to check the identifier mapper
            if (associatedClass.getIdentifierMapper() == null) {
                return null;
            }
            StringTokenizer st = new StringTokenizer(propertyName, ".", false);
            while (st.hasMoreElements()) {
                String element = (String) st.nextElement();
                if (property == null) {
                    property = associatedClass.getIdentifierMapper().getProperty(element);
                } else {
                    if (!property.isComposite()) {
                        return null;
                    }
                    property = ((Component) property.getValue()).getProperty(element);
                }
            }
        } catch (MappingException ee) {
            return null;
        }
    }
    return property;
}
Also used : StringTokenizer(java.util.StringTokenizer) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) SyntheticProperty(org.hibernate.mapping.SyntheticProperty) MappingException(org.hibernate.MappingException)

Example 9 with Component

use of org.hibernate.mapping.Component 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 10 with Component

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

the class AnnotationBinder method bindIdClass.

private static void bindIdClass(String generatorType, String generatorName, PropertyData inferredData, PropertyData baseInferredData, Ejb3Column[] columns, PropertyHolder propertyHolder, boolean isComposite, AccessType propertyAccessor, EntityBinder entityBinder, boolean isEmbedded, boolean isIdentifierMapper, MetadataBuildingContext buildingContext, Map<XClass, InheritanceState> inheritanceStatePerClass) {
    /*
		 * Fill simple value and property since and Id is a property
		 */
    PersistentClass persistentClass = propertyHolder.getPersistentClass();
    if (!(persistentClass instanceof RootClass)) {
        throw new AnnotationException("Unable to define/override @Id(s) on a subclass: " + propertyHolder.getEntityName());
    }
    RootClass rootClass = (RootClass) persistentClass;
    String persistentClassName = rootClass.getClassName();
    SimpleValue id;
    final String propertyName = inferredData.getPropertyName();
    HashMap<String, IdGenerator> localGenerators = new HashMap<String, IdGenerator>();
    if (isComposite) {
        id = fillComponent(propertyHolder, inferredData, baseInferredData, propertyAccessor, false, entityBinder, isEmbedded, isIdentifierMapper, false, buildingContext, inheritanceStatePerClass);
        Component componentId = (Component) id;
        componentId.setKey(true);
        if (rootClass.getIdentifier() != null) {
            throw new AnnotationException(componentId.getComponentClassName() + " must not have @Id properties when used as an @EmbeddedId");
        }
        if (componentId.getPropertySpan() == 0) {
            throw new AnnotationException(componentId.getComponentClassName() + " has no persistent id property");
        }
        //tuplizers
        XProperty property = inferredData.getProperty();
        setupComponentTuplizer(property, componentId);
    } else {
        for (Ejb3Column column : columns) {
            //this is an id
            column.forceNotNull();
        }
        SimpleValueBinder value = new SimpleValueBinder();
        value.setPropertyName(propertyName);
        value.setReturnedClassName(inferredData.getTypeName());
        value.setColumns(columns);
        value.setPersistentClassName(persistentClassName);
        value.setBuildingContext(buildingContext);
        value.setType(inferredData.getProperty(), inferredData.getClassOrElement(), persistentClassName, null);
        value.setAccessType(propertyAccessor);
        id = value.make();
    }
    rootClass.setIdentifier(id);
    BinderHelper.makeIdGenerator(id, generatorType, generatorName, buildingContext, Collections.<String, IdentifierGeneratorDefinition>emptyMap());
    if (isEmbedded) {
        rootClass.setEmbeddedIdentifier(inferredData.getPropertyClass() == null);
    } else {
        PropertyBinder binder = new PropertyBinder();
        binder.setName(propertyName);
        binder.setValue(id);
        binder.setAccessType(inferredData.getDefaultAccess());
        binder.setProperty(inferredData.getProperty());
        Property prop = binder.makeProperty();
        rootClass.setIdentifierProperty(prop);
        //if the id property is on a superclass, update the metamodel
        final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(inferredData.getDeclaringClass(), inheritanceStatePerClass, buildingContext);
        if (superclass != null) {
            superclass.setDeclaredIdentifierProperty(prop);
        } else {
            //we know the property is on the actual entity
            rootClass.setDeclaredIdentifierProperty(prop);
        }
    }
}
Also used : RootClass(org.hibernate.mapping.RootClass) XProperty(org.hibernate.annotations.common.reflection.XProperty) HashMap(java.util.HashMap) IdGenerator(org.hibernate.mapping.IdGenerator) SimpleValue(org.hibernate.mapping.SimpleValue) SimpleValueBinder(org.hibernate.cfg.annotations.SimpleValueBinder) AnnotationException(org.hibernate.AnnotationException) PropertyBinder(org.hibernate.cfg.annotations.PropertyBinder) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty) PersistentClass(org.hibernate.mapping.PersistentClass)

Aggregations

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