Java tutorial
/* * 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. * <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; } }