All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.cfg.annotations.ResultsetMappingSecondPass Maven / Gradle / Ivy

There is a newer version: 7.0.0.Beta1
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate.cfg.annotations;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.persistence.SqlResultSetMapping;

import org.hibernate.MappingException;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.cfg.QuerySecondPass;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value;

/**
 * @author Emmanuel Bernard
 */
public class ResultsetMappingSecondPass implements QuerySecondPass {
	private static final CoreMessageLogger LOG = CoreLogging.messageLogger( ResultsetMappingSecondPass.class );

	private final SqlResultSetMapping ann;
	private final MetadataBuildingContext context;
	private final boolean isDefault;

	public ResultsetMappingSecondPass(SqlResultSetMapping ann, MetadataBuildingContext context, boolean isDefault) {
		this.ann = ann;
		this.context = context;
		this.isDefault = isDefault;
	}

	@Override
	public void doSecondPass(Map persistentClasses) throws MappingException {
		if ( ann == null ) {
			return;
		}

		final SqlResultSetMappingDefinition mappingDefinition = SqlResultSetMappingDefinition.from( ann, context );

		if ( isDefault ) {
			context.getMetadataCollector().addDefaultResultSetMapping( mappingDefinition );
		}
		else {
			context.getMetadataCollector().addResultSetMapping( mappingDefinition );
		}

		//TODO add parameters checkings
//		if ( ann == null ) return;
//		ResultSetMappingDescriptor definition = new ResultSetMappingDescriptor( ann.name() );
//		LOG.debugf( "Binding result set mapping: %s", definition.getName() );
//
//		int entityAliasIndex = 0;
//
//		for (EntityResult entity : ann.entities()) {
//			//TODO parameterize lock mode?
//			List properties = new ArrayList();
//			List propertyNames = new ArrayList();
//			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 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 uniqueReturnProperty = new HashSet();
//			Map> propertyResultsTmp = new HashMap>();
//			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 intermediateResults = propertyResultsTmp.get( key );
//				if ( intermediateResults == null ) {
//					intermediateResults = new ArrayList();
//					propertyResultsTmp.put( key, intermediateResults );
//				}
//				intermediateResults.add( quotingNormalizedColumnName );
//			}
//
//			Map propertyResults = new HashMap();
//			for ( Map.Entry> 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 columnReturns = new ArrayList();
//			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 );
//		}
	}

	private String normalizeColumnQuoting(String name) {
		return context.getMetadataCollector().getDatabase().toIdentifier( name ).render();
	}

	private List getFollowers(Iterator parentPropIter, String reducedName, String name) {
		boolean hasFollowers = false;
		List followers = new ArrayList();
		while ( parentPropIter.hasNext() ) {
			String currentPropertyName = ( (Property) parentPropIter.next() ).getName();
			String currentName = reducedName + '.' + currentPropertyName;
			if ( hasFollowers ) {
				followers.add( currentName );
			}
			if ( name.equals( currentName ) ) {
				hasFollowers = true;
			}
		}
		return followers;
	}

	private Iterator getSubPropertyIterator(PersistentClass pc, String reducedName) {
		Value value = pc.getRecursiveProperty( reducedName ).getValue();
		Iterator parentPropIter;
		if ( value instanceof Component ) {
			Component comp = (Component) value;
			parentPropIter = comp.getPropertyIterator();
		}
		else if ( value instanceof ToOne ) {
			ToOne toOne = (ToOne) value;
			PersistentClass referencedPc = context.getMetadataCollector().getEntityBinding( toOne.getReferencedEntityName() );
			if ( toOne.getReferencedPropertyName() != null ) {
				try {
					parentPropIter = ( (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
					);
				}
			}
			else {
				try {
					if ( referencedPc.getIdentifierMapper() == null ) {
						parentPropIter = ( (Component) referencedPc.getIdentifierProperty()
								.getValue() ).getPropertyIterator();
					}
					else {
						parentPropIter = referencedPc.getIdentifierMapper().getPropertyIterator();
					}
				}
				catch (ClassCastException e) {
					throw new MappingException(
							"dotted notation reference neither a component nor a many/one to one", e
					);
				}
			}
		}
		else {
			throw new MappingException( "dotted notation reference neither a component nor a many/one to one" );
		}
		return parentPropIter;
	}

	private static int getIndexOfFirstMatchingProperty(List propertyNames, String follower) {
		int propertySize = propertyNames.size();
		for (int propIndex = 0; propIndex < propertySize; propIndex++) {
			if ( ( (String) propertyNames.get( propIndex ) ).startsWith( follower ) ) {
				return propIndex;
			}
		}
		return -1;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy