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

Hibernate example source code file (PropertyBinder.java)

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

annotationexception, annotationexception, component, generated, inheritancestate, property, property, rootclass, simplevaluebinder, simplevaluebinder, string, string, util, value, xclass

The Hibernate PropertyBinder.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.cfg.annotations;

import java.util.Map;
import javax.persistence.EmbeddedId;
import javax.persistence.Id;
import org.hibernate.AnnotationException;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.cfg.AccessType;
import org.hibernate.cfg.AnnotationBinder;
import org.hibernate.cfg.BinderHelper;
import org.hibernate.cfg.Ejb3Column;
import org.hibernate.cfg.InheritanceState;
import org.hibernate.cfg.Mappings;
import org.hibernate.cfg.PropertyHolder;
import org.hibernate.cfg.PropertyPreloadedData;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Value;

import org.jboss.logging.Logger;

/**
 * @author Emmanuel Bernard
 */
public class PropertyBinder {
    private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, PropertyBinder.class.getName());

	private String name;
	private String returnedClassName;
	private boolean lazy;
	private AccessType accessType;
	private Ejb3Column[] columns;
	private PropertyHolder holder;
	private Mappings mappings;
	private Value value;
	private boolean insertable = true;
	private boolean updatable = true;
	private String cascade;
	private SimpleValueBinder simpleValueBinder;
	private XClass declaringClass;
	private boolean declaringClassSet;
	private boolean embedded;
	private EntityBinder entityBinder;
	private boolean isXToMany;
	private String referencedEntityName;

	public void setReferencedEntityName(String referencedEntityName) {
		this.referencedEntityName = referencedEntityName;
	}

	public void setEmbedded(boolean embedded) {
		this.embedded = embedded;
	}

	public void setEntityBinder(EntityBinder entityBinder) {
		this.entityBinder = entityBinder;
	}

	/*
			 * property can be null
			 * prefer propertyName to property.getName() since some are overloaded
			 */
	private XProperty property;
	private XClass returnedClass;
	private boolean isId;
	private Map<XClass, InheritanceState> inheritanceStatePerClass;
	private Property mappingProperty;

	public void setInsertable(boolean insertable) {
		this.insertable = insertable;
	}

	public void setUpdatable(boolean updatable) {
		this.updatable = updatable;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setReturnedClassName(String returnedClassName) {
		this.returnedClassName = returnedClassName;
	}

	public void setLazy(boolean lazy) {
		this.lazy = lazy;
	}

	public void setAccessType(AccessType accessType) {
		this.accessType = accessType;
	}

	public void setColumns(Ejb3Column[] columns) {
		insertable = columns[0].isInsertable();
		updatable = columns[0].isUpdatable();
		//consistency is checked later when we know the property name
		this.columns = columns;
	}

	public void setHolder(PropertyHolder holder) {
		this.holder = holder;
	}

	public void setValue(Value value) {
		this.value = value;
	}

	public void setCascade(String cascadeStrategy) {
		this.cascade = cascadeStrategy;
	}

	public void setMappings(Mappings mappings) {
		this.mappings = mappings;
	}

	public void setDeclaringClass(XClass declaringClass) {
		this.declaringClass = declaringClass;
		this.declaringClassSet = true;
	}

	private void validateBind() {
		if ( property.isAnnotationPresent( Immutable.class ) ) {
			throw new AnnotationException(
					"@Immutable on property not allowed. " +
							"Only allowed on entity level or on a collection."
			);
		}
		if ( !declaringClassSet ) {
			throw new AssertionFailure( "declaringClass has not been set before a bind" );
		}
	}

	private void validateMake() {
		//TODO check necessary params for a make
	}

	private Property makePropertyAndValue() {
		validateBind();
        LOG.debugf("MetadataSourceProcessor property %s with lazy=%s", name, lazy);
		String containerClassName = holder == null ?
				null :
				holder.getClassName();
		simpleValueBinder = new SimpleValueBinder();
		simpleValueBinder.setMappings( mappings );
		simpleValueBinder.setPropertyName( name );
		simpleValueBinder.setReturnedClassName( returnedClassName );
		simpleValueBinder.setColumns( columns );
		simpleValueBinder.setPersistentClassName( containerClassName );
		simpleValueBinder.setType( property, returnedClass );
		simpleValueBinder.setMappings( mappings );
		simpleValueBinder.setReferencedEntityName( referencedEntityName );
		SimpleValue propertyValue = simpleValueBinder.make();
		setValue( propertyValue );
		return makeProperty();
	}

	//used when value is provided
	public Property makePropertyAndBind() {
		return bind( makeProperty() );
	}

	//used to build everything from scratch
	public Property makePropertyValueAndBind() {
		return bind( makePropertyAndValue() );
	}

	public void setXToMany(boolean xToMany) {
		this.isXToMany = xToMany;
	}

	private Property bind(Property prop) {
		if (isId) {
			final RootClass rootClass = ( RootClass ) holder.getPersistentClass();
			//if an xToMany, it as to be wrapped today.
			//FIXME this pose a problem as the PK is the class instead of the associated class which is not really compliant with the spec
			if ( isXToMany || entityBinder.wrapIdsInEmbeddedComponents() ) {
				Component identifier = (Component) rootClass.getIdentifier();
				if (identifier == null) {
					identifier = AnnotationBinder.createComponent( holder, new PropertyPreloadedData(null, null, null), true, false, mappings );
					rootClass.setIdentifier( identifier );
					identifier.setNullValue( "undefined" );
					rootClass.setEmbeddedIdentifier( true );
					rootClass.setIdentifierMapper( identifier );
				}
				//FIXME is it good enough?
				identifier.addProperty( prop );
			}
			else {
				rootClass.setIdentifier( ( KeyValue ) getValue() );
				if (embedded) {
					rootClass.setEmbeddedIdentifier( true );
				}
				else {
					rootClass.setIdentifierProperty( prop );
					final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
							declaringClass,
							inheritanceStatePerClass,
							mappings
					);
					if (superclass != null) {
						superclass.setDeclaredIdentifierProperty(prop);
					}
					else {
						//we know the property is on the actual entity
						rootClass.setDeclaredIdentifierProperty( prop );
					}
				}
			}
		}
		else {
			holder.addProperty( prop, columns, declaringClass );
		}
		return prop;
	}

	//used when the value is provided and the binding is done elsewhere
	public Property makeProperty() {
		validateMake();
        LOG.debugf("Building property %s", name);
		Property prop = new Property();
		prop.setName( name );
		prop.setNodeName( name );
		prop.setValue( value );
		prop.setLazy( lazy );
		prop.setCascade( cascade );
		prop.setPropertyAccessorName( accessType.getType() );
		Generated ann = property != null ?
				property.getAnnotation( Generated.class ) :
				null;
		GenerationTime generated = ann != null ?
				ann.value() :
				null;
		if ( generated != null ) {
			if ( !GenerationTime.NEVER.equals( generated ) ) {
				if ( property.isAnnotationPresent( javax.persistence.Version.class )
						&& GenerationTime.INSERT.equals( generated ) ) {
					throw new AnnotationException(
							"@Generated(INSERT) on a @Version property not allowed, use ALWAYS: "
									+ StringHelper.qualify( holder.getPath(), name )
					);
				}
				insertable = false;
				if ( GenerationTime.ALWAYS.equals( generated ) ) {
					updatable = false;
				}
				prop.setGeneration( PropertyGeneration.parse( generated.toString().toLowerCase() ) );
			}
		}
		NaturalId naturalId = property != null ?
				property.getAnnotation( NaturalId.class ) :
				null;
		if ( naturalId != null ) {
			if ( !naturalId.mutable() ) {
				updatable = false;
			}
			prop.setNaturalIdentifier( true );
		}
		prop.setInsertable( insertable );
		prop.setUpdateable( updatable );
		OptimisticLock lockAnn = property != null ?
				property.getAnnotation( OptimisticLock.class ) :
				null;
		if ( lockAnn != null ) {
			prop.setOptimisticLocked( !lockAnn.excluded() );
			//TODO this should go to the core as a mapping validation checking
			if ( lockAnn.excluded() && (
					property.isAnnotationPresent( javax.persistence.Version.class )
							|| property.isAnnotationPresent( Id.class )
							|| property.isAnnotationPresent( EmbeddedId.class ) ) ) {
				throw new AnnotationException(
						"@OptimisticLock.exclude=true incompatible with @Id, @EmbeddedId and @Version: "
								+ StringHelper.qualify( holder.getPath(), name )
				);
			}
		}
        LOG.trace("Cascading " + name + " with " + cascade);
		this.mappingProperty = prop;
		return prop;
	}

	public void setProperty(XProperty property) {
		this.property = property;
	}

	public void setReturnedClass(XClass returnedClass) {
		this.returnedClass = returnedClass;
	}

	public SimpleValueBinder getSimpleValueBinder() {
		return simpleValueBinder;
	}

	public Value getValue() {
		return value;
	}

	public void setId(boolean id) {
		this.isId = id;
	}

	public void setInheritanceStatePerClass(Map<XClass, InheritanceState> inheritanceStatePerClass) {
		this.inheritanceStatePerClass = inheritanceStatePerClass;
	}
}

Other Hibernate examples (source code examples)

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