/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Middleware LLC.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 *
 */
package org.hibernate.transform;
import java.util.Arrays;

import org.hibernate.HibernateException;
import org.hibernate.property.ChainedPropertyAccessor;
import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.PropertyAccessorFactory;
import org.hibernate.property.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) { PropertyAccessor propertyAccessor = new ChainedPropertyAccessor( new PropertyAccessor[] { PropertyAccessorFactory.getPropertyAccessor( resultClass, null ), PropertyAccessorFactory.getPropertyAccessor( "field" ) } ); 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 ] = propertyAccessor.getSetter( resultClass, alias ); } } 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; } }