/*
 * 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.transform;

import java.util.Arrays;

import org.hibernate.HibernateException;
import org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl;
import org.hibernate.property.access.internal.PropertyAccessStrategyChainedImpl;
import org.hibernate.property.access.internal.PropertyAccessStrategyFieldImpl;
import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl;
import org.hibernate.property.access.spi.Setter;

Result transformer that allows to transform a result to a user specified class which will be populated via setter methods or fields matching the alias names.

List resultWithAliasedBean = s.createCriteria(Enrolment.class)
			.createAlias("student", "st")
			.createAlias("course", "co")
			.setProjection( Projections.projectionList()
					.add( Projections.property("co.description"), "courseDescription" )
			)
			.setResultTransformer( new AliasToBeanResultTransformer(StudentDTO.class) )
			.list();

StudentDTO dto = (StudentDTO)resultWithAliasedBean.get(0);
Author:max
/** * Result transformer that allows to transform a result to * a user specified class which will be populated via setter * methods or fields matching the alias names. * <p/> * <pre> * List resultWithAliasedBean = s.createCriteria(Enrolment.class) * .createAlias("student", "st") * .createAlias("course", "co") * .setProjection( Projections.projectionList() * .add( Projections.property("co.description"), "courseDescription" ) * ) * .setResultTransformer( new AliasToBeanResultTransformer(StudentDTO.class) ) * .list(); * <p/> * StudentDTO dto = (StudentDTO)resultWithAliasedBean.get(0); * </pre> * * @author max */
public class AliasToBeanResultTransformer extends AliasedTupleSubsetResultTransformer { // IMPL NOTE : due to the delayed population of setters (setters cached // for performance), we really cannot properly define equality for // this transformer private final Class resultClass; private boolean isInitialized; private String[] aliases; private Setter[] setters; public AliasToBeanResultTransformer(Class resultClass) { if ( resultClass == null ) { throw new IllegalArgumentException( "resultClass cannot be null" ); } isInitialized = false; this.resultClass = resultClass; } @Override public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) { return false; } @Override public Object transformTuple(Object[] tuple, String[] aliases) { Object result; try { if ( ! isInitialized ) { initialize( aliases ); } else { check( aliases ); } result = resultClass.newInstance(); for ( int i = 0; i < aliases.length; i++ ) { if ( setters[i] != null ) { setters[i].set( result, tuple[i], null ); } } } catch ( InstantiationException e ) { throw new HibernateException( "Could not instantiate resultclass: " + resultClass.getName() ); } catch ( IllegalAccessException e ) { throw new HibernateException( "Could not instantiate resultclass: " + resultClass.getName() ); } return result; } private void initialize(String[] aliases) { PropertyAccessStrategyChainedImpl propertyAccessStrategy = new PropertyAccessStrategyChainedImpl( PropertyAccessStrategyBasicImpl.INSTANCE, PropertyAccessStrategyFieldImpl.INSTANCE, PropertyAccessStrategyMapImpl.INSTANCE ); this.aliases = new String[ aliases.length ]; setters = new Setter[ aliases.length ]; for ( int i = 0; i < aliases.length; i++ ) { String alias = aliases[ i ]; if ( alias != null ) { this.aliases[ i ] = alias; setters[ i ] = propertyAccessStrategy.buildPropertyAccess( resultClass, alias ).getSetter(); } } isInitialized = true; } private void check(String[] aliases) { if ( ! Arrays.equals( aliases, this.aliases ) ) { throw new IllegalStateException( "aliases are different from what is cached; aliases=" + Arrays.asList( aliases ) + " cached=" + Arrays.asList( this.aliases ) ); } } @Override public boolean equals(Object o) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } AliasToBeanResultTransformer that = ( AliasToBeanResultTransformer ) o; if ( ! resultClass.equals( that.resultClass ) ) { return false; } if ( ! Arrays.equals( aliases, that.aliases ) ) { return false; } return true; } @Override public int hashCode() { int result = resultClass.hashCode(); result = 31 * result + ( aliases != null ? Arrays.hashCode( aliases ) : 0 ); return result; } }