Search in sources :

Example 1 with EntityResult

use of javax.persistence.EntityResult in project hibernate-orm by hibernate.

the class JPAOverriddenAnnotationReader method buildSqlResultsetMappings.

public static List<SqlResultSetMapping> buildSqlResultsetMappings(Element element, XMLContext.Default defaults, ClassLoaderAccess classLoaderAccess) {
    final List<SqlResultSetMapping> builtResultSetMappings = new ArrayList<>();
    if (element == null) {
        return builtResultSetMappings;
    }
    // iterate over each <sql-result-set-mapping/> element
    for (Object resultSetMappingElementObject : element.elements("sql-result-set-mapping")) {
        final Element resultSetMappingElement = (Element) resultSetMappingElementObject;
        final AnnotationDescriptor resultSetMappingAnnotation = new AnnotationDescriptor(SqlResultSetMapping.class);
        copyStringAttribute(resultSetMappingAnnotation, resultSetMappingElement, "name", true);
        // iterate over the <sql-result-set-mapping/> sub-elements, which should include:
        // * <entity-result/>
        // * <column-result/>
        // * <constructor-result/>
        List<EntityResult> entityResultAnnotations = null;
        List<ColumnResult> columnResultAnnotations = null;
        List<ConstructorResult> constructorResultAnnotations = null;
        for (Object resultElementObject : resultSetMappingElement.elements()) {
            final Element resultElement = (Element) resultElementObject;
            if ("entity-result".equals(resultElement.getName())) {
                if (entityResultAnnotations == null) {
                    entityResultAnnotations = new ArrayList<>();
                }
                // process the <entity-result/>
                entityResultAnnotations.add(buildEntityResult(resultElement, defaults, classLoaderAccess));
            } else if ("column-result".equals(resultElement.getName())) {
                if (columnResultAnnotations == null) {
                    columnResultAnnotations = new ArrayList<>();
                }
                columnResultAnnotations.add(buildColumnResult(resultElement, defaults, classLoaderAccess));
            } else if ("constructor-result".equals(resultElement.getName())) {
                if (constructorResultAnnotations == null) {
                    constructorResultAnnotations = new ArrayList<>();
                }
                constructorResultAnnotations.add(buildConstructorResult(resultElement, defaults, classLoaderAccess));
            } else {
                // most likely the <result-class/> this code used to handle.  I have left the code here,
                // but commented it out for now.  I'll just log a warning for now.
                LOG.debug("Encountered unrecognized sql-result-set-mapping sub-element : " + resultElement.getName());
            // String clazzName = subelement.attributeValue( "result-class" );
            // if ( StringHelper.isNotEmpty( clazzName ) ) {
            // Class clazz;
            // try {
            // clazz = ReflectHelper.classForName(
            // XMLContext.buildSafeClassName( clazzName, defaults ),
            // JPAOverriddenAnnotationReader.class
            // );
            // }
            // catch ( ClassNotFoundException e ) {
            // throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
            // }
            // ann.setValue( "resultClass", clazz );
            // }
            }
        }
        if (entityResultAnnotations != null && !entityResultAnnotations.isEmpty()) {
            resultSetMappingAnnotation.setValue("entities", entityResultAnnotations.toArray(new EntityResult[entityResultAnnotations.size()]));
        }
        if (columnResultAnnotations != null && !columnResultAnnotations.isEmpty()) {
            resultSetMappingAnnotation.setValue("columns", columnResultAnnotations.toArray(new ColumnResult[columnResultAnnotations.size()]));
        }
        if (constructorResultAnnotations != null && !constructorResultAnnotations.isEmpty()) {
            resultSetMappingAnnotation.setValue("classes", constructorResultAnnotations.toArray(new ConstructorResult[constructorResultAnnotations.size()]));
        }
        // this was part of the old code too, but could never figure out what it is supposed to do...
        // copyStringAttribute( ann, subelement, "result-set-mapping", false );
        builtResultSetMappings.add(AnnotationFactory.create(resultSetMappingAnnotation));
    }
    return builtResultSetMappings;
}
Also used : AnnotationDescriptor(org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor) AnnotatedElement(java.lang.reflect.AnnotatedElement) Element(org.dom4j.Element) ArrayList(java.util.ArrayList) EntityResult(javax.persistence.EntityResult) ConstructorResult(javax.persistence.ConstructorResult) ColumnResult(javax.persistence.ColumnResult) AccessibleObject(java.lang.reflect.AccessibleObject) SqlResultSetMapping(javax.persistence.SqlResultSetMapping)

Example 2 with EntityResult

use of javax.persistence.EntityResult in project hibernate-orm by hibernate.

the class ResultsetMappingSecondPass method doSecondPass.

@Override
public void doSecondPass(Map persistentClasses) throws MappingException {
    // TODO add parameters checkings
    if (ann == null)
        return;
    ResultSetMappingDefinition definition = new ResultSetMappingDefinition(ann.name());
    LOG.debugf("Binding result set mapping: %s", definition.getName());
    int entityAliasIndex = 0;
    for (EntityResult entity : ann.entities()) {
        // TODO parameterize lock mode?
        List<FieldResult> properties = new ArrayList<FieldResult>();
        List<String> propertyNames = new ArrayList<String>();
        for (FieldResult field : entity.fields()) {
            // use an ArrayList cause we might have several columns per root property
            String name = field.name();
            if (name.indexOf('.') == -1) {
                // regular property
                properties.add(field);
                propertyNames.add(name);
            } else {
                /**
                 * Reorder properties
                 * 1. get the parent property
                 * 2. list all the properties following the expected one in the parent property
                 * 3. calculate the lowest index and insert the property
                 */
                PersistentClass pc = context.getMetadataCollector().getEntityBinding(entity.entityClass().getName());
                if (pc == null) {
                    throw new MappingException(String.format(Locale.ENGLISH, "Could not resolve entity [%s] referenced in SqlResultSetMapping [%s]", entity.entityClass().getName(), ann.name()));
                }
                int dotIndex = name.lastIndexOf('.');
                String reducedName = name.substring(0, dotIndex);
                Iterator parentPropItr = getSubPropertyIterator(pc, reducedName);
                List<String> followers = getFollowers(parentPropItr, reducedName, name);
                int index = propertyNames.size();
                for (String follower : followers) {
                    int currentIndex = getIndexOfFirstMatchingProperty(propertyNames, follower);
                    index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
                }
                propertyNames.add(index, name);
                properties.add(index, field);
            }
        }
        Set<String> uniqueReturnProperty = new HashSet<String>();
        Map<String, ArrayList<String>> propertyResultsTmp = new HashMap<String, ArrayList<String>>();
        for (Object property : properties) {
            final FieldResult propertyresult = (FieldResult) property;
            final String name = propertyresult.name();
            if ("class".equals(name)) {
                throw new MappingException("class is not a valid property name to use in a @FieldResult, use @Entity(discriminatorColumn) instead");
            }
            if (uniqueReturnProperty.contains(name)) {
                throw new MappingException("duplicate @FieldResult for property " + name + " on @Entity " + entity.entityClass().getName() + " in " + ann.name());
            }
            uniqueReturnProperty.add(name);
            final String quotingNormalizedColumnName = normalizeColumnQuoting(propertyresult.column());
            String key = StringHelper.root(name);
            ArrayList<String> intermediateResults = propertyResultsTmp.get(key);
            if (intermediateResults == null) {
                intermediateResults = new ArrayList<String>();
                propertyResultsTmp.put(key, intermediateResults);
            }
            intermediateResults.add(quotingNormalizedColumnName);
        }
        Map<String, String[]> propertyResults = new HashMap<String, String[]>();
        for (Map.Entry<String, ArrayList<String>> entry : propertyResultsTmp.entrySet()) {
            propertyResults.put(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));
        }
        if (!BinderHelper.isEmptyAnnotationValue(entity.discriminatorColumn())) {
            final String quotingNormalizedName = normalizeColumnQuoting(entity.discriminatorColumn());
            propertyResults.put("class", new String[] { quotingNormalizedName });
        }
        if (propertyResults.isEmpty()) {
            propertyResults = java.util.Collections.emptyMap();
        }
        NativeSQLQueryRootReturn result = new NativeSQLQueryRootReturn("alias" + entityAliasIndex++, entity.entityClass().getName(), propertyResults, LockMode.READ);
        definition.addQueryReturn(result);
    }
    for (ColumnResult column : ann.columns()) {
        definition.addQueryReturn(new NativeSQLQueryScalarReturn(normalizeColumnQuoting(column.name()), column.type() != null ? context.getMetadataCollector().getTypeResolver().heuristicType(column.type().getName()) : null));
    }
    for (ConstructorResult constructorResult : ann.classes()) {
        List<NativeSQLQueryScalarReturn> columnReturns = new ArrayList<NativeSQLQueryScalarReturn>();
        for (ColumnResult columnResult : constructorResult.columns()) {
            columnReturns.add(new NativeSQLQueryScalarReturn(normalizeColumnQuoting(columnResult.name()), columnResult.type() != null ? context.getMetadataCollector().getTypeResolver().heuristicType(columnResult.type().getName()) : null));
        }
        definition.addQueryReturn(new NativeSQLQueryConstructorReturn(constructorResult.targetClass(), columnReturns));
    }
    if (isDefault) {
        context.getMetadataCollector().addDefaultResultSetMapping(definition);
    } else {
        context.getMetadataCollector().addResultSetMapping(definition);
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) EntityResult(javax.persistence.EntityResult) NativeSQLQueryRootReturn(org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn) MappingException(org.hibernate.MappingException) NativeSQLQueryConstructorReturn(org.hibernate.engine.query.spi.sql.NativeSQLQueryConstructorReturn) Iterator(java.util.Iterator) ColumnResult(javax.persistence.ColumnResult) FieldResult(javax.persistence.FieldResult) PersistentClass(org.hibernate.mapping.PersistentClass) HashSet(java.util.HashSet) ConstructorResult(javax.persistence.ConstructorResult) HashMap(java.util.HashMap) Map(java.util.Map) ResultSetMappingDefinition(org.hibernate.engine.ResultSetMappingDefinition) NativeSQLQueryScalarReturn(org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn)

Aggregations

ArrayList (java.util.ArrayList)2 ColumnResult (javax.persistence.ColumnResult)2 ConstructorResult (javax.persistence.ConstructorResult)2 EntityResult (javax.persistence.EntityResult)2 AccessibleObject (java.lang.reflect.AccessibleObject)1 AnnotatedElement (java.lang.reflect.AnnotatedElement)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 Map (java.util.Map)1 FieldResult (javax.persistence.FieldResult)1 SqlResultSetMapping (javax.persistence.SqlResultSetMapping)1 Element (org.dom4j.Element)1 MappingException (org.hibernate.MappingException)1 AnnotationDescriptor (org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor)1 ResultSetMappingDefinition (org.hibernate.engine.ResultSetMappingDefinition)1 NativeSQLQueryConstructorReturn (org.hibernate.engine.query.spi.sql.NativeSQLQueryConstructorReturn)1 NativeSQLQueryRootReturn (org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn)1 NativeSQLQueryScalarReturn (org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn)1 PersistentClass (org.hibernate.mapping.PersistentClass)1