alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (StandardAnsiSqlAggregationFunctions.java)

This example Hibernate source code file (StandardAnsiSqlAggregationFunctions.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

avgfunction, countfunction, instance, instance, jdbc, maxfunction, minfunction, queryexception, queryexception, sessionfactoryimplementor, sql, standardsqlfunction, standardsqlfunction, string, string, sumfunction, util

The Hibernate StandardAnsiSqlAggregationFunctions.java source code

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2010, Red Hat Inc. 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 Inc.
 *
 * 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.dialect.function;

import java.sql.Types;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;

/**
 * Centralized definition of standard ANSI SQL aggregation functions
 *
 * @author Steve Ebersole
 */
public class StandardAnsiSqlAggregationFunctions {
	/**
	 * Definition of a standard ANSI SQL compliant <tt>COUNT function
	 */
	public static class CountFunction extends StandardSQLFunction {
		public static final CountFunction INSTANCE = new CountFunction();

		public CountFunction() {
			super( "count", StandardBasicTypes.LONG );
		}

		@Override
		public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) {
			if ( arguments.size() > 1 ) {
				if ( "distinct".equalsIgnoreCase( arguments.get( 0 ).toString() ) ) {
					return renderCountDistinct( arguments );
				}
			}
			return super.render( firstArgumentType, arguments, factory );
		}

		private String renderCountDistinct(List arguments) {
			StringBuffer buffer = new StringBuffer();
			buffer.append( "count(distinct " );
			String sep = "";
			Iterator itr = arguments.iterator();
			itr.next(); // intentionally skip first
			while ( itr.hasNext() ) {
				buffer.append( sep )
						.append( itr.next() );
				sep = ", ";
			}
			return buffer.append( ")" ).toString();
		}
	}


	/**
	 * Definition of a standard ANSI SQL compliant <tt>AVG function
	 */
	public static class AvgFunction extends StandardSQLFunction {
		public static final AvgFunction INSTANCE = new AvgFunction();

		public AvgFunction() {
			super( "avg", StandardBasicTypes.DOUBLE );
		}

		@Override
		public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) throws QueryException {
			int jdbcTypeCode = determineJdbcTypeCode( firstArgumentType, factory );
			return render( jdbcTypeCode, arguments.get(0).toString(), factory );
		}

		protected final int determineJdbcTypeCode(Type firstArgumentType, SessionFactoryImplementor factory) throws QueryException {
			try {
				final int[] jdbcTypeCodes = firstArgumentType.sqlTypes( factory );
				if ( jdbcTypeCodes.length != 1 ) {
					throw new QueryException( "multiple-column type in avg()" );
				}
				return jdbcTypeCodes[0];
			}
			catch ( MappingException me ) {
				throw new QueryException( me );
			}
		}

		protected String render(int firstArgumentJdbcType, String argument, SessionFactoryImplementor factory) {
			return "avg(" + renderArgument( argument, firstArgumentJdbcType ) + ")";
		}

		protected String renderArgument(String argument, int firstArgumentJdbcType) {
			return argument;
		}
	}


	public static class MaxFunction extends StandardSQLFunction {
		public static final MaxFunction INSTANCE = new MaxFunction();

		public MaxFunction() {
			super( "max" );
		}
	}

	public static class MinFunction extends StandardSQLFunction {
		public static final MinFunction INSTANCE = new MinFunction();

		public MinFunction() {
			super( "min" );
		}
	}


	public static class SumFunction extends StandardSQLFunction {
		public static final SumFunction INSTANCE = new SumFunction();

		public SumFunction() {
			super( "sum" );
		}

		protected final int determineJdbcTypeCode(Type type, Mapping mapping) throws QueryException {
			try {
				final int[] jdbcTypeCodes = type.sqlTypes( mapping );
				if ( jdbcTypeCodes.length != 1 ) {
					throw new QueryException( "multiple-column type in sum()" );
				}
				return jdbcTypeCodes[0];
			}
			catch ( MappingException me ) {
				throw new QueryException( me );
			}
		}

		public Type getReturnType(Type firstArgumentType, Mapping mapping) {
			final int jdbcType = determineJdbcTypeCode( firstArgumentType, mapping );

			// First allow the actual type to control the return value; the underlying sqltype could
			// actually be different
			if ( firstArgumentType == StandardBasicTypes.BIG_INTEGER ) {
				return StandardBasicTypes.BIG_INTEGER;
			}
			else if ( firstArgumentType == StandardBasicTypes.BIG_DECIMAL ) {
				return StandardBasicTypes.BIG_DECIMAL;
			}
			else if ( firstArgumentType == StandardBasicTypes.LONG
					|| firstArgumentType == StandardBasicTypes.SHORT
					|| firstArgumentType == StandardBasicTypes.INTEGER ) {
				return StandardBasicTypes.LONG;
			}
			else if ( firstArgumentType == StandardBasicTypes.FLOAT || firstArgumentType == StandardBasicTypes.DOUBLE)  {
				return StandardBasicTypes.DOUBLE;
			}

			// finally use the jdbcType if == on Hibernate types did not find a match.
			//
			//	IMPL NOTE : we do not match on Types.NUMERIC because it could be either, so we fall-through to the
			// 		first argument type
			if ( jdbcType == Types.FLOAT
					|| jdbcType == Types.DOUBLE
					|| jdbcType == Types.DECIMAL
					|| jdbcType == Types.REAL) {
				return StandardBasicTypes.DOUBLE;
			}
			else if ( jdbcType == Types.BIGINT
					|| jdbcType == Types.INTEGER
					|| jdbcType == Types.SMALLINT
					|| jdbcType == Types.TINYINT ) {
				return StandardBasicTypes.LONG;
			}

			// as a last resort, return the type of the first argument
			return firstArgumentType;
		}
	}

	public static void primeFunctionMap(Map<String, SQLFunction> functionMap) {
		functionMap.put( AvgFunction.INSTANCE.getName(), AvgFunction.INSTANCE );
		functionMap.put( CountFunction.INSTANCE.getName(), CountFunction.INSTANCE );
		functionMap.put( MaxFunction.INSTANCE.getName(), MaxFunction.INSTANCE );
		functionMap.put( MinFunction.INSTANCE.getName(), MinFunction.INSTANCE );
		functionMap.put( SumFunction.INSTANCE.getName(), SumFunction.INSTANCE );
	}
}

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate StandardAnsiSqlAggregationFunctions.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.