Search in sources :

Example 6 with Value

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

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

the class MapKeyCustomEnumTypeTest method getMapKeyType.

private Type getMapKeyType(Property prop) {
    Value value = prop.getValue();
    assertEquals(Map.class, value.getClass());
    Map map = (Map) value;
    return map.getIndex().getType();
}
Also used : Value(org.hibernate.mapping.Value) Map(org.hibernate.mapping.Map)

Example 8 with Value

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

the class CollectionMetadataGenerator method searchMappedByKey.

@SuppressWarnings({ "unchecked" })
private String searchMappedByKey(PersistentClass referencedClass, Collection collectionValue) {
    final Iterator<Value> assocIdClassProps = referencedClass.getKeyClosureIterator();
    while (assocIdClassProps.hasNext()) {
        final Value value = assocIdClassProps.next();
        // make sure its a 'Component' because IdClass is registered as this type.
        if (value instanceof Component) {
            final Component component = (Component) value;
            final Iterator<Property> componentPropertyIterator = component.getPropertyIterator();
            while (componentPropertyIterator.hasNext()) {
                final Property property = componentPropertyIterator.next();
                final Iterator<Selectable> propertySelectables = property.getValue().getColumnIterator();
                final Iterator<Selectable> collectionSelectables = collectionValue.getKey().getColumnIterator();
                if (Tools.iteratorsContentEqual(propertySelectables, collectionSelectables)) {
                    return property.getName();
                }
            }
        }
    }
    return null;
}
Also used : Selectable(org.hibernate.mapping.Selectable) Value(org.hibernate.mapping.Value) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property)

Example 9 with Value

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

the class CollectionMetadataGenerator method addOneToManyAttached.

@SuppressWarnings({ "unchecked" })
private void addOneToManyAttached(boolean fakeOneToManyBidirectional) {
    LOG.debugf("Adding audit mapping for property %s.%s: one-to-many collection, using a join column on the referenced entity", referencingEntityName, propertyName);
    // check whether the property has an @IndexColumn or @OrderColumn because its part of an
    // IndexedCollection mapping type.
    final boolean indexed = (propertyValue instanceof IndexedCollection) && ((IndexedCollection) propertyValue).getIndex() != null;
    final String mappedBy = getMappedBy(propertyValue);
    final IdMappingData referencedIdMapping = mainGenerator.getReferencedIdMappingData(referencingEntityName, referencedEntityName, propertyAuditingData, false);
    final IdMappingData referencingIdMapping = referencingEntityConfiguration.getIdMappingData();
    // Generating the id mappers data for the referencing side of the relation.
    final MiddleIdData referencingIdData = createMiddleIdData(referencingIdMapping, mappedBy + "_", referencingEntityName);
    // And for the referenced side. The prefixed mapper won't be used (as this collection isn't persisted
    // in a join table, so the prefix value is arbitrary).
    final MiddleIdData referencedIdData = createMiddleIdData(referencedIdMapping, null, referencedEntityName);
    // Generating the element mapping.
    final MiddleComponentData elementComponentData = new MiddleComponentData(new MiddleRelatedComponentMapper(referencedIdData), 0);
    // Generating the index mapping, if an index exists. It can only exists in case a javax.persistence.MapKey
    // annotation is present on the entity. So the middleEntityXml will be not be used. The queryGeneratorBuilder
    // will only be checked for nullnes.
    MiddleComponentData indexComponentData = addIndex(null, null);
    // Generating the query generator - it should read directly from the related entity.
    final RelationQueryGenerator queryGenerator = new OneAuditEntityQueryGenerator(mainGenerator.getGlobalCfg(), mainGenerator.getVerEntCfg(), mainGenerator.getAuditStrategy(), referencingIdData, referencedEntityName, referencedIdData, isEmbeddableElementType(), mappedBy, isMappedByKey(propertyValue, mappedBy));
    // Creating common mapper data.
    final CommonCollectionMapperData commonCollectionMapperData = new CommonCollectionMapperData(mainGenerator.getVerEntCfg(), referencedEntityName, propertyAuditingData.getPropertyData(), referencingIdData, queryGenerator);
    PropertyMapper fakeBidirectionalRelationMapper;
    PropertyMapper fakeBidirectionalRelationIndexMapper;
    if (fakeOneToManyBidirectional || indexed) {
        // In case of a fake many-to-one bidirectional relation, we have to generate a mapper which maps
        // the mapped-by property name to the id of the related entity (which is the owner of the collection).
        final String auditMappedBy;
        if (fakeOneToManyBidirectional) {
            auditMappedBy = propertyAuditingData.getAuditMappedBy();
        } else {
            auditMappedBy = propertyValue.getMappedByProperty();
        }
        // Creating a prefixed relation mapper.
        final IdMapper relMapper = referencingIdMapping.getIdMapper().prefixMappedProperties(MappingTools.createToOneRelationPrefix(auditMappedBy));
        fakeBidirectionalRelationMapper = new ToOneIdMapper(relMapper, // when constructing the PropertyData.
        new PropertyData(auditMappedBy, null, null, null), referencingEntityName, false);
        final String positionMappedBy;
        if (fakeOneToManyBidirectional) {
            positionMappedBy = propertyAuditingData.getPositionMappedBy();
        } else if (indexed) {
            final Value indexValue = ((IndexedCollection) propertyValue).getIndex();
            positionMappedBy = indexValue.getColumnIterator().next().getText();
        } else {
            positionMappedBy = null;
        }
        // Checking if there's an index defined. If so, adding a mapper for it.
        if (positionMappedBy != null) {
            fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper(new PropertyData(positionMappedBy, null, null, null));
            // Also, overwriting the index component data to properly read the index.
            indexComponentData = new MiddleComponentData(new MiddleStraightComponentMapper(positionMappedBy), 0);
        } else {
            fakeBidirectionalRelationIndexMapper = null;
        }
    } else {
        fakeBidirectionalRelationMapper = null;
        fakeBidirectionalRelationIndexMapper = null;
    }
    // Checking the type of the collection and adding an appropriate mapper.
    addMapper(commonCollectionMapperData, elementComponentData, indexComponentData);
    // Storing information about this relation.
    referencingEntityConfiguration.addToManyNotOwningRelation(propertyName, mappedBy, referencedEntityName, referencingIdData.getPrefixedMapper(), fakeBidirectionalRelationMapper, fakeBidirectionalRelationIndexMapper, indexed);
}
Also used : PropertyData(org.hibernate.envers.internal.entities.PropertyData) CommonCollectionMapperData(org.hibernate.envers.internal.entities.mapper.relation.CommonCollectionMapperData) MiddleRelatedComponentMapper(org.hibernate.envers.internal.entities.mapper.relation.component.MiddleRelatedComponentMapper) IdMapper(org.hibernate.envers.internal.entities.mapper.id.IdMapper) ToOneIdMapper(org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper) SinglePropertyMapper(org.hibernate.envers.internal.entities.mapper.SinglePropertyMapper) MultiPropertyMapper(org.hibernate.envers.internal.entities.mapper.MultiPropertyMapper) SinglePropertyMapper(org.hibernate.envers.internal.entities.mapper.SinglePropertyMapper) PropertyMapper(org.hibernate.envers.internal.entities.mapper.PropertyMapper) MiddleIdData(org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData) RelationQueryGenerator(org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator) Value(org.hibernate.mapping.Value) MiddleComponentData(org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData) ToOneIdMapper(org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper) OneAuditEntityQueryGenerator(org.hibernate.envers.internal.entities.mapper.relation.query.OneAuditEntityQueryGenerator) IndexedCollection(org.hibernate.mapping.IndexedCollection) MiddleStraightComponentMapper(org.hibernate.envers.internal.entities.mapper.relation.component.MiddleStraightComponentMapper) IdMappingData(org.hibernate.envers.internal.entities.IdMappingData)

Example 10 with Value

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

the class ResultSetMappingBinder method extractPropertyResults.

@SuppressWarnings("unchecked")
private static Map<String, String[]> extractPropertyResults(String alias, NativeQueryNonScalarRootReturn rtnSource, PersistentClass pc, HbmLocalMetadataBuildingContext context) {
    if (CollectionHelper.isEmpty(rtnSource.getReturnProperty())) {
        return null;
    }
    final HashMap results = new HashMap();
    List<JaxbHbmNativeQueryPropertyReturnType> propertyReturnSources = new ArrayList<JaxbHbmNativeQueryPropertyReturnType>();
    List<String> propertyNames = new ArrayList<String>();
    for (JaxbHbmNativeQueryPropertyReturnType propertyReturnSource : rtnSource.getReturnProperty()) {
        final int dotPosition = propertyReturnSource.getName().lastIndexOf('.');
        if (pc == null || dotPosition == -1) {
            propertyReturnSources.add(propertyReturnSource);
            propertyNames.add(propertyReturnSource.getName());
        } else {
            final String reducedName = propertyReturnSource.getName().substring(0, dotPosition);
            final Value value = pc.getRecursiveProperty(reducedName).getValue();
            Iterator parentPropItr;
            if (value instanceof Component) {
                final Component comp = (Component) value;
                parentPropItr = comp.getPropertyIterator();
            } else if (value instanceof ToOne) {
                final ToOne toOne = (ToOne) value;
                final PersistentClass referencedPc = context.getMetadataCollector().getEntityBinding(toOne.getReferencedEntityName());
                if (toOne.getReferencedPropertyName() != null) {
                    try {
                        parentPropItr = ((Component) referencedPc.getRecursiveProperty(toOne.getReferencedPropertyName()).getValue()).getPropertyIterator();
                    } catch (ClassCastException e) {
                        throw new MappingException("dotted notation reference neither a component nor a many/one to one", e, context.getOrigin());
                    }
                } else {
                    try {
                        if (referencedPc.getIdentifierMapper() == null) {
                            parentPropItr = ((Component) referencedPc.getIdentifierProperty().getValue()).getPropertyIterator();
                        } else {
                            parentPropItr = referencedPc.getIdentifierMapper().getPropertyIterator();
                        }
                    } catch (ClassCastException e) {
                        throw new MappingException("dotted notation reference neither a component nor a many/one to one", e, context.getOrigin());
                    }
                }
            } else {
                throw new MappingException("dotted notation reference neither a component nor a many/one to one", context.getOrigin());
            }
            boolean hasFollowers = false;
            List<String> followers = new ArrayList<String>();
            while (parentPropItr.hasNext()) {
                final Property parentProperty = (Property) parentPropItr.next();
                final String currentPropertyName = parentProperty.getName();
                final String currentName = reducedName + '.' + currentPropertyName;
                if (hasFollowers) {
                    followers.add(currentName);
                }
                if (propertyReturnSource.getName().equals(currentName)) {
                    hasFollowers = true;
                }
            }
            int index = propertyNames.size();
            for (String follower : followers) {
                int currentIndex = getIndexOfFirstMatchingProperty(propertyNames, follower);
                index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
            }
            propertyNames.add(index, propertyReturnSource.getName());
            propertyReturnSources.add(index, propertyReturnSource);
        }
    }
    Set<String> uniqueReturnProperty = new HashSet<String>();
    for (JaxbHbmNativeQueryPropertyReturnType propertyReturnBinding : propertyReturnSources) {
        final String name = propertyReturnBinding.getName();
        if ("class".equals(name)) {
            throw new MappingException("class is not a valid property name to use in a <return-property>, use <return-discriminator> instead", context.getOrigin());
        }
        //TODO: validate existing of property with the chosen name. (secondpass )
        ArrayList allResultColumns = extractResultColumns(propertyReturnBinding);
        if (allResultColumns.isEmpty()) {
            throw new MappingException(String.format(Locale.ENGLISH, "return-property [alias=%s, property=%s] must specify at least one column or return-column name", alias, propertyReturnBinding.getName()), context.getOrigin());
        }
        if (uniqueReturnProperty.contains(name)) {
            throw new MappingException(String.format(Locale.ENGLISH, "Duplicate return-property [alias=%s] : %s", alias, propertyReturnBinding.getName()), context.getOrigin());
        }
        uniqueReturnProperty.add(name);
        // the issue here is that for <return-join/> representing an entity collection,
        // the collection element values (the property values of the associated entity)
        // are represented as 'element.{propertyname}'.  Thus the StringHelper.root()
        // here puts everything under 'element' (which additionally has significant
        // meaning).  Probably what we need to do is to something like this instead:
        //      String root = StringHelper.root( name );
        //      String key = root; // by default
        //      if ( !root.equals( name ) ) {
        //	        // we had a dot
        //          if ( !root.equals( alias ) {
        //              // the root does not apply to the specific alias
        //              if ( "elements".equals( root ) {
        //                  // we specifically have a <return-join/> representing an entity collection
        //                  // and this <return-property/> is one of that entity's properties
        //                  key = name;
        //              }
        //          }
        //      }
        // but I am not clear enough on the intended purpose of this code block, especially
        // in relation to the "Reorder properties" code block above...
        //			String key = StringHelper.root( name );
        ArrayList intermediateResults = (ArrayList) results.get(name);
        if (intermediateResults == null) {
            results.put(name, allResultColumns);
        } else {
            intermediateResults.addAll(allResultColumns);
        }
    }
    for (Object o : results.entrySet()) {
        Map.Entry entry = (Map.Entry) o;
        if (entry.getValue() instanceof ArrayList) {
            ArrayList list = (ArrayList) entry.getValue();
            entry.setValue(list.toArray(new String[list.size()]));
        }
    }
    return results.isEmpty() ? Collections.EMPTY_MAP : results;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) JaxbHbmNativeQueryPropertyReturnType(org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryPropertyReturnType) MappingException(org.hibernate.boot.MappingException) Value(org.hibernate.mapping.Value) Iterator(java.util.Iterator) ToOne(org.hibernate.mapping.ToOne) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) HashMap(java.util.HashMap) Map(java.util.Map) PersistentClass(org.hibernate.mapping.PersistentClass) HashSet(java.util.HashSet)

Aggregations

Value (org.hibernate.mapping.Value)13 Component (org.hibernate.mapping.Component)8 Property (org.hibernate.mapping.Property)7 PersistentClass (org.hibernate.mapping.PersistentClass)6 SimpleValue (org.hibernate.mapping.SimpleValue)5 Iterator (java.util.Iterator)4 Collection (org.hibernate.mapping.Collection)4 Column (org.hibernate.mapping.Column)4 ToOne (org.hibernate.mapping.ToOne)4 AnnotationException (org.hibernate.AnnotationException)3 AssertionFailure (org.hibernate.AssertionFailure)3 Ejb3JoinColumn (org.hibernate.cfg.Ejb3JoinColumn)3 DependantValue (org.hibernate.mapping.DependantValue)3 ManyToOne (org.hibernate.mapping.ManyToOne)3 OneToMany (org.hibernate.mapping.OneToMany)3 HashMap (java.util.HashMap)2 Map (java.util.Map)2 XProperty (org.hibernate.annotations.common.reflection.XProperty)2 Metadata (org.hibernate.boot.Metadata)2 MetadataSources (org.hibernate.boot.MetadataSources)2