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

Hibernate example source code file (PersistenceUtilHelper.java)

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

classcache, classcache, field, hibernateproxy, io, list, loadstate, member, member, metadatacache, method, method, object, reflection, string, string, util

The Hibernate PersistenceUtilHelper.java source code

package org.hibernate.ejb.util;
import java.io.Serializable;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import javax.persistence.PersistenceException;
import javax.persistence.spi.LoadState;
import org.hibernate.AssertionFailure;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.bytecode.instrumentation.internal.FieldInterceptionHelper;
import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;

/**
 * @author Emmanuel Bernard
 * @author Hardy Ferentschik
 */
public class PersistenceUtilHelper {
	public static LoadState isLoadedWithoutReference(Object proxy, String property, MetadataCache cache) {
		Object entity;
		boolean sureFromUs = false;
		if ( proxy instanceof HibernateProxy ) {
			LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer();
			if ( li.isUninitialized() ) {
				return LoadState.NOT_LOADED;
			}
			else {
				entity = li.getImplementation();
			}
			sureFromUs = true;
		}
		else {
			entity = proxy;
		}

		//we are instrumenting but we can't assume we are the only ones
		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
			FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
			final boolean isInitialized = interceptor == null || interceptor.isInitialized( property );
			LoadState state;
			if (isInitialized && interceptor != null) {
				//property is loaded according to bytecode enhancement, but is it loaded as far as association?
				//it's ours, we can read
				state = isLoaded( get( entity, property, cache ) );
				//it's ours so we know it's loaded
				if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
			}
			else if ( interceptor != null && (! isInitialized)) {
				state = LoadState.NOT_LOADED;
			}
			else if ( sureFromUs ) { //interceptor == null
				//property is loaded according to bytecode enhancement, but is it loaded as far as association?
				//it's ours, we can read
				state = isLoaded( get( entity, property, cache ) );
				//it's ours so we know it's loaded
				if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
			}
			else {
				state = LoadState.UNKNOWN;
			}

			return state;
		}
		else {
			//can't do sureFromUs ? LoadState.LOADED : LoadState.UNKNOWN;
			//is that an association?
			return LoadState.UNKNOWN;
		}
	}

	public static LoadState isLoadedWithReference(Object proxy, String property, MetadataCache cache) {
		//for sure we don't instrument and for sure it's not a lazy proxy
		Object object = get(proxy, property, cache);
		return isLoaded( object );
	}

	private static Object get(Object proxy, String property, MetadataCache cache) {
		final Class<?> clazz = proxy.getClass();

		try {
			Member member = cache.getMember( clazz, property );
			if (member instanceof Field) {
				return ( (Field) member ).get( proxy );
			}
			else if (member instanceof Method) {
				return ( (Method) member ).invoke( proxy );
			}
			else {
				throw new AssertionFailure( "Member object neither Field nor Method: " + member);
			}
		}
		catch ( IllegalAccessException e ) {
			throw new PersistenceException( "Unable to access field or method: "
							+ clazz + "#"
							+ property, e);
		}
		catch ( InvocationTargetException e ) {
			throw new PersistenceException( "Unable to access field or method: "
							+ clazz + "#"
							+ property, e);
		}
	}

	private static void setAccessibility(Member member) {
		//Sun's ease of use, sigh...
		( ( AccessibleObject ) member ).setAccessible( true );
	}

	public static LoadState isLoaded(Object o) {
		if ( o instanceof HibernateProxy ) {
			final boolean isInitialized = !( ( HibernateProxy ) o ).getHibernateLazyInitializer().isUninitialized();
			return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
		}
		else if ( o instanceof PersistentCollection ) {
			final boolean isInitialized = ( (PersistentCollection) o ).wasInitialized();
			return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
		}
		else {
			return LoadState.UNKNOWN;
		}
	}

	/**
	 * Returns the method with the specified name or <code>null if it does not exist.
	 *
	 * @param clazz The class to check.
	 * @param methodName The method name.
	 *
	 * @return Returns the method with the specified name or <code>null if it does not exist.
	 */
	private static Method getMethod(Class<?> clazz, String methodName) {
		try {
			char string[] = methodName.toCharArray();
			string[0] = Character.toUpperCase( string[0] );
			methodName = new String( string );
			try {
				return clazz.getDeclaredMethod( "get" + methodName );
			}
			catch ( NoSuchMethodException e ) {
				return clazz.getDeclaredMethod( "is" + methodName );
			}
		}
		catch ( NoSuchMethodException e ) {
			return null;
		}
	}

	/**
	 * Cache hierarchy and member resolution in a weak hash map
	 */
	//TODO not really thread-safe
	public static class MetadataCache implements Serializable {
		private transient Map<Class classCache = new WeakHashMap, ClassCache>();


		private void readObject(java.io.ObjectInputStream stream) {
			classCache = new WeakHashMap<Class();
		}

		Member getMember(Class<?> clazz, String property) {
			ClassCache cache = classCache.get( clazz );
			if (cache == null) {
				cache = new ClassCache(clazz);
				classCache.put( clazz, cache );
			}
			Member member = cache.members.get( property );
			if ( member == null ) {
				member = findMember( clazz, property );
				cache.members.put( property, member );
			}
			return member;
		}

		private Member findMember(Class<?> clazz, String property) {
			final List<Class classes = getClassHierarchy( clazz );

			for (Class current : classes) {
				final Field field;
				try {
					field = current.getDeclaredField( property );
					setAccessibility( field );
					return field;
				}
				catch ( NoSuchFieldException e ) {
					final Method method = getMethod( current, property );
					if (method != null) {
						setAccessibility( method );
						return method;
					}
				}
			}
			//we could not find any match
			throw new PersistenceException( "Unable to find field or method: "
							+ clazz + "#"
							+ property);
		}

		private List<Class getClassHierarchy(Class clazz) {
			ClassCache cache = classCache.get( clazz );
			if (cache == null) {
				cache = new ClassCache(clazz);
				classCache.put( clazz, cache );
			}
			return cache.classHierarchy;
		}

		private static List<Class findClassHierarchy(Class clazz) {
			List<Class classes = new ArrayList>();
			Class<?> current = clazz;
			do {
				classes.add( current );
				current = current.getSuperclass();
			}
			while ( current != null );
			return classes;
		}

		private static class ClassCache {
			List<Class classHierarchy;
			Map<String, Member> members = new HashMap();

			public ClassCache(Class<?> clazz) {
				classHierarchy = findClassHierarchy( clazz );
			}
		}
	}

}

Other Hibernate examples (source code examples)

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