Search in sources :

Example 21 with Component

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

the class OneToOneSecondPass method doSecondPass.

//TODO refactor this code, there is a lot of duplication in this method
public void doSecondPass(Map persistentClasses) throws MappingException {
    org.hibernate.mapping.OneToOne value = new org.hibernate.mapping.OneToOne(buildingContext.getMetadataCollector(), propertyHolder.getTable(), propertyHolder.getPersistentClass());
    final String propertyName = inferredData.getPropertyName();
    value.setPropertyName(propertyName);
    String referencedEntityName = ToOneBinder.getReferenceEntityName(inferredData, targetEntity, buildingContext);
    value.setReferencedEntityName(referencedEntityName);
    AnnotationBinder.defineFetchingStrategy(value, inferredData.getProperty());
    //value.setFetchMode( fetchMode );
    value.setCascadeDeleteEnabled(cascadeOnDelete);
    if (!optional)
        value.setConstrained(true);
    value.setForeignKeyType(value.isConstrained() ? ForeignKeyDirection.FROM_PARENT : ForeignKeyDirection.TO_PARENT);
    PropertyBinder binder = new PropertyBinder();
    binder.setName(propertyName);
    binder.setValue(value);
    binder.setCascade(cascadeStrategy);
    binder.setAccessType(inferredData.getDefaultAccess());
    Property prop = binder.makeProperty();
    if (ignoreNotFound) {
        prop.setOptional(true);
    }
    if (BinderHelper.isEmptyAnnotationValue(mappedBy)) {
        /*
			 * we need to check if the columns are in the right order
			 * if not, then we need to create a many to one and formula
			 * but actually, since entities linked by a one to one need
			 * to share the same composite id class, this cannot happen in hibernate
			 */
        boolean rightOrder = true;
        if (rightOrder) {
            String path = StringHelper.qualify(propertyHolder.getPath(), propertyName);
            final ToOneFkSecondPass secondPass = new ToOneFkSecondPass(value, joinColumns, //cannot have nullabe and unique on certain DBs
            !optional, propertyHolder.getEntityOwnerClassName(), path, buildingContext);
            secondPass.doSecondPass(persistentClasses);
            //no column associated since its a one to one
            propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
        } else {
        //this is a many to one with Formula
        }
    } else {
        PersistentClass otherSide = (PersistentClass) persistentClasses.get(value.getReferencedEntityName());
        Property otherSideProperty;
        try {
            if (otherSide == null) {
                throw new MappingException("Unable to find entity: " + value.getReferencedEntityName());
            }
            otherSideProperty = BinderHelper.findPropertyByName(otherSide, mappedBy);
        } catch (MappingException e) {
            throw new AnnotationException("Unknown mappedBy in: " + StringHelper.qualify(ownerEntity, ownerProperty) + ", referenced property unknown: " + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
        }
        if (otherSideProperty == null) {
            throw new AnnotationException("Unknown mappedBy in: " + StringHelper.qualify(ownerEntity, ownerProperty) + ", referenced property unknown: " + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
        }
        if (otherSideProperty.getValue() instanceof OneToOne) {
            propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
        } else if (otherSideProperty.getValue() instanceof ManyToOne) {
            Iterator it = otherSide.getJoinIterator();
            Join otherSideJoin = null;
            while (it.hasNext()) {
                Join otherSideJoinValue = (Join) it.next();
                if (otherSideJoinValue.containsProperty(otherSideProperty)) {
                    otherSideJoin = otherSideJoinValue;
                    break;
                }
            }
            if (otherSideJoin != null) {
                //@OneToOne @JoinTable
                Join mappedByJoin = buildJoinFromMappedBySide((PersistentClass) persistentClasses.get(ownerEntity), otherSideProperty, otherSideJoin);
                ManyToOne manyToOne = new ManyToOne(buildingContext.getMetadataCollector(), mappedByJoin.getTable());
                //FIXME use ignore not found here
                manyToOne.setIgnoreNotFound(ignoreNotFound);
                manyToOne.setCascadeDeleteEnabled(value.isCascadeDeleteEnabled());
                manyToOne.setFetchMode(value.getFetchMode());
                manyToOne.setLazy(value.isLazy());
                manyToOne.setReferencedEntityName(value.getReferencedEntityName());
                manyToOne.setUnwrapProxy(value.isUnwrapProxy());
                prop.setValue(manyToOne);
                Iterator otherSideJoinKeyColumns = otherSideJoin.getKey().getColumnIterator();
                while (otherSideJoinKeyColumns.hasNext()) {
                    Column column = (Column) otherSideJoinKeyColumns.next();
                    Column copy = new Column();
                    copy.setLength(column.getLength());
                    copy.setScale(column.getScale());
                    copy.setValue(manyToOne);
                    copy.setName(column.getQuotedName());
                    copy.setNullable(column.isNullable());
                    copy.setPrecision(column.getPrecision());
                    copy.setUnique(column.isUnique());
                    copy.setSqlType(column.getSqlType());
                    copy.setCheckConstraint(column.getCheckConstraint());
                    copy.setComment(column.getComment());
                    copy.setDefaultValue(column.getDefaultValue());
                    manyToOne.addColumn(copy);
                }
                mappedByJoin.addProperty(prop);
            } else {
                propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
            }
            value.setReferencedPropertyName(mappedBy);
            // HHH-6813
            // Foo: @Id long id, @OneToOne(mappedBy="foo") Bar bar
            // Bar: @Id @OneToOne Foo foo
            boolean referencesDerivedId = false;
            try {
                referencesDerivedId = otherSide.getIdentifier() instanceof Component && ((Component) otherSide.getIdentifier()).getProperty(mappedBy) != null;
            } catch (MappingException e) {
            // ignore
            }
            boolean referenceToPrimaryKey = referencesDerivedId || mappedBy == null;
            value.setReferenceToPrimaryKey(referenceToPrimaryKey);
            // loop of attempts to resolve identifiers.
            if (referencesDerivedId) {
                ((ManyToOne) otherSideProperty.getValue()).setReferenceToPrimaryKey(false);
            }
            String propertyRef = value.getReferencedPropertyName();
            if (propertyRef != null) {
                buildingContext.getMetadataCollector().addUniquePropertyReference(value.getReferencedEntityName(), propertyRef);
            }
        } else {
            throw new AnnotationException("Referenced property not a (One|Many)ToOne: " + StringHelper.qualify(otherSide.getEntityName(), mappedBy) + " in mappedBy of " + StringHelper.qualify(ownerEntity, ownerProperty));
        }
    }
    final ForeignKey fk = inferredData.getProperty().getAnnotation(ForeignKey.class);
    if (fk != null && !BinderHelper.isEmptyAnnotationValue(fk.name())) {
        value.setForeignKeyName(fk.name());
    } else {
        final javax.persistence.ForeignKey jpaFk = inferredData.getProperty().getAnnotation(javax.persistence.ForeignKey.class);
        if (jpaFk != null) {
            if (jpaFk.value() == ConstraintMode.NO_CONSTRAINT) {
                value.setForeignKeyName("none");
            } else {
                value.setForeignKeyName(StringHelper.nullIfEmpty(jpaFk.name()));
                value.setForeignKeyDefinition(StringHelper.nullIfEmpty(jpaFk.foreignKeyDefinition()));
            }
        }
    }
}
Also used : OneToOne(org.hibernate.mapping.OneToOne) Join(org.hibernate.mapping.Join) ForeignKey(org.hibernate.annotations.ForeignKey) ManyToOne(org.hibernate.mapping.ManyToOne) MappingException(org.hibernate.MappingException) OneToOne(org.hibernate.mapping.OneToOne) Column(org.hibernate.mapping.Column) Iterator(java.util.Iterator) AnnotationException(org.hibernate.AnnotationException) PropertyBinder(org.hibernate.cfg.annotations.PropertyBinder) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) PersistentClass(org.hibernate.mapping.PersistentClass)

Example 22 with Component

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

the class AttributeFactory method determineAttributeMetadata.

/**
	 * Here is most of the nuts and bolts of this factory, where we interpret the known JPA metadata
	 * against the known Hibernate metadata and build a descriptor for the attribute.
	 *
	 * @param attributeContext The attribute to be described
	 * @param memberResolver Strategy for how to resolve the member defining the attribute.
	 * @param <X> The owner type
	 * @param <Y> The attribute type
	 *
	 * @return The attribute description
	 */
@SuppressWarnings({ "unchecked" })
private <X, Y> AttributeMetadata<X, Y> determineAttributeMetadata(AttributeContext<X> attributeContext, MemberResolver memberResolver) {
    LOG.trace("Starting attribute metadata determination [" + attributeContext.getPropertyMapping().getName() + "]");
    final Member member = memberResolver.resolveMember(attributeContext);
    LOG.trace("    Determined member [" + member + "]");
    final Value value = attributeContext.getPropertyMapping().getValue();
    final org.hibernate.type.Type type = value.getType();
    LOG.trace("    Determined type [name=" + type.getName() + ", class=" + type.getClass().getName() + "]");
    if (type.isAnyType()) {
        // ANY mappings are currently not supported in the JPA metamodel; see HHH-6589
        if (context.isIgnoreUnsupported()) {
            return null;
        } else {
            throw new UnsupportedOperationException("ANY not supported");
        }
    } else if (type.isAssociationType()) {
        // collection or entity
        if (type.isEntityType()) {
            // entity
            return new SingularAttributeMetadataImpl<X, Y>(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, determineSingularAssociationAttributeType(member));
        }
        // collection
        if (value instanceof Collection) {
            final Collection collValue = (Collection) value;
            final Value elementValue = collValue.getElement();
            final org.hibernate.type.Type elementType = elementValue.getType();
            // First, determine the type of the elements and use that to help determine the
            // collection type)
            final Attribute.PersistentAttributeType elementPersistentAttributeType;
            final Attribute.PersistentAttributeType persistentAttributeType;
            if (elementType.isAnyType()) {
                if (context.isIgnoreUnsupported()) {
                    return null;
                } else {
                    throw new UnsupportedOperationException("collection of any not supported yet");
                }
            }
            final boolean isManyToMany = isManyToMany(member);
            if (elementValue instanceof Component) {
                elementPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED;
                persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
            } else if (elementType.isAssociationType()) {
                elementPersistentAttributeType = isManyToMany ? Attribute.PersistentAttributeType.MANY_TO_MANY : Attribute.PersistentAttributeType.ONE_TO_MANY;
                persistentAttributeType = elementPersistentAttributeType;
            } else {
                elementPersistentAttributeType = Attribute.PersistentAttributeType.BASIC;
                persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
            }
            final Attribute.PersistentAttributeType keyPersistentAttributeType;
            // Finally, we determine the type of the map key (if needed)
            if (value instanceof Map) {
                final Value keyValue = ((Map) value).getIndex();
                final org.hibernate.type.Type keyType = keyValue.getType();
                if (keyType.isAnyType()) {
                    if (context.isIgnoreUnsupported()) {
                        return null;
                    } else {
                        throw new UnsupportedOperationException("collection of any not supported yet");
                    }
                }
                if (keyValue instanceof Component) {
                    keyPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED;
                } else if (keyType.isAssociationType()) {
                    keyPersistentAttributeType = Attribute.PersistentAttributeType.MANY_TO_ONE;
                } else {
                    keyPersistentAttributeType = Attribute.PersistentAttributeType.BASIC;
                }
            } else {
                keyPersistentAttributeType = null;
            }
            return new PluralAttributeMetadataImpl(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, persistentAttributeType, elementPersistentAttributeType, keyPersistentAttributeType);
        } else if (value instanceof OneToMany) {
            // element value within a o.h.mapping.Collection (see logic branch above)
            throw new IllegalArgumentException("HUH???");
        //					final boolean isManyToMany = isManyToMany( member );
        //					//one to many with FK => entity
        //					return new PluralAttributeMetadataImpl(
        //							attributeContext.getPropertyMapping(),
        //							attributeContext.getOwnerType(),
        //							member,
        //							isManyToMany
        //									? Attribute.PersistentAttributeType.MANY_TO_MANY
        //									: Attribute.PersistentAttributeType.ONE_TO_MANY
        //							value,
        //							AttributeContext.TypeStatus.ENTITY,
        //							Attribute.PersistentAttributeType.ONE_TO_MANY,
        //							null, null, null
        //					);
        }
    } else if (attributeContext.getPropertyMapping().isComposite()) {
        // component
        return new SingularAttributeMetadataImpl<X, Y>(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.EMBEDDED);
    } else {
        // basic type
        return new SingularAttributeMetadataImpl<X, Y>(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.BASIC);
    }
    throw new UnsupportedOperationException("oops, we are missing something: " + attributeContext.getPropertyMapping());
}
Also used : OneToMany(org.hibernate.mapping.OneToMany) EmbeddedComponentType(org.hibernate.type.EmbeddedComponentType) EntityType(org.hibernate.type.EntityType) ComponentType(org.hibernate.type.ComponentType) Type(javax.persistence.metamodel.Type) ParameterizedType(java.lang.reflect.ParameterizedType) Value(org.hibernate.mapping.Value) Collection(org.hibernate.mapping.Collection) Component(org.hibernate.mapping.Component) Member(java.lang.reflect.Member) Map(org.hibernate.mapping.Map)

Example 23 with Component

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

the class AbstractEntityPersister method internalInitSubclassPropertyAliasesMap.

private void internalInitSubclassPropertyAliasesMap(String path, Iterator propertyIterator) {
    while (propertyIterator.hasNext()) {
        Property prop = (Property) propertyIterator.next();
        String propname = path == null ? prop.getName() : path + "." + prop.getName();
        if (prop.isComposite()) {
            Component component = (Component) prop.getValue();
            Iterator compProps = component.getPropertyIterator();
            internalInitSubclassPropertyAliasesMap(propname, compProps);
        } else {
            String[] aliases = new String[prop.getColumnSpan()];
            String[] cols = new String[prop.getColumnSpan()];
            Iterator colIter = prop.getColumnIterator();
            int l = 0;
            while (colIter.hasNext()) {
                Selectable thing = (Selectable) colIter.next();
                aliases[l] = thing.getAlias(getFactory().getDialect(), prop.getValue().getTable());
                // TODO: skip formulas?
                cols[l] = thing.getText(getFactory().getDialect());
                l++;
            }
            subclassPropertyAliases.put(propname, aliases);
            subclassPropertyColumnNames.put(propname, cols);
        }
    }
}
Also used : Selectable(org.hibernate.mapping.Selectable) Iterator(java.util.Iterator) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property)

Example 24 with Component

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

the class CompositeElementTest method afterMetadataBuilt.

@Override
protected void afterMetadataBuilt(Metadata metadata) {
    Collection children = metadata.getCollectionBinding(Parent.class.getName() + ".children");
    Component childComponents = (Component) children.getElement();
    Formula f = (Formula) childComponents.getProperty("bioLength").getValue().getColumnIterator().next();
    SQLFunction lengthFunction = metadata.getDatabase().getJdbcEnvironment().getDialect().getFunctions().get("length");
    if (lengthFunction != null) {
        ArrayList args = new ArrayList();
        args.add("bio");
        f.setFormula(lengthFunction.render(StandardBasicTypes.INTEGER, args, null));
    }
}
Also used : Formula(org.hibernate.mapping.Formula) ArrayList(java.util.ArrayList) Collection(org.hibernate.mapping.Collection) SQLFunction(org.hibernate.dialect.function.SQLFunction) Component(org.hibernate.mapping.Component)

Example 25 with Component

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

the class ComponentTest method afterMetadataBuilt.

@Override
protected void afterMetadataBuilt(Metadata metadata) {
    // Oracle and Postgres do not have year() functions, so we need to
    // redefine the 'User.person.yob' formula
    //
    // consider temporary until we add the capability to define
    // mapping formulas which can use dialect-registered functions...
    PersistentClass user = metadata.getEntityBinding(User.class.getName());
    org.hibernate.mapping.Property personProperty = user.getProperty("person");
    Component component = (Component) personProperty.getValue();
    Formula f = (Formula) component.getProperty("yob").getValue().getColumnIterator().next();
    SQLFunction yearFunction = metadata.getDatabase().getJdbcEnvironment().getDialect().getFunctions().get("year");
    if (yearFunction == null) {
        // the dialect not know to support a year() function, so rely on the
        // ANSI SQL extract function
        f.setFormula("extract( year from dob )");
    } else {
        List args = new ArrayList();
        args.add("dob");
        f.setFormula(yearFunction.render(StandardBasicTypes.INTEGER, args, null));
    }
}
Also used : Formula(org.hibernate.mapping.Formula) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) SQLFunction(org.hibernate.dialect.function.SQLFunction) Component(org.hibernate.mapping.Component) 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