All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.mapping.Property Maven / Gradle / Ivy

There is a newer version: 7.0.0.Beta1
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate.mapping;

import java.io.Serializable;
import java.util.Comparator;
import java.util.List;
import java.util.StringTokenizer;

import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.boot.model.domain.BasicValueMapping;
import org.hibernate.boot.model.domain.EntityMapping;
import org.hibernate.boot.model.domain.ManagedTypeMapping;
import org.hibernate.boot.model.domain.PersistentAttributeMapping;
import org.hibernate.boot.model.domain.ValueMapping;
import org.hibernate.boot.model.relational.MappedColumn;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.collection.internal.StandardArraySemantics;
import org.hibernate.collection.internal.StandardBagSemantics;
import org.hibernate.collection.internal.StandardIdentifierBagSemantics;
import org.hibernate.collection.internal.StandardListSemantics;
import org.hibernate.collection.internal.StandardMapSemantics;
import org.hibernate.collection.internal.StandardOrderedMapSemantics;
import org.hibernate.collection.internal.StandardOrderedSetSemantics;
import org.hibernate.collection.internal.StandardSetSemantics;
import org.hibernate.collection.internal.StandardSortedMapSemantics;
import org.hibernate.collection.internal.StandardSortedSetSemantics;
import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.CascadeStyles;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.metamodel.model.creation.spi.RuntimeModelCreationContext;
import org.hibernate.metamodel.model.domain.internal.SingularPersistentAttributeBasic;
import org.hibernate.metamodel.model.domain.internal.SingularPersistentAttributeEmbedded;
import org.hibernate.metamodel.model.domain.internal.SingularPersistentAttributeEntity;
import org.hibernate.metamodel.model.domain.spi.ManagedTypeDescriptor;
import org.hibernate.metamodel.model.domain.spi.PersistentAttributeDescriptor;
import org.hibernate.metamodel.model.domain.spi.PersistentCollectionDescriptor;
import org.hibernate.metamodel.model.domain.spi.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.spi.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.spi.SingularPersistentAttribute.SingularAttributeClassification;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.property.access.spi.PropertyAccessStrategyResolver;
import org.hibernate.property.access.spi.Setter;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tuple.ValueGeneration;

/**
 * Represents a property as part of an entity or a component.
 *
 * @author Gavin King
 */
public class Property implements Serializable, PersistentAttributeMapping {
	private final MetadataBuildingContext context;
	private String name;
	private Value value;
	private String cascade;
	private boolean updateable = true;
	private boolean insertable = true;
	private boolean selectable = true;
	private boolean optimisticLocked = true;
	private ValueGeneration valueGenerationStrategy;
	private String propertyAccessorName;
	private boolean lazy;
	private String lazyGroup;
	private boolean optional;
	private java.util.Map metaAttributes;
	private PersistentClass persistentClass;
	private boolean naturalIdentifier;
	private boolean lob;

	@Override
	public String getMappedBy() {
		return mappedBy;
	}

	public void setMappedBy(String mappedBy) {
		this.mappedBy = mappedBy;
	}

	private String mappedBy;

	public Property(MetadataBuildingContext context) {
		this.context = context;
	}

	@Override
	public ValueMapping getValueMapping() {
		return value;
	}

	@Override
	public boolean isBackRef() {
		return false;
	}

	/**
	 * Does this property represent a synthetic property?  A synthetic property is one we create during
	 * metamodel binding to represent a collection of columns but which does not represent a property
	 * physically available on the entity.
	 *
	 * @return True if synthetic; false otherwise.
	 */

	public boolean isSynthetic() {
		return false;
	}


	
	public int getColumnSpan() {
		return value.getColumnSpan();
	}

	@SuppressWarnings("unchecked")
	public List getMappedColumns(){
		return value.getMappedColumns();
	}

	@Override
	public String getName() {
		return name;
	}

	public boolean isComposite() {
		return value instanceof Component;
	}

	public Value getValue() {
		return value;
	}

	public boolean isPrimitive(Class clazz) {
		return getGetter(clazz).getReturnType().isPrimitive();
	}
//
//	public CascadeStyle getCascadeStyle() throws MappingException {
//		Type type = value.getType();
//		if ( type.isComponentType() ) {
//			return getCompositeCascadeStyle( (EmbeddedType) type, cascade );
//		}
//		else if ( type.getClassification().equals( Type.Classification.COLLECTION ) ) {
//			return getCollectionCascadeStyle( ( (Collection) value ).getElement().getType(), cascade );
//		}
//		else {
//			return getCascadeStyle( cascade );
//		}
//	}
//
//	private static CascadeStyle getCompositeCascadeStyle(EmbeddedType compositeType, String cascade) {
//		if ( compositeType.getClassification().equals( Type.Classification.ANY ) ) {
//			return getCascadeStyle( cascade );
//		}
//		int length = compositeType.getSubtypes().length;
//		for ( int i=0; i PersistentAttributeDescriptor makeRuntimeAttribute(
			ManagedTypeDescriptor runtimeContainer,
			ManagedTypeMapping bootContainer,
			SingularPersistentAttribute.Disposition singularAttributeDisposition,
			RuntimeModelCreationContext context) {
		assert value != null;

		// todo (7.0) : better served through polymorphism though Value?

		// todo (6.0) : how to handle synthetic/virtual properties?
		assert !Backref.class.isInstance( this );
		assert !IndexBackref.class.isInstance( this );
		assert !SyntheticProperty.class.isInstance( this );

		if ( value instanceof Collection ) {
			return buildCollectionAttribute( runtimeContainer, bootContainer, context );
		}
		else {
			return buildSingularAttribute( runtimeContainer, bootContainer, singularAttributeDisposition, context );
		}
	}
	@SuppressWarnings("unchecked")
	private  PluralPersistentAttribute buildCollectionAttribute(
			ManagedTypeDescriptor runtimeContainer,
			ManagedTypeMapping bootContainer,
			RuntimeModelCreationContext context) {

		final PersistentCollectionDescriptor descriptor = context.getRuntimeModelDescriptorFactory().createPersistentCollectionDescriptor(
				this,
				runtimeContainer,
				context
		);
		context.registerCollectionDescriptor( descriptor, (Collection) value );

		return descriptor.getDescribedAttribute();
	}

	@SuppressWarnings("unchecked")
	private  CollectionSemantics resolveCollectionSemantics() {
		// todo (6.0) : re-use CollectionSemantics from boot resolution
		// 		the decision that a property is a persistent-collection (value instanceof Collection)
		//		should already have used CollectionSemanticsResolver to make that determination
		//
		// this is what would allow plugging in non-java.util.Collection collections (Celyon)
		//
		// for now create it here

		if ( value instanceof Array ) {
			return (CollectionSemantics) StandardArraySemantics.INSTANCE;
		}
		else if ( value instanceof Bag ) {
			return (CollectionSemantics) StandardBagSemantics.INSTANCE;
		}
		else if ( value instanceof IdentifierBag ) {
			return (CollectionSemantics) StandardIdentifierBagSemantics.INSTANCE;
		}
		else if ( value instanceof org.hibernate.mapping.List ) {
			return (CollectionSemantics) StandardListSemantics.INSTANCE;
		}
		else if ( value instanceof Set ) {
			final Set set = (Set) this.value;
			final Comparator comparator = set.getComparator();
			if ( comparator != null ) {
				return (CollectionSemantics) StandardSortedSetSemantics.INSTANCE;
			}

			if ( set.hasOrder() ) {
				return (CollectionSemantics) StandardOrderedSetSemantics.INSTANCE;
			}

			return (CollectionSemantics) StandardSetSemantics.INSTANCE;
		}
		else if ( value instanceof Map ) {
			final Map map = (Map) value;
			final Comparator comparator = map.getComparator();
			if ( comparator != null ) {
				return (CollectionSemantics) StandardSortedMapSemantics.INSTANCE;
			}

			if ( map.hasOrder() ) {
				return (CollectionSemantics) StandardOrderedMapSemantics.INSTANCE;
			}

			return (CollectionSemantics) StandardMapSemantics.INSTANCE;
		}

		throw new HibernateException(
				"Unable to determine collection semantics - `" +
						getEntity().getEntityName() + '#' +
						getName() + " : " +
						value.getJavaTypeMapping().getTypeName()
		);
	}

	@SuppressWarnings("unchecked")
	private  SingularPersistentAttribute buildSingularAttribute(
			ManagedTypeDescriptor runtimeContainer,
			ManagedTypeMapping bootContainer,
			SingularPersistentAttribute.Disposition singularAttributeDisposition,
			RuntimeModelCreationContext context) {
		final PropertyAccess propertyAccess = runtimeContainer.getRepresentationStrategy().generatePropertyAccess(
				bootContainer,
				this,
				runtimeContainer,
				context.getSessionFactory().getSessionFactoryOptions().getBytecodeProvider()
		);
		if ( value instanceof BasicValueMapping ) {
			return new SingularPersistentAttributeBasic(
					runtimeContainer,
					this,
					propertyAccess,
					singularAttributeDisposition,
					context
			);
		}
		else if ( value instanceof ToOne ) {
			return new SingularPersistentAttributeEntity(
					runtimeContainer,
					this,
					propertyAccess,
					singularAttributeDisposition,
					isManyToOne( (ToOne) value )
							? SingularAttributeClassification.MANY_TO_ONE
							: SingularAttributeClassification.ONE_TO_ONE,
					context
			);
		}
		else if ( value instanceof Component ) {
			return new SingularPersistentAttributeEmbedded(
					runtimeContainer,
					this,
					propertyAccess,
					singularAttributeDisposition,
					context
			);
		}
		else if ( value instanceof Any ) {
			throw new NotYetImplementedFor6Exception();
		}

		throw new MappingException( "Unrecognized ValueMapping type for conversion to runtime model : " + value );
	}

	private boolean isManyToOne(ToOne value) {
		return ManyToOne.class.isInstance( value );
	}

	public Property shallowCopy() {
		Property clone = new Property( context );
		clone.setCascade( getCascade() );
		clone.setInsertable( isInsertable() );
		clone.setLazy( isLazy() );
		clone.setName( getName() );
		clone.setNaturalIdentifier( isNaturalIdentifier() );
		clone.setOptimisticLocked( isOptimisticLocked() );
		clone.setOptional( isOptional() );
		clone.setPersistentClass( (PersistentClass) getEntity() );
		clone.setPropertyAccessorName( getPropertyAccessorName() );
		clone.setSelectable( isSelectable() );
		clone.setUpdateable( isUpdateable() );
		clone.setValue( getValue() );
		return clone;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy