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

Hibernate example source code file (CriteriaQueryTranslator.java)

This example Hibernate source code file (CriteriaQueryTranslator.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

criteria, criteria, criteriainfoprovider, criteriainfoprovider, hibernateexception, hibernateexception, iterator, map, object, queryexception, string, string, type, typedvalue, util

The Hibernate CriteriaQueryTranslator.java source code

/*
 * 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.loader.criteria;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.EnhancedProjection;
import org.hibernate.criterion.Projection;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.TypedValue;
import org.hibernate.hql.internal.ast.util.SessionFactoryHelper;
import org.hibernate.internal.CriteriaImpl;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.persister.entity.Loadable;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.sql.JoinType;
import org.hibernate.type.AssociationType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.StringRepresentableType;
import org.hibernate.type.Type;
import org.hibernate.internal.util.StringHelper;

/**
 * @author Gavin King
 */
public class CriteriaQueryTranslator implements CriteriaQuery {

	public static final String ROOT_SQL_ALIAS = Criteria.ROOT_ALIAS + '_';

	private CriteriaQuery outerQueryTranslator;

	private final CriteriaImpl rootCriteria;
	private final String rootEntityName;
	private final String rootSQLAlias;
	private int aliasCount = 0;

	private final Map /* <Criteria, CriteriaInfoProvider> */ criteriaInfoMap = new LinkedHashMap();
	private final Map /* <String, CriteriaInfoProvider> */ nameCriteriaInfoMap = new LinkedHashMap();
	private final Map criteriaSQLAliasMap = new HashMap();
	private final Map aliasCriteriaMap = new HashMap();
	private final Map associationPathCriteriaMap = new LinkedHashMap();
	private final Map<String,JoinType> associationPathJoinTypesMap = new LinkedHashMap();
	private final Map withClauseMap = new HashMap();
	
	private final SessionFactoryImplementor sessionFactory;
	private final SessionFactoryHelper helper;

	public CriteriaQueryTranslator(
			final SessionFactoryImplementor factory,
	        final CriteriaImpl criteria,
	        final String rootEntityName,
	        final String rootSQLAlias,
	        CriteriaQuery outerQuery) throws HibernateException {
		this( factory, criteria, rootEntityName, rootSQLAlias );
		outerQueryTranslator = outerQuery;
	}

	public CriteriaQueryTranslator(
			final SessionFactoryImplementor factory,
	        final CriteriaImpl criteria,
	        final String rootEntityName,
	        final String rootSQLAlias) throws HibernateException {
		this.rootCriteria = criteria;
		this.rootEntityName = rootEntityName;
		this.sessionFactory = factory;
		this.rootSQLAlias = rootSQLAlias;
		this.helper = new SessionFactoryHelper(factory);
		createAliasCriteriaMap();
		createAssociationPathCriteriaMap();
		createCriteriaEntityNameMap();
		createCriteriaSQLAliasMap();
	}

	public String generateSQLAlias() {
		return StringHelper.generateAlias( Criteria.ROOT_ALIAS, aliasCount ) + '_';
	}

	public String getRootSQLALias() {
		return rootSQLAlias;
	}

	private Criteria getAliasedCriteria(String alias) {
		return ( Criteria ) aliasCriteriaMap.get( alias );
	}

	public boolean isJoin(String path) {
		return associationPathCriteriaMap.containsKey( path );
	}

	public JoinType getJoinType(String path) {
		JoinType result = associationPathJoinTypesMap.get( path );
		return ( result == null ? JoinType.INNER_JOIN : result );
	}

	public Criteria getCriteria(String path) {
		return ( Criteria ) associationPathCriteriaMap.get( path );
	}

	public Set getQuerySpaces() {
		Set result = new HashSet();
		Iterator iter = criteriaInfoMap.values().iterator();
		while ( iter.hasNext() ) {
			CriteriaInfoProvider info = ( CriteriaInfoProvider )iter.next();
			result.addAll( Arrays.asList( info.getSpaces() ) );
		}
		return result;
	}

	private void createAliasCriteriaMap() {
		aliasCriteriaMap.put( rootCriteria.getAlias(), rootCriteria );
		Iterator iter = rootCriteria.iterateSubcriteria();
		while ( iter.hasNext() ) {
			Criteria subcriteria = ( Criteria ) iter.next();
			if ( subcriteria.getAlias() != null ) {
				Object old = aliasCriteriaMap.put( subcriteria.getAlias(), subcriteria );
				if ( old != null ) {
					throw new QueryException( "duplicate alias: " + subcriteria.getAlias() );
				}
			}
		}
	}

	private void createAssociationPathCriteriaMap() {
		Iterator iter = rootCriteria.iterateSubcriteria();
		while ( iter.hasNext() ) {
			CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) iter.next();
			String wholeAssociationPath = getWholeAssociationPath( crit );
			Object old = associationPathCriteriaMap.put( wholeAssociationPath, crit );
			if ( old != null ) {
				throw new QueryException( "duplicate association path: " + wholeAssociationPath );
			}
			JoinType joinType = crit.getJoinType();
			old = associationPathJoinTypesMap.put( wholeAssociationPath, joinType );
			if ( old != null ) {
				// TODO : not so sure this is needed...
				throw new QueryException( "duplicate association path: " + wholeAssociationPath );
			}
			if ( crit.getWithClause() != null )
			{
				this.withClauseMap.put(wholeAssociationPath, crit.getWithClause());
			}
		}
	}

	private String getWholeAssociationPath(CriteriaImpl.Subcriteria subcriteria) {
		String path = subcriteria.getPath();

		// some messy, complex stuff here, since createCriteria() can take an
		// aliased path, or a path rooted at the creating criteria instance
		Criteria parent = null;
		if ( path.indexOf( '.' ) > 0 ) {
			// if it is a compound path
			String testAlias = StringHelper.root( path );
			if ( !testAlias.equals( subcriteria.getAlias() ) ) {
				// and the qualifier is not the alias of this criteria
				//      -> check to see if we belong to some criteria other
				//          than the one that created us
				parent = ( Criteria ) aliasCriteriaMap.get( testAlias );
			}
		}
		if ( parent == null ) {
			// otherwise assume the parent is the the criteria that created us
			parent = subcriteria.getParent();
		}
		else {
			path = StringHelper.unroot( path );
		}

		if ( parent.equals( rootCriteria ) ) {
			// if its the root criteria, we are done
			return path;
		}
		else {
			// otherwise, recurse
			return getWholeAssociationPath( ( CriteriaImpl.Subcriteria ) parent ) + '.' + path;
		}
	}

	private void createCriteriaEntityNameMap() {
		// initialize the rootProvider first
		CriteriaInfoProvider rootProvider = new EntityCriteriaInfoProvider(( Queryable ) sessionFactory.getEntityPersister( rootEntityName ) );
		criteriaInfoMap.put( rootCriteria, rootProvider);
		nameCriteriaInfoMap.put ( rootProvider.getName(), rootProvider );

		Iterator iter = associationPathCriteriaMap.entrySet().iterator();
		while ( iter.hasNext() ) {
			Map.Entry me = ( Map.Entry ) iter.next();
			CriteriaInfoProvider info = getPathInfo((String)me.getKey());

			criteriaInfoMap.put(
					me.getValue(), //the criteria instance
					info
			);

			nameCriteriaInfoMap.put( info.getName(), info );
		}
	}


	private CriteriaInfoProvider getPathInfo(String path) {
		StringTokenizer tokens = new StringTokenizer( path, "." );
		String componentPath = "";

		// start with the 'rootProvider'
		CriteriaInfoProvider provider = ( CriteriaInfoProvider )nameCriteriaInfoMap.get( rootEntityName );

		while ( tokens.hasMoreTokens() ) {
			componentPath += tokens.nextToken();
			Type type = provider.getType( componentPath );
			if ( type.isAssociationType() ) {
				// CollectionTypes are always also AssociationTypes - but there's not always an associated entity...
				AssociationType atype = ( AssociationType ) type;
				CollectionType ctype = type.isCollectionType() ? (CollectionType)type : null;
				Type elementType = (ctype != null) ? ctype.getElementType( sessionFactory ) : null;
				// is the association a collection of components or value-types? (i.e a colloction of valued types?)
				if ( ctype != null  && elementType.isComponentType() ) {
					provider = new ComponentCollectionCriteriaInfoProvider( helper.getCollectionPersister(ctype.getRole()) );
				}
				else if ( ctype != null && !elementType.isEntityType() ) {
					provider = new ScalarCollectionCriteriaInfoProvider( helper, ctype.getRole() );
				}
				else {
					provider = new EntityCriteriaInfoProvider(( Queryable ) sessionFactory.getEntityPersister(
											  atype.getAssociatedEntityName( sessionFactory )
											  ));
				}
				
				componentPath = "";
			}
			else if ( type.isComponentType() ) {
				if (!tokens.hasMoreTokens()) {
					throw new QueryException("Criteria objects cannot be created directly on components.  Create a criteria on owning entity and use a dotted property to access component property: "+path);
				} else {
					componentPath += '.';
				}
			}
			else {
				throw new QueryException( "not an association: " + componentPath );
			}
		}
		
		return provider;
	}

	public int getSQLAliasCount() {
		return criteriaSQLAliasMap.size();
	}

	private void createCriteriaSQLAliasMap() {
		int i = 0;
		Iterator criteriaIterator = criteriaInfoMap.entrySet().iterator();
		while ( criteriaIterator.hasNext() ) {
			Map.Entry me = ( Map.Entry ) criteriaIterator.next();
			Criteria crit = ( Criteria ) me.getKey();
			String alias = crit.getAlias();
			if ( alias == null ) {
				alias = (( CriteriaInfoProvider ) me.getValue()).getName(); // the entity name
			}
			criteriaSQLAliasMap.put( crit, StringHelper.generateAlias( alias, i++ ) );
		}
		criteriaSQLAliasMap.put( rootCriteria, rootSQLAlias );
	}

	public CriteriaImpl getRootCriteria() {
		return rootCriteria;
	}

	public QueryParameters getQueryParameters() {
		LockOptions lockOptions = new LockOptions();
		RowSelection selection = new RowSelection();
		selection.setFirstRow( rootCriteria.getFirstResult() );
		selection.setMaxRows( rootCriteria.getMaxResults() );
		selection.setTimeout( rootCriteria.getTimeout() );
		selection.setFetchSize( rootCriteria.getFetchSize() );

		Iterator iter = rootCriteria.getLockModes().entrySet().iterator();
		while ( iter.hasNext() ) {
			Map.Entry me = ( Map.Entry ) iter.next();
			final Criteria subcriteria = getAliasedCriteria( ( String ) me.getKey() );
			lockOptions.setAliasSpecificLockMode( getSQLAlias( subcriteria ), (LockMode)me.getValue() );
		}
		List values = new ArrayList();
		List types = new ArrayList();
		iter = rootCriteria.iterateSubcriteria();
		while ( iter.hasNext() ) {
			CriteriaImpl.Subcriteria subcriteria = ( CriteriaImpl.Subcriteria ) iter.next();
			LockMode lm = subcriteria.getLockMode();
			if ( lm != null ) {
				lockOptions.setAliasSpecificLockMode( getSQLAlias( subcriteria ), lm );
			}
			if ( subcriteria.getWithClause() != null )
			{
				TypedValue[] tv = subcriteria.getWithClause().getTypedValues( subcriteria, this );
				for ( int i = 0; i < tv.length; i++ ) {
					values.add( tv[i].getValue() );
					types.add( tv[i].getType() );
				}
			}
		}

		// Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering,
		// because the lock mode gathering loop now contains join clauses which can contain
		// parameter bindings (as in the HQL WITH clause).
		iter = rootCriteria.iterateExpressionEntries();
		while ( iter.hasNext() ) {
			CriteriaImpl.CriterionEntry ce = ( CriteriaImpl.CriterionEntry ) iter.next();
			TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this );
			for ( int i = 0; i < tv.length; i++ ) {
				values.add( tv[i].getValue() );
				types.add( tv[i].getType() );
			}
		}

		Object[] valueArray = values.toArray();
		Type[] typeArray = ArrayHelper.toTypeArray( types );
		return new QueryParameters(
				typeArray,
		        valueArray,
		        lockOptions,
		        selection,
		        rootCriteria.isReadOnlyInitialized(),
		        ( rootCriteria.isReadOnlyInitialized() ? rootCriteria.isReadOnly() : false ),
		        rootCriteria.getCacheable(),
		        rootCriteria.getCacheRegion(),
		        rootCriteria.getComment(),
		        rootCriteria.isLookupByNaturalKey(),
		        rootCriteria.getResultTransformer()
		);
	}

	public boolean hasProjection() {
		return rootCriteria.getProjection() != null;
	}

	public String getGroupBy() {
		if ( rootCriteria.getProjection().isGrouped() ) {
			return rootCriteria.getProjection()
					.toGroupSqlString( rootCriteria.getProjectionCriteria(), this );
		}
		else {
			return "";
		}
	}

	public String getSelect() {
		return rootCriteria.getProjection().toSqlString(
				rootCriteria.getProjectionCriteria(),
		        0,
		        this
		);
	}

	/* package-protected */
	Type getResultType(Criteria criteria) {
		return getFactory().getTypeResolver().getTypeFactory().manyToOne( getEntityName( criteria ) );
	}

	public Type[] getProjectedTypes() {
		return rootCriteria.getProjection().getTypes( rootCriteria, this );
	}

	public String[] getProjectedColumnAliases() {
		return rootCriteria.getProjection() instanceof EnhancedProjection ?
				( ( EnhancedProjection ) rootCriteria.getProjection() ).getColumnAliases( 0, rootCriteria, this ) :
				rootCriteria.getProjection().getColumnAliases( 0 );
	}

	public String[] getProjectedAliases() {
		return rootCriteria.getProjection().getAliases();
	}

	public String getWhereCondition() {
		StringBuffer condition = new StringBuffer( 30 );
		Iterator criterionIterator = rootCriteria.iterateExpressionEntries();
		while ( criterionIterator.hasNext() ) {
			CriteriaImpl.CriterionEntry entry = ( CriteriaImpl.CriterionEntry ) criterionIterator.next();
			String sqlString = entry.getCriterion().toSqlString( entry.getCriteria(), this );
			condition.append( sqlString );
			if ( criterionIterator.hasNext() ) {
				condition.append( " and " );
			}
		}
		return condition.toString();
	}

	public String getOrderBy() {
		StringBuffer orderBy = new StringBuffer( 30 );
		Iterator criterionIterator = rootCriteria.iterateOrderings();
		while ( criterionIterator.hasNext() ) {
			CriteriaImpl.OrderEntry oe = ( CriteriaImpl.OrderEntry ) criterionIterator.next();
			orderBy.append( oe.getOrder().toSqlString( oe.getCriteria(), this ) );
			if ( criterionIterator.hasNext() ) {
				orderBy.append( ", " );
			}
		}
		return orderBy.toString();
	}

	public SessionFactoryImplementor getFactory() {
		return sessionFactory;
	}

	public String getSQLAlias(Criteria criteria) {
		return ( String ) criteriaSQLAliasMap.get( criteria );
	}

	public String getEntityName(Criteria criteria) {
		return (( CriteriaInfoProvider ) criteriaInfoMap.get( criteria )).getName();
	}

	public String getColumn(Criteria criteria, String propertyName) {
		String[] cols = getColumns( propertyName, criteria );
		if ( cols.length != 1 ) {
			throw new QueryException( "property does not map to a single column: " + propertyName );
		}
		return cols[0];
	}

	/**
	 * Get the names of the columns constrained
	 * by this criterion.
	 */
	public String[] getColumnsUsingProjection(
			Criteria subcriteria,
	        String propertyName) throws HibernateException {

		//first look for a reference to a projection alias
		final Projection projection = rootCriteria.getProjection();
		String[] projectionColumns = null;
		if ( projection != null ) {
			projectionColumns = ( projection instanceof EnhancedProjection ?
					( ( EnhancedProjection ) projection ).getColumnAliases( propertyName, 0, rootCriteria, this ) :
					projection.getColumnAliases( propertyName, 0 )
			);
		}
		if ( projectionColumns == null ) {
			//it does not refer to an alias of a projection,
			//look for a property
			try {
				return getColumns( propertyName, subcriteria );
			}
			catch ( HibernateException he ) {
				//not found in inner query , try the outer query
				if ( outerQueryTranslator != null ) {
					return outerQueryTranslator.getColumnsUsingProjection( subcriteria, propertyName );
				}
				else {
					throw he;
				}
			}
		}
		else {
			//it refers to an alias of a projection
			return projectionColumns;
		}
	}

	public String[] getIdentifierColumns(Criteria subcriteria) {
		String[] idcols =
				( ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ) ).getIdentifierColumnNames();
		return StringHelper.qualify( getSQLAlias( subcriteria ), idcols );
	}

	public Type getIdentifierType(Criteria subcriteria) {
		return ( ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ) ).getIdentifierType();
	}

	public TypedValue getTypedIdentifierValue(Criteria subcriteria, Object value) {
		final Loadable loadable = ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) );
		return new TypedValue(
				loadable.getIdentifierType(),
		        value,
		        EntityMode.POJO
		);
	}

	public String[] getColumns(
			String propertyName,
	        Criteria subcriteria) throws HibernateException {
		return getPropertyMapping( getEntityName( subcriteria, propertyName ) )
				.toColumns(
						getSQLAlias( subcriteria, propertyName ),
				        getPropertyName( propertyName )
				);
	}

	/**
	 * Get the names of the columns mapped by a property path; if the
	 * property path is not found in subcriteria, try the "outer" query.
	 * Projection aliases are ignored.
	 */
	public String[] findColumns(String propertyName, Criteria subcriteria )
	throws HibernateException {
		try {
			return getColumns( propertyName, subcriteria );
		}
		catch ( HibernateException he ) {
			//not found in inner query, try the outer query
			if ( outerQueryTranslator != null ) {
				return outerQueryTranslator.findColumns( propertyName, subcriteria );
			}
			else {
				throw he;
			}
		}
	}

	public Type getTypeUsingProjection(Criteria subcriteria, String propertyName)
			throws HibernateException {

		//first look for a reference to a projection alias
		final Projection projection = rootCriteria.getProjection();
		Type[] projectionTypes = projection == null ?
		                         null :
		                         projection.getTypes( propertyName, subcriteria, this );

		if ( projectionTypes == null ) {
			try {
				//it does not refer to an alias of a projection,
				//look for a property
				return getType( subcriteria, propertyName );
			}
			catch ( HibernateException he ) {
				//not found in inner query , try the outer query
				if ( outerQueryTranslator != null ) {
					return outerQueryTranslator.getType( subcriteria, propertyName );
				}
				else {
					throw he;
				}
			}
		}
		else {
			if ( projectionTypes.length != 1 ) {
				//should never happen, i think
				throw new QueryException( "not a single-length projection: " + propertyName );
			}
			return projectionTypes[0];
		}
	}

	public Type getType(Criteria subcriteria, String propertyName)
			throws HibernateException {
		return getPropertyMapping( getEntityName( subcriteria, propertyName ) )
				.toType( getPropertyName( propertyName ) );
	}

	/**
	 * Get the a typed value for the given property value.
	 */
	public TypedValue getTypedValue(Criteria subcriteria, String propertyName, Object value)
			throws HibernateException {
		// Detect discriminator values...
		if ( value instanceof Class ) {
			Class entityClass = ( Class ) value;
			Queryable q = SessionFactoryHelper.findQueryableUsingImports( sessionFactory, entityClass.getName() );
			if ( q != null ) {
				Type type = q.getDiscriminatorType();
				String stringValue = q.getDiscriminatorSQLValue();
				if (stringValue != null && stringValue.length() > 2
						&& stringValue.startsWith("'")
						&& stringValue.endsWith("'")) { // remove the single
														// quotes
					stringValue = stringValue.substring(1,
							stringValue.length() - 1);
				}
				
				// Convert the string value into the proper type.
				if ( type instanceof StringRepresentableType ) {
					StringRepresentableType nullableType = (StringRepresentableType) type;
					value = nullableType.fromStringValue( stringValue );
				}
				else {
					throw new QueryException( "Unsupported discriminator type " + type );
				}
				return new TypedValue(
						type,
				        value,
				        EntityMode.POJO
				);
			}
		}
		// Otherwise, this is an ordinary value.
		return new TypedValue(
				getTypeUsingProjection( subcriteria, propertyName ),
		        value,
		        EntityMode.POJO
		);
	}

	private PropertyMapping getPropertyMapping(String entityName)
			throws MappingException {
		CriteriaInfoProvider info = ( CriteriaInfoProvider )nameCriteriaInfoMap.get(entityName);
		return info.getPropertyMapping();
	}

	//TODO: use these in methods above

	public String getEntityName(Criteria subcriteria, String propertyName) {
		if ( propertyName.indexOf( '.' ) > 0 ) {
			String root = StringHelper.root( propertyName );
			Criteria crit = getAliasedCriteria( root );
			if ( crit != null ) {
				return getEntityName( crit );
			}
		}
		return getEntityName( subcriteria );
	}

	public String getSQLAlias(Criteria criteria, String propertyName) {
		if ( propertyName.indexOf( '.' ) > 0 ) {
			String root = StringHelper.root( propertyName );
			Criteria subcriteria = getAliasedCriteria( root );
			if ( subcriteria != null ) {
				return getSQLAlias( subcriteria );
			}
		}
		return getSQLAlias( criteria );
	}

	public String getPropertyName(String propertyName) {
		if ( propertyName.indexOf( '.' ) > 0 ) {
			String root = StringHelper.root( propertyName );
			Criteria crit = getAliasedCriteria( root );
			if ( crit != null ) {
				return propertyName.substring( root.length() + 1 );
			}
		}
		return propertyName;
	}

	public String getWithClause(String path)
	{
		final Criterion crit = (Criterion)this.withClauseMap.get(path);
		return crit == null ? null : crit.toSqlString(getCriteria(path), this);
	}

	public boolean hasRestriction(String path)
	{
		final CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) getCriteria( path );
		return crit == null ? false : crit.hasRestriction();
	}


}

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate CriteriaQueryTranslator.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.