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

Hibernate example source code file (Example.java)

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

compositetype, criteriaquery, example, example, hibernateexception, io, object, object, propertyselector, string, string, stringbuffer, type, type, typedvalue, util

The Hibernate Example.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.criterion;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.TypedValue;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.CompositeType;
import org.hibernate.type.Type;

/**
 * Support for query by example.
 * <pre>
 * List results = session.createCriteria(Parent.class)
 *     .add( Example.create(parent).ignoreCase() )
 *     .createCriteria("child")
 *         .add( Example.create( parent.getChild() ) )
 *     .list();
 * </pre>
 * "Examples" may be mixed and matched with "Expressions" in the same <tt>Criteria.
 * @see org.hibernate.Criteria
 * @author Gavin King
 */

public class Example implements Criterion {

	private final Object entity;
	private final Set excludedProperties = new HashSet();
	private PropertySelector selector;
	private boolean isLikeEnabled;
	private Character escapeCharacter;
	private boolean isIgnoreCaseEnabled;
	private MatchMode matchMode;

	/**
	 * A strategy for choosing property values for inclusion in the query
	 * criteria
	 */

	public static interface PropertySelector extends Serializable {
		public boolean include(Object propertyValue, String propertyName, Type type);
	}

	private static final PropertySelector NOT_NULL = new NotNullPropertySelector();
	private static final PropertySelector ALL = new AllPropertySelector();
	private static final PropertySelector NOT_NULL_OR_ZERO = new NotNullOrZeroPropertySelector();

	static final class AllPropertySelector implements PropertySelector {
		public boolean include(Object object, String propertyName, Type type) {
			return true;
		}
		
		private Object readResolve() {
			return ALL;
		}
	}

	static final class NotNullPropertySelector implements PropertySelector {
		public boolean include(Object object, String propertyName, Type type) {
			return object!=null;
		}
		
		private Object readResolve() {
			return NOT_NULL;
		}
	}

	static final class NotNullOrZeroPropertySelector implements PropertySelector {
		public boolean include(Object object, String propertyName, Type type) {
			return object!=null && (
				!(object instanceof Number) || ( (Number) object ).longValue()!=0
			);
		}
		
		private Object readResolve() {
			return NOT_NULL_OR_ZERO;
		}
	}

	/**
	 * Set escape character for "like" clause
	 */
	public Example setEscapeCharacter(Character escapeCharacter) {
		this.escapeCharacter = escapeCharacter;
		return this;
	}

	/**
	 * Set the property selector
	 */
	public Example setPropertySelector(PropertySelector selector) {
		this.selector = selector;
		return this;
	}

	/**
	 * Exclude zero-valued properties
	 */
	public Example excludeZeroes() {
		setPropertySelector(NOT_NULL_OR_ZERO);
		return this;
	}

	/**
	 * Don't exclude null or zero-valued properties
	 */
	public Example excludeNone() {
		setPropertySelector(ALL);
		return this;
	}

	/**
	 * Use the "like" operator for all string-valued properties
	 */
	public Example enableLike(MatchMode matchMode) {
		isLikeEnabled = true;
		this.matchMode = matchMode;
		return this;
	}

	/**
	 * Use the "like" operator for all string-valued properties
	 */
	public Example enableLike() {
		return enableLike(MatchMode.EXACT);
	}

	/**
	 * Ignore case for all string-valued properties
	 */
	public Example ignoreCase() {
		isIgnoreCaseEnabled = true;
		return this;
	}

	/**
	 * Exclude a particular named property
	 */
	public Example excludeProperty(String name) {
		excludedProperties.add(name);
		return this;
	}

	/**
	 * Create a new instance, which includes all non-null properties
	 * by default
	 * @param entity
	 * @return a new instance of <tt>Example
	 */
	public static Example create(Object entity) {
		if (entity==null) throw new NullPointerException("null example");
		return new Example(entity, NOT_NULL);
	}

	protected Example(Object entity, PropertySelector selector) {
		this.entity = entity;
		this.selector = selector;
	}

	public String toString() {
		return "example (" + entity + ')';
	}

	private boolean isPropertyIncluded(Object value, String name, Type type) {
		return !excludedProperties.contains(name) &&
			!type.isAssociationType() &&
			selector.include(value, name, type);
	}

	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
		throws HibernateException {

		StringBuffer buf = new StringBuffer().append('(');
		EntityPersister meta = criteriaQuery.getFactory().getEntityPersister( criteriaQuery.getEntityName(criteria) );
		String[] propertyNames = meta.getPropertyNames();
		Type[] propertyTypes = meta.getPropertyTypes();
		//TODO: get all properties, not just the fetched ones!
		Object[] propertyValues = meta.getPropertyValues( entity );
		for (int i=0; i<propertyNames.length; i++) {
			Object propertyValue = propertyValues[i];
			String propertyName = propertyNames[i];

			boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
				isPropertyIncluded( propertyValue, propertyName, propertyTypes[i] );
			if (isPropertyIncluded) {
				if ( propertyTypes[i].isComponentType() ) {
					appendComponentCondition(
						propertyName,
						propertyValue,
						(CompositeType) propertyTypes[i],
						criteria,
						criteriaQuery,
						buf
					);
				}
				else {
					appendPropertyCondition(
						propertyName,
						propertyValue,
						criteria,
						criteriaQuery,
						buf
					);
				}
			}
		}
		if ( buf.length()==1 ) buf.append("1=1"); //yuck!
		return buf.append(')').toString();
	}

	private static final Object[] TYPED_VALUES = new TypedValue[0];

	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
	throws HibernateException {

		EntityPersister meta = criteriaQuery.getFactory()
				.getEntityPersister( criteriaQuery.getEntityName(criteria) );
		String[] propertyNames = meta.getPropertyNames();
		Type[] propertyTypes = meta.getPropertyTypes();
		 //TODO: get all properties, not just the fetched ones!
		Object[] values = meta.getPropertyValues( entity );
		List list = new ArrayList();
		for (int i=0; i<propertyNames.length; i++) {
			Object value = values[i];
			Type type = propertyTypes[i];
			String name = propertyNames[i];

			boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
				isPropertyIncluded(value, name, type);

			if (isPropertyIncluded) {
				if ( propertyTypes[i].isComponentType() ) {
					addComponentTypedValues(name, value, (CompositeType) type, list, criteria, criteriaQuery);
				}
				else {
					addPropertyTypedValue(value, type, list);
				}
			}
		}
		return (TypedValue[]) list.toArray(TYPED_VALUES);
	}
	
	private EntityMode getEntityMode(Criteria criteria, CriteriaQuery criteriaQuery) {
		EntityPersister meta = criteriaQuery.getFactory()
				.getEntityPersister( criteriaQuery.getEntityName(criteria) );
		EntityMode result = meta.getEntityMode();
		if ( ! meta.getEntityMetamodel().getTuplizer().isInstance( entity ) ) {
			throw new ClassCastException( entity.getClass().getName() );
		}
		return result;
	}

	protected void addPropertyTypedValue(Object value, Type type, List list) {
		if ( value!=null ) {
			if ( value instanceof String ) {
				String string = (String) value;
				if (isIgnoreCaseEnabled) string = string.toLowerCase();
				if (isLikeEnabled) string = matchMode.toMatchString(string);
				value = string;
			}
			list.add( new TypedValue(type, value, null) );
		}
	}

	protected void addComponentTypedValues(
			String path, 
			Object component, 
			CompositeType type,
			List list, 
			Criteria criteria, 
			CriteriaQuery criteriaQuery)
	throws HibernateException {

		if (component!=null) {
			String[] propertyNames = type.getPropertyNames();
			Type[] subtypes = type.getSubtypes();
			Object[] values = type.getPropertyValues( component, getEntityMode(criteria, criteriaQuery) );
			for (int i=0; i<propertyNames.length; i++) {
				Object value = values[i];
				Type subtype = subtypes[i];
				String subpath = StringHelper.qualify( path, propertyNames[i] );
				if ( isPropertyIncluded(value, subpath, subtype) ) {
					if ( subtype.isComponentType() ) {
						addComponentTypedValues(subpath, value, (CompositeType) subtype, list, criteria, criteriaQuery);
					}
					else {
						addPropertyTypedValue(value, subtype, list);
					}
				}
			}
		}
	}

	protected void appendPropertyCondition(
		String propertyName,
		Object propertyValue,
		Criteria criteria,
		CriteriaQuery cq,
		StringBuffer buf)
	throws HibernateException {
		Criterion crit;
		if ( propertyValue!=null ) {
			boolean isString = propertyValue instanceof String;
			if ( isLikeEnabled && isString ) {
				crit = new LikeExpression(
						propertyName,
						( String ) propertyValue,
						matchMode,
						escapeCharacter,
						isIgnoreCaseEnabled
				);
			}
			else {
				crit = new SimpleExpression( propertyName, propertyValue, "=", isIgnoreCaseEnabled && isString );
			}
		}
		else {
			crit = new NullExpression(propertyName);
		}
		String critCondition = crit.toSqlString(criteria, cq);
		if ( buf.length()>1 && critCondition.trim().length()>0 ) buf.append(" and ");
		buf.append(critCondition);
	}

	protected void appendComponentCondition(
		String path,
		Object component,
		CompositeType type,
		Criteria criteria,
		CriteriaQuery criteriaQuery,
		StringBuffer buf)
	throws HibernateException {

		if (component!=null) {
			String[] propertyNames = type.getPropertyNames();
			Object[] values = type.getPropertyValues( component, getEntityMode(criteria, criteriaQuery) );
			Type[] subtypes = type.getSubtypes();
			for (int i=0; i<propertyNames.length; i++) {
				String subpath = StringHelper.qualify( path, propertyNames[i] );
				Object value = values[i];
				if ( isPropertyIncluded( value, subpath, subtypes[i] ) ) {
					Type subtype = subtypes[i];
					if ( subtype.isComponentType() ) {
						appendComponentCondition(
							subpath,
							value,
							(CompositeType) subtype,
							criteria,
							criteriaQuery,
							buf
						);
					}
					else {
						appendPropertyCondition(
							subpath,
							value,
							criteria,
							criteriaQuery,
							buf
						);
					}
				}
			}
		}
	}
}

Other Hibernate examples (source code examples)

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