org.hibernate.jpa.spi.NativeQueryTupleTransformer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
Hibernate's core ORM functionality
/*
* 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.jpa.spi;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.Tuple;
import javax.persistence.TupleElement;
import org.hibernate.HibernateException;
import org.hibernate.transform.BasicTransformerAdapter;
/**
* ResultTransformer adapter for handling Tuple results from Native queries
*
* @author Arnold Galovics
*/
public class NativeQueryTupleTransformer extends BasicTransformerAdapter {
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
return new NativeTupleImpl( tuple, aliases );
}
private static class NativeTupleElementImpl implements TupleElement {
private final Class javaType;
private final String alias;
public NativeTupleElementImpl(Class javaType, String alias) {
this.javaType = javaType;
this.alias = alias;
}
@Override
public Class getJavaType() {
return javaType;
}
@Override
public String getAlias() {
return alias;
}
}
private static class NativeTupleImpl implements Tuple {
private Object[] tuple;
private Map aliasToValue = new LinkedHashMap<>();
private Map aliasReferences = new LinkedHashMap<>();
public NativeTupleImpl(Object[] tuple, String[] aliases) {
if ( tuple == null ) {
throw new HibernateException( "Tuple must not be null" );
}
if ( aliases == null ) {
throw new HibernateException( "Aliases must not be null" );
}
if ( tuple.length != aliases.length ) {
throw new HibernateException( "Got different size of tuples and aliases" );
}
this.tuple = tuple;
for ( int i = 0; i < tuple.length; i++ ) {
aliasToValue.put( aliases[i], tuple[i] );
aliasReferences.put( aliases[i].toLowerCase(), aliases[i] );
}
}
@Override
public X get(String alias, Class type) {
final Object untyped = get( alias );
return ( untyped != null ) ? type.cast( untyped ) : null;
}
@Override
public Object get(String alias) {
final String aliasReference = aliasReferences.get( alias.toLowerCase() );
if ( aliasReference != null && aliasToValue.containsKey( aliasReference ) ) {
return aliasToValue.get( aliasReference );
}
throw new IllegalArgumentException( "Unknown alias [" + alias + "]" );
}
@Override
public X get(int i, Class type) {
final Object untyped = get( i );
return ( untyped != null ) ? type.cast( untyped ) : null;
}
@Override
public Object get(int i) {
if ( i < 0 ) {
throw new IllegalArgumentException( "requested tuple index must be greater than zero" );
}
if ( i >= aliasToValue.size() ) {
throw new IllegalArgumentException( "requested tuple index exceeds actual tuple size" );
}
return tuple[i];
}
@Override
public Object[] toArray() {
// todo : make a copy?
return tuple;
}
@Override
public List> getElements() {
List> elements = new ArrayList<>( aliasToValue.size() );
for ( Map.Entry entry : aliasToValue.entrySet() ) {
elements.add( new NativeTupleElementImpl<>( getValueClass( entry.getValue() ), entry.getKey() ) );
}
return elements;
}
private Class getValueClass(Object value) {
Class valueClass = Object.class;
if ( value != null ) {
valueClass = value.getClass();
}
return valueClass;
}
@Override
public X get(TupleElement tupleElement) {
return get( tupleElement.getAlias(), tupleElement.getJavaType() );
}
}
}