[hibernate-commits] Hibernate SVN: r17836 - core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Oct 26 01:23:41 EDT 2009


Author: steve.ebersole at jboss.com
Date: 2009-10-26 01:23:40 -0400 (Mon, 26 Oct 2009)
New Revision: 17836

Added:
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractAttribute.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractManagedType.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractType.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeImplementor.java
Removed:
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java
Modified:
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java
Log:
HHH-4202 - Implement JPA 2.0 metamodel APIs


Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractAttribute.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractAttribute.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractAttribute.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -0,0 +1,142 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.metamodel;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.io.ObjectInputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.ManagedType;
+
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Models the commonality of the JPA {@link Attribute} hierarchy.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractAttribute<X, Y>
+		implements Attribute<X, Y>, AttributeImplementor<X,Y>, Serializable {
+	private final String name;
+	private final Class<Y> javaType;
+	private final AbstractManagedType<X> declaringType;
+	private transient Member member;
+	private final PersistentAttributeType persistentAttributeType;
+
+	public AbstractAttribute(
+			String name,
+			Class<Y> javaType,
+			AbstractManagedType<X> declaringType,
+			Member member,
+			PersistentAttributeType persistentAttributeType) {
+		this.name = name;
+		this.javaType = javaType;
+		this.declaringType = declaringType;
+		this.member = member;
+		this.persistentAttributeType = persistentAttributeType;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public ManagedType<X> getDeclaringType() {
+		return declaringType;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Class<Y> getJavaType() {
+		return javaType;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Member getJavaMember() {
+		return member;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public PersistentAttributeType getPersistentAttributeType() {
+		return persistentAttributeType;
+	}
+
+	/**
+	 * Used by JDK serialization...
+	 *
+	 * @param ois The input stream from which we are being read...
+	 * @throws java.io.IOException Indicates a general IO stream exception
+	 * @throws ClassNotFoundException Indicates a class resolution issue
+	 */
+	protected void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		ois.defaultReadObject();
+		final String memberDeclaringClassName = ( String ) ois.readObject();
+		final String memberName = ( String ) ois.readObject();
+		final String memberType = ( String ) ois.readObject();
+
+		final Class memberDeclaringClass = Class.forName(
+				memberDeclaringClassName,
+				false,
+				declaringType.getJavaType().getClassLoader()
+		);
+		try {
+			this.member = "method".equals( memberType )
+					? memberDeclaringClass.getMethod( memberName, ReflectHelper.NO_PARAM_SIGNATURE )
+					: memberDeclaringClass.getField( memberName );
+		}
+		catch ( Exception e ) {
+			throw new IllegalStateException(
+					"Unable to locate member [" + memberDeclaringClassName + "#"
+							+ memberName + "]"
+			);
+		}
+	}
+
+	/**
+	 * Used by JDK serialization...
+	 *
+	 * @param oos The output stream to which we are being written...
+	 * @throws IOException Indicates a general IO stream exception
+	 */
+	protected void writeObject(ObjectOutputStream oos) throws IOException {
+		oos.defaultWriteObject();
+		oos.writeObject( getJavaMember().getDeclaringClass().getName() );
+		oos.writeObject( getJavaMember().getName() );
+		// should only ever be a field or the getter-method...
+		oos.writeObject( Method.class.isInstance( getJavaMember() ) ? "method" : "field" );
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -0,0 +1,243 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.metamodel;
+
+import java.io.Serializable;
+import java.util.Set;
+import javax.persistence.metamodel.IdentifiableType;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.Type;
+import javax.persistence.metamodel.Attribute;
+
+/**
+ * Defines commonality for the JPA {@link IdentifiableType} types.  JPA defines
+ * identifiable types as entities or mapped-superclasses.  Basically things to which an
+ * identifier can be attached.
+ * <p/>
+ * NOTE : Currently we only really have support for direct entities in the Hibernate metamodel
+ * as the information for them is consumed into the closest actual entity subclass(es) in the
+ * internal Hibernate mapping-metamodel.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractIdentifiableType<X>
+		extends AbstractManagedType<X>
+		implements IdentifiableType<X>, Serializable {
+
+	private final boolean hasIdentifierProperty;
+	private final boolean isVersioned;
+
+	private SingularAttributeImpl<X, ?> id;
+	private SingularAttributeImpl<X, ?> version;
+	private Set<SingularAttribute<? super X,?>> idClassAttributes;
+
+	public AbstractIdentifiableType(
+			Class<X> javaType,
+			AbstractIdentifiableType<? super X> superType,
+			boolean hasIdentifierProperty,
+			boolean versioned) {
+		super( javaType, superType );
+		this.hasIdentifierProperty = hasIdentifierProperty;
+		isVersioned = versioned;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public AbstractIdentifiableType<? super X> getSupertype() {
+		return ( AbstractIdentifiableType<? super X> ) super.getSupertype();
+	}
+
+	protected AbstractIdentifiableType<? super X> requireSupertype() {
+		if ( getSupertype() == null ) {
+			throw new IllegalStateException( "No supertype found" );
+		}
+		return getSupertype();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean hasSingleIdAttribute() {
+		return hasIdentifierProperty;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <Y> SingularAttribute<? super X, Y> getId(Class<Y> type) {
+		final SingularAttribute<? super X, Y> id_;
+		if ( id != null ) {
+			checkSimpleId();
+			id_ = ( SingularAttribute<? super X, Y> ) id;
+		}
+		else {
+			id_ = requireSupertype().getId( type );
+		}
+		// TODO : check that type and id_.getJavaType() are related
+		return id_;
+	}
+
+	/**
+	 * Centralized check to ensure the id for this hierarchy is a simple one (i.e., does not use
+	 * an id-class).
+	 *
+	 * @see #checkIdClass()
+	 */
+	protected void checkSimpleId() {
+		if ( ! hasIdentifierProperty ) {
+			throw new IllegalStateException( "This class uses an @IdClass" );
+		}
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <Y> SingularAttribute<X, Y> getDeclaredId(Class<Y> yClass) {
+		checkDeclaredId();
+		checkSimpleId();
+		// TODO : check that type and id.getJavaType() are related
+		return (SingularAttribute<X, Y>) id;
+	}
+
+	/**
+	 * Centralized check to ensure the id is actually declared on the class mapped here, as opposed to a
+	 * super class.
+	 */
+	protected void checkDeclaredId() {
+		if ( id == null ) {
+			throw new IllegalArgumentException( "The id attribute is not declared on this type" );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Type<?> getIdType() {
+		if ( id != null ) {
+			checkSimpleId();
+			return id.getType();
+		}
+		else {
+			return requireSupertype().getIdType();
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Set<SingularAttribute<? super X, ?>> getIdClassAttributes() {
+		checkIdClass();
+		return idClassAttributes;
+	}
+
+	/**
+	 * Centralized check to ensure the id for this hierarchy uses an id-class.
+	 *
+	 * @see #checkSimpleId()
+	 */
+	private void checkIdClass() {
+		if ( hasIdentifierProperty ) {
+			throw new IllegalArgumentException( "This class does not use @IdClass" );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean hasVersionAttribute() {
+		return isVersioned;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <Y> SingularAttribute<? super X, Y> getVersion(Class<Y> type) {
+		if ( ! hasVersionAttribute() ) {
+			return null;
+		}
+		final SingularAttribute<? super X, Y> version_;
+		if ( version != null ) {
+			version_ = ( SingularAttribute<? super X, Y> ) version;
+		}
+		else {
+			version_ = requireSupertype().getVersion( type );
+		}
+		// TODO : check that type and version_.getJavaType() are related
+		return version_;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <Y> SingularAttribute<X, Y> getDeclaredVersion(Class<Y> yClass) {
+		checkDeclaredVersion();
+		// TODO : check that type and version_.getJavaType() are related
+		return ( SingularAttribute<X, Y> ) version;
+	}
+
+	/**
+	 * Centralized check to ensure the version (if one) is actually declared on the class mapped here, as opposed to a
+	 * super class.
+	 */
+	protected void checkDeclaredVersion() {
+		if ( version == null ) {
+			if ( getSupertype() != null && getSupertype().hasVersionAttribute() ) {
+				throw new IllegalArgumentException( "The version attribute is not declared on this type" );
+			}
+		}
+	}
+
+	public Builder<X> getBuilder() {
+		final AbstractManagedType.Builder<X> managedBuilder = super.getBuilder();
+		return new Builder<X>() {
+			public void applyIdAttribute(SingularAttributeImpl<X, ?> idAttribute) {
+				AbstractIdentifiableType.this.id = idAttribute;
+			}
+
+			public void applyIdClassAttributes(Set<SingularAttribute<? super X,?>> idClassAttributes) {
+				AbstractIdentifiableType.this.idClassAttributes = idClassAttributes;
+			}
+
+			public void applyVersionAttribute(SingularAttributeImpl<X, ?> versionAttribute) {
+				AbstractIdentifiableType.this.version = versionAttribute;
+			}
+
+			public void addAttribute(Attribute<X, ?> attribute) {
+				managedBuilder.addAttribute( attribute );
+			}
+		};
+	}
+
+	public static interface Builder<X> extends AbstractManagedType.Builder<X> {
+		public void applyIdAttribute(SingularAttributeImpl<X,?> idAttribute);
+		public void applyIdClassAttributes(Set<SingularAttribute<? super X,?>> idClassAttributes);
+		public void applyVersionAttribute(SingularAttributeImpl<X,?> versionAttribute);
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractManagedType.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractManagedType.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractManagedType.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -0,0 +1,494 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.metamodel;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.Bindable;
+import javax.persistence.metamodel.CollectionAttribute;
+import javax.persistence.metamodel.SetAttribute;
+import javax.persistence.metamodel.ListAttribute;
+import javax.persistence.metamodel.MapAttribute;
+
+import org.hibernate.annotations.common.AssertionFailure;
+
+/**
+ * Defines commonality for the JPA {@link ManagedType} hierarchy of interfaces.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractManagedType<X> 
+		extends AbstractType<X>
+		implements ManagedType<X>, Serializable {
+
+	private final  AbstractManagedType<? super X> superType;
+
+	private final Map<String,Attribute<X, ?>> declaredAttributes
+			= new HashMap<String, Attribute<X,?>>();
+	private final Map<String, SingularAttribute<X, ?>> declaredSingularAttributes
+			= new HashMap<String, SingularAttribute<X,?>>();
+	private final Map<String, PluralAttribute<X, ?, ?>> declaredPluralAttributes
+			= new HashMap<String, PluralAttribute<X,?,?>>();
+
+	protected AbstractManagedType(Class<X> javaType, AbstractManagedType<? super X> superType) {
+		super( javaType );
+		this.superType = superType;
+	}
+
+	protected AbstractManagedType<? super X> getSupertype() {
+		return superType;
+	}
+
+	private boolean locked = false;
+
+	public Builder<X> getBuilder() {
+		if ( locked ) {
+			throw new IllegalStateException( "Type has been locked" );
+		}
+		return new Builder<X>() {
+			public void addAttribute(Attribute<X,?> attribute) {
+				declaredAttributes.put( attribute.getName(), attribute );
+				final Bindable.BindableType bindableType = ( ( Bindable ) attribute ).getBindableType();
+				switch ( bindableType ) {
+					case SINGULAR_ATTRIBUTE : {
+						declaredSingularAttributes.put( attribute.getName(), (SingularAttribute<X,?>) attribute );
+						break;
+					}
+					case PLURAL_ATTRIBUTE : {
+						declaredPluralAttributes.put(attribute.getName(), (PluralAttribute<X,?,?>) attribute );
+						break;
+					}
+					default : {
+						throw new AssertionFailure( "unknown bindable type: " + bindableType );
+					}
+				}
+			}
+		};
+	}
+
+	public void lock() {
+		locked = true;
+	}
+
+	public static interface Builder<X> {
+		public void addAttribute(Attribute<X,?> attribute);
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public Set<Attribute<? super X, ?>> getAttributes() {
+		HashSet attributes = new HashSet<Attribute<X, ?>>( declaredAttributes.values() );
+		if ( getSupertype() != null ) {
+			attributes.addAll( getSupertype().getAttributes() );
+		}
+		return attributes;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Set<Attribute<X, ?>> getDeclaredAttributes() {
+		return new HashSet<Attribute<X, ?>>( declaredAttributes.values() );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public Attribute<? super X, ?> getAttribute(String name) {
+		Attribute<? super X, ?> attribute = declaredAttributes.get( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getAttribute( name );
+		}
+		return attribute;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Attribute<X, ?> getDeclaredAttribute(String name) {
+		final Attribute<X, ?> attr = declaredSingularAttributes.get( name );
+		checkNotNull( "Attribute ", attr, name );
+		return attr;
+	}
+
+	private void checkNotNull(String attributeType, Attribute<?,?> attribute, String name) {
+		if ( attribute == null ) {
+			throw new IllegalArgumentException( attributeType + " named " + name + " is not present" );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public Set<SingularAttribute<? super X, ?>> getSingularAttributes() {
+		HashSet attributes = new HashSet<SingularAttribute<X, ?>>( declaredSingularAttributes.values() );
+		if ( getSupertype() != null ) {
+			attributes.addAll( getSupertype().getSingularAttributes() );
+		}
+		return attributes;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Set<SingularAttribute<X, ?>> getDeclaredSingularAttributes() {
+		return new HashSet<SingularAttribute<X, ?>>( declaredSingularAttributes.values() );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public SingularAttribute<? super X, ?> getSingularAttribute(String name) {
+		SingularAttribute<? super X, ?> attribute = declaredSingularAttributes.get( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getSingularAttribute( name );
+		}
+		return attribute;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public SingularAttribute<X, ?> getDeclaredSingularAttribute(String name) {
+		final SingularAttribute<X, ?> attr = declaredSingularAttributes.get( name );
+		checkNotNull( "SingularAttribute ", attr, name );
+		return attr;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <Y> SingularAttribute<? super X, Y> getSingularAttribute(String name, Class<Y> type) {
+		SingularAttribute<? super X, ?> attribute = declaredSingularAttributes.get( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getSingularAttribute( name );
+		}
+		checkTypeForSingleAttribute( "SingularAttribute ", attribute, name, type );
+		return ( SingularAttribute<? super X, Y> ) attribute;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings( "unchecked")
+	public <Y> SingularAttribute<X, Y> getDeclaredSingularAttribute(String name, Class<Y> javaType) {
+		final SingularAttribute<X, ?> attr = declaredSingularAttributes.get( name );
+		checkTypeForSingleAttribute( "SingularAttribute ", attr, name, javaType );
+		return ( SingularAttribute<X, Y> ) attr;
+	}
+
+	private <Y> void checkTypeForSingleAttribute(
+			String attributeType,
+			SingularAttribute<?,?> attribute,
+			String name,
+			Class<Y> javaType) {
+		if ( attribute == null || ( javaType != null && !attribute.getBindableJavaType().equals( javaType ) ) ) {
+			throw new IllegalArgumentException(
+					attributeType + " named " + name
+					+ ( javaType != null ? " and of type " + javaType.getName() : "" )
+					+ " is not present"
+			);
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public Set<PluralAttribute<? super X, ?, ?>> getPluralAttributes() {
+		HashSet attributes = new HashSet<PluralAttribute<? super X, ?, ?>>( declaredPluralAttributes.values() );
+		if ( getSupertype() != null ) {
+			attributes.addAll( getSupertype().getPluralAttributes() );
+		}
+		return attributes;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Set<PluralAttribute<X, ?, ?>> getDeclaredPluralAttributes() {
+		return new HashSet<PluralAttribute<X,?,?>>( declaredPluralAttributes.values() );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public CollectionAttribute<? super X, ?> getCollection(String name) {
+		PluralAttribute<? super X, ?, ?> attribute = getPluralAttribute( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getPluralAttribute( name );
+		}
+		basicCollectionCheck( attribute, name );
+		return ( CollectionAttribute<X, ?> ) attribute;
+	}
+
+	private PluralAttribute<? super X, ?, ?> getPluralAttribute(String name) {
+		return declaredPluralAttributes.get( name );
+	}
+
+	private void basicCollectionCheck(PluralAttribute<? super X, ?, ?> attribute, String name) {
+		checkNotNull( "CollectionAttribute", attribute, name );
+		if ( ! CollectionAttribute.class.isAssignableFrom( attribute.getClass() ) ) {
+			throw new IllegalArgumentException( name + " is not a CollectionAttribute: " + attribute.getClass() );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings( "unchecked")
+	public CollectionAttribute<X, ?> getDeclaredCollection(String name) {
+		final PluralAttribute<X,?,?> attribute = declaredPluralAttributes.get( name );
+		basicCollectionCheck( attribute, name );
+		return ( CollectionAttribute<X, ?> ) attribute;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public SetAttribute<? super X, ?> getSet(String name) {
+		PluralAttribute<? super X, ?, ?> attribute = getPluralAttribute( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getPluralAttribute( name );
+		}
+		basicSetCheck( attribute, name );
+		return (SetAttribute<? super X, ?>) attribute;
+	}
+
+	private void basicSetCheck(PluralAttribute<? super X, ?, ?> attribute, String name) {
+		checkNotNull( "SetAttribute", attribute, name );
+		if ( ! SetAttribute.class.isAssignableFrom( attribute.getClass() ) ) {
+			throw new IllegalArgumentException( name + " is not a SetAttribute: " + attribute.getClass() );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings( "unchecked")
+	public SetAttribute<X, ?> getDeclaredSet(String name) {
+		final PluralAttribute<X,?,?> attribute = declaredPluralAttributes.get( name );
+		basicSetCheck( attribute, name );
+		return ( SetAttribute<X, ?> ) attribute;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public ListAttribute<? super X, ?> getList(String name) {
+		PluralAttribute<? super X, ?, ?> attribute = getPluralAttribute( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getPluralAttribute( name );
+		}
+		basicListCheck( attribute, name );
+		return (ListAttribute<? super X, ?>) attribute;
+	}
+
+	private void basicListCheck(PluralAttribute<? super X, ?, ?> attribute, String name) {
+		checkNotNull( "ListAttribute", attribute, name );
+		if ( ! ListAttribute.class.isAssignableFrom( attribute.getClass() ) ) {
+			throw new IllegalArgumentException( name + " is not a ListAttribute: " + attribute.getClass() );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public ListAttribute<X, ?> getDeclaredList(String name) {
+		final PluralAttribute<X,?,?> attribute = declaredPluralAttributes.get( name );
+		basicListCheck( attribute, name );
+		return ( ListAttribute<X, ?> ) attribute;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public MapAttribute<? super X, ?, ?> getMap(String name) {
+		PluralAttribute<? super X, ?, ?> attribute = getPluralAttribute( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getPluralAttribute( name );
+		}
+		basicMapCheck( attribute, name );
+		return (MapAttribute<? super X, ?, ?>) attribute;
+	}
+
+	private void basicMapCheck(PluralAttribute<? super X, ?, ?> attribute, String name) {
+		checkNotNull( "MapAttribute", attribute, name );
+		if ( ! MapAttribute.class.isAssignableFrom( attribute.getClass() ) ) {
+			throw new IllegalArgumentException( name + " is not a MapAttribute: " + attribute.getClass() );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public MapAttribute<X, ?, ?> getDeclaredMap(String name) {
+		final PluralAttribute<X,?,?> attribute = declaredPluralAttributes.get( name );
+		basicMapCheck( attribute, name );
+		return ( MapAttribute<X,?,?> ) attribute;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <E> CollectionAttribute<? super X, E> getCollection(String name, Class<E> elementType) {
+		PluralAttribute<? super X, ?, ?> attribute = declaredPluralAttributes.get( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getPluralAttribute( name );
+		}
+		checkCollectionElementType( attribute, name, elementType );
+		return ( CollectionAttribute<? super X, E> ) attribute;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public <E> CollectionAttribute<X, E> getDeclaredCollection(String name, Class<E> elementType) {
+		final PluralAttribute<X,?,?> attribute = declaredPluralAttributes.get( name );
+		checkCollectionElementType( attribute, name, elementType );
+		return ( CollectionAttribute<X, E> ) attribute;
+	}
+
+	private <E> void checkCollectionElementType(PluralAttribute<?,?,?> attribute, String name, Class<E> elementType) {
+		checkTypeForPluralAttributes( "CollectionAttribute", attribute, name, elementType, PluralAttribute.CollectionType.COLLECTION );
+	}
+
+	private <E> void checkTypeForPluralAttributes(
+			String attributeType,
+			PluralAttribute<?,?,?> attribute,
+			String name,
+			Class<E> elementType,
+			PluralAttribute.CollectionType collectionType) {
+		if ( attribute == null
+				|| ( elementType != null && !attribute.getBindableJavaType().equals( elementType ) )
+				|| attribute.getCollectionType() != collectionType ) {
+			throw new IllegalArgumentException(
+					attributeType + " named " + name
+					+ ( elementType != null ? " and of element type " + elementType : "" )
+					+ " is not present"
+			);
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <E> SetAttribute<? super X, E> getSet(String name, Class<E> elementType) {
+		PluralAttribute<? super X, ?, ?> attribute = declaredPluralAttributes.get( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getPluralAttribute( name );
+		}
+		checkSetElementType( attribute, name, elementType );
+		return ( SetAttribute<? super X, E> ) attribute;
+	}
+
+	private <E> void checkSetElementType(PluralAttribute<? super X, ?, ?> attribute, String name, Class<E> elementType) {
+		checkTypeForPluralAttributes( "SetAttribute", attribute, name, elementType, PluralAttribute.CollectionType.SET );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public <E> SetAttribute<X, E> getDeclaredSet(String name, Class<E> elementType) {
+		final PluralAttribute<X,?,?> attribute = declaredPluralAttributes.get( name );
+		checkSetElementType( attribute, name, elementType );
+		return ( SetAttribute<X, E> ) attribute;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <E> ListAttribute<? super X, E> getList(String name, Class<E> elementType) {
+		PluralAttribute<? super X, ?, ?> attribute = declaredPluralAttributes.get( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getPluralAttribute( name );
+		}
+		checkListElementType( attribute, name, elementType );
+		return ( ListAttribute<? super X, E> ) attribute;
+	}
+
+	private <E> void checkListElementType(PluralAttribute<? super X, ?, ?> attribute, String name, Class<E> elementType) {
+		checkTypeForPluralAttributes( "ListAttribute", attribute, name, elementType, PluralAttribute.CollectionType.LIST );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public <E> ListAttribute<X, E> getDeclaredList(String name, Class<E> elementType) {
+		final PluralAttribute<X,?,?> attribute = declaredPluralAttributes.get( name );
+		checkListElementType( attribute, name, elementType );
+		return ( ListAttribute<X, E> ) attribute;
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	public <K, V> MapAttribute<? super X, K, V> getMap(String name, Class<K> keyType, Class<V> valueType) {
+		PluralAttribute<? super X, ?, ?> attribute = getPluralAttribute( name );
+		if ( attribute == null && getSupertype() != null ) {
+			attribute = getSupertype().getPluralAttribute( name );
+		}
+		checkMapValueType( attribute, name, valueType );
+		final MapAttribute<? super X, K, V> mapAttribute = ( MapAttribute<? super X, K, V> ) attribute;
+		checkMapKeyType( mapAttribute, name, keyType );
+		return mapAttribute;
+	}
+
+	private <V> void checkMapValueType(PluralAttribute<? super X, ?, ?> attribute, String name, Class<V> valueType) {
+		checkTypeForPluralAttributes( "MapAttribute", attribute, name, valueType, PluralAttribute.CollectionType.MAP);
+	}
+
+	private <K,V> void checkMapKeyType(MapAttribute<? super X, K, V> mapAttribute, String name, Class<K> keyType) {
+		if ( mapAttribute.getKeyJavaType() != keyType ) {
+			throw new IllegalArgumentException( "MapAttribute named " + name + " does not support a key of type " + keyType );
+		}
+	}
+
+	public <K, V> MapAttribute<X, K, V> getDeclaredMap(String name, Class<K> keyType, Class<V> valueType) {
+		final PluralAttribute<X,?,?> attribute = declaredPluralAttributes.get( name );
+		checkMapValueType( attribute, name, valueType );
+		final MapAttribute<X, K, V> mapAttribute = ( MapAttribute<X, K, V> ) attribute;
+		checkMapKeyType( mapAttribute, name, keyType );
+		return mapAttribute;
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractType.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractType.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractType.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -0,0 +1,44 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.metamodel;
+
+import java.io.Serializable;
+import javax.persistence.metamodel.Type;
+
+/**
+ * Defines commonality for the JPA {@link Type} hierarchy of interfaces.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractType<X> implements Type<X>, Serializable {
+	private final Class<X> javaType;
+
+	public AbstractType(Class<X> javaType) {
+		this.javaType = javaType;
+	}
+
+	public Class<X> getJavaType() {
+		return javaType;
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -0,0 +1,356 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.metamodel;
+
+import java.util.Iterator;
+import java.lang.reflect.Member;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.Type;
+
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Value;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Map;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.OneToMany;
+import org.hibernate.annotations.common.AssertionFailure;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ * @author Emmanuel Bernard
+ */
+public class AttributeFactory {
+	private final MetadataContext context;
+
+	public AttributeFactory(MetadataContext context) {
+		this.context = context;
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	public <X, Y> AttributeImplementor<X, Y> buildAttribute(AbstractManagedType<X> ownerType, Property property) {
+		AttributeContext attrContext = getAttributeContext( property );
+		final AttributeImplementor<X, Y> attribute;
+		if ( attrContext.isCollection() ) {
+			attribute = buildPluralAttribute( ownerType, property, attrContext );
+		}
+		else {
+			final Type<Y> attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue() );
+			attribute = new SingularAttributeImpl<X,Y>(
+					property.getName(),
+					property.getType().getReturnedClass(),
+					ownerType,
+					determineJavaMember( property ),
+					false,
+					false,
+					property.isOptional(),
+					attrType,
+					attrContext.getElementAttributeType()
+			);
+		}
+		return attribute;
+	}
+
+	@SuppressWarnings( "unchecked" )
+	private <X, Y, V, K> AttributeImplementor<X, Y> buildPluralAttribute(AbstractManagedType<X> ownerType, Property property, AttributeContext attrContext) {
+		AttributeImplementor<X, Y> attribute;
+		final Type<V> attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue() );
+		final Class<Y> collectionClass = (Class<Y>) attrContext.getCollectionClass();
+		if ( java.util.Map.class.isAssignableFrom( collectionClass ) ) {
+			final Type<K> keyType = getType( attrContext.getKeyTypeStatus(), attrContext.getKeyValue() );
+			attribute = PluralAttributeImpl.create( ownerType, attrType, collectionClass, keyType )
+					.member( determineJavaMember( property ) )
+					.property( property )
+					.persistentAttributeType( attrContext.getElementAttributeType() )
+					.build();
+		}
+		else {
+			attribute =  PluralAttributeImpl.create( ownerType, attrType, collectionClass, null )
+					.member( determineJavaMember( property ) )
+					.property( property )
+					.persistentAttributeType( attrContext.getElementAttributeType() )
+					.build();
+		}
+		return attribute;
+	}
+
+	private <X> Type<X> getType(AttributeContext.TypeStatus elementTypeStatus, Value value) {
+		final org.hibernate.type.Type type = value.getType();
+		switch ( elementTypeStatus ) {
+			case BASIC:
+				return buildBasicType( type );
+			case EMBEDDABLE:
+				return buildEmbeddableType( value, type );
+			case ENTITY:
+				return buildEntityType( type );
+			default:
+				throw new AssertionFailure( "Unknown AttributeContext.TypeStatus: " + elementTypeStatus );
+
+		}
+	}
+
+	@SuppressWarnings( "unchecked" )
+	private <X> Type<X> buildBasicType(org.hibernate.type.Type type) {
+		final Class<X> clazz = type.getReturnedClass();
+		return new BasicTypeImpl<X>( clazz, Type.PersistenceType.BASIC );
+	}
+
+	@SuppressWarnings( "unchecked" )
+	private <X> Type<X> buildEntityType(org.hibernate.type.Type type) {
+		String entityName = ( (org.hibernate.type.EntityType) type ).getAssociatedEntityName();
+		return ( Type<X> ) context.locateEntityType( entityName );
+	}
+
+	@SuppressWarnings( "unchecked" )
+	private <X> Type<X> buildEmbeddableType(Value value, org.hibernate.type.Type type) {
+		//build embedable type
+		final Class<X> clazz = type.getReturnedClass();
+		final EmbeddableTypeImpl<X> embeddableType = new EmbeddableTypeImpl<X>( clazz );
+		context.registerEmbeddedableType( embeddableType );
+		final Component component = (Component) value;
+		final Iterator<Property> subProperties = component.getPropertyIterator();
+		while ( subProperties.hasNext() ) {
+			final Property property = subProperties.next();
+			embeddableType.getBuilder().addAttribute( buildAttribute( embeddableType, property ) );
+		}
+		embeddableType.lock();
+		return embeddableType;
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	public <X, Y> SingularAttributeImpl<X, Y> buildIdAttribute(AbstractManagedType<X> ownerType, Property property) {
+		final AttributeContext attrContext = getAttributeContext( property );
+		final Type<Y> attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue() );
+		final Class<Y> idJavaType = property.getType().getReturnedClass();
+		return new SingularAttributeImpl.Identifier(
+				property.getName(),
+				idJavaType,
+				ownerType,
+				determineJavaMember( property ),
+				attrType,
+				attrContext.getElementAttributeType()
+		);
+	}
+
+	@SuppressWarnings({ "UnusedDeclaration" })
+	private Member determineJavaMember(Property property) {
+		return null;
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	public <X, Y> SingularAttributeImpl<X, Y> buildVerisonAttribute(AbstractManagedType<X> ownerType, Property property) {
+		final AttributeContext attrContext = getAttributeContext( property );
+		final Class<Y> javaType = property.getType().getReturnedClass();
+		final Type<Y> attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue() );
+		return new SingularAttributeImpl.Version(
+				property.getName(),
+				javaType,
+				ownerType,
+				determineJavaMember( property ),
+				attrType,
+				attrContext.getElementAttributeType()
+		);
+	}
+
+	private static class AttributeContext {
+		private final Value elementValue;
+		private final TypeStatus typeStatus;
+		private final Class<?> collectionClass;
+		private final Attribute.PersistentAttributeType attrType;
+		private final Value keyValue;
+		private final TypeStatus keyTypeStatus;
+
+		enum TypeStatus {
+			EMBEDDABLE,
+			ENTITY,
+			BASIC
+		}
+
+		private AttributeContext(
+				Value elementValue,
+				TypeStatus elementTypeStatus,
+				Attribute.PersistentAttributeType elementPAT,
+				Class<?> collectionClass,
+				Value keyValue,
+				TypeStatus keyTypeStatus) {
+			this.elementValue = elementValue;
+			this.typeStatus = elementTypeStatus;
+			this.collectionClass = collectionClass;
+			this.attrType = elementPAT;
+			this.keyValue = keyValue;
+			this.keyTypeStatus = keyTypeStatus;
+		}
+
+		public Value getElementValue() {
+			return elementValue;
+		}
+
+		public TypeStatus getElementTypeStatus() {
+			return typeStatus;
+		}
+
+		public boolean isCollection() {
+			return collectionClass != null;
+		}
+
+		public Class<?> getCollectionClass() {
+			return collectionClass;
+		}
+
+		public Attribute.PersistentAttributeType getElementAttributeType() {
+			return attrType;
+		}
+
+		public Value getKeyValue() {
+			return keyValue;
+		}
+
+		public TypeStatus getKeyTypeStatus() {
+			return keyTypeStatus;
+		}
+	}
+
+	private static AttributeContext getAttributeContext(Property property) {
+		// FIXME the logical level for *To* is different from the Hibernate physical model.
+		//		ie a @ManyToOne @AssocTable is a many-to-many for hibernate
+		//		and a @OneToMany @AssocTable is a many-to-many for hibernate
+		// FIXME so basically Attribute.PersistentAttributeType is crap at the moment
+		final Value value = property.getValue();
+		final org.hibernate.type.Type type = value.getType();
+		if ( type.isAnyType() ) {
+			throw new UnsupportedOperationException( "any not supported yet" );
+		}
+		else if ( type.isAssociationType() ) {
+			//collection or entity
+			if ( type.isCollectionType() ) {
+				//do collection
+				if ( value instanceof Collection ) {
+					final Collection collValue = ( Collection ) value;
+					final Value elementValue = collValue.getElement();
+					final org.hibernate.type.Type elementType = elementValue.getType();
+					final AttributeContext.TypeStatus elementTypeStatus;
+					final Attribute.PersistentAttributeType elementPAT;
+					final Class<?> collectionClass = collValue.getCollectionType().getReturnedClass();
+
+
+					final Value keyValue;
+					final org.hibernate.type.Type keyType;
+					final AttributeContext.TypeStatus keyTypeStatus;
+					if ( value instanceof Map ) {
+						keyValue = ( ( Map ) value ).getIndex();
+						keyType = keyValue.getType();
+						if ( keyValue instanceof Component ) {
+							keyTypeStatus = AttributeContext.TypeStatus.EMBEDDABLE;
+						}
+						else if ( keyType.isAnyType() ) {
+							throw new UnsupportedOperationException( "collection of any not supported yet" );
+						}
+						else if ( keyType.isAssociationType() ) {
+							keyTypeStatus = AttributeContext.TypeStatus.ENTITY;
+						}
+						else {
+							keyTypeStatus = AttributeContext.TypeStatus.BASIC;
+						}
+					}
+					else {
+						keyValue = null;
+						keyTypeStatus = null;
+					}
+
+					if ( elementValue instanceof Component ) {
+						//collection of components
+						elementTypeStatus = AttributeContext.TypeStatus.EMBEDDABLE;
+						elementPAT = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
+					}
+					else if ( elementType.isAnyType() ) {
+						throw new UnsupportedOperationException( "collection of any not supported yet" );
+					}
+					else if ( elementType.isAssociationType() ) {
+						//collection of entity
+						elementTypeStatus = AttributeContext.TypeStatus.ENTITY;
+						elementPAT = Attribute.PersistentAttributeType.MANY_TO_MANY;
+					}
+					else {
+						//collection of basic type
+						elementTypeStatus = AttributeContext.TypeStatus.BASIC;
+						elementPAT = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
+					}
+					return new AttributeContext(
+							elementValue,
+							elementTypeStatus,
+							elementPAT,
+							collectionClass,
+							keyValue,
+							keyTypeStatus
+					);
+				}
+				else if ( value instanceof OneToMany ) {
+					//one to many with FK => entity
+					return new AttributeContext(
+							value,
+							AttributeContext.TypeStatus.ENTITY,
+							Attribute.PersistentAttributeType.ONE_TO_MANY,
+							null, null, null
+					);
+				}
+
+			}
+			else {
+				//ToOne association
+				return new AttributeContext(
+						value,
+						AttributeContext.TypeStatus.ENTITY,
+						Attribute.PersistentAttributeType.MANY_TO_MANY,
+						//FIXME how to differentiate the logical many to one from the one to one (not physical level)
+						null,
+						null,
+						null
+				);
+			}
+		}
+		else if ( property.isComposite() ) {
+			//embeddable
+			return new AttributeContext(
+					value,
+					AttributeContext.TypeStatus.EMBEDDABLE,
+					Attribute.PersistentAttributeType.EMBEDDED,
+					null, null, null
+			);
+
+		}
+		else {
+			//basic type
+			return new AttributeContext(
+					value,
+					AttributeContext.TypeStatus.BASIC,
+					Attribute.PersistentAttributeType.BASIC,
+					null, null, null
+			);
+		}
+		throw new UnsupportedOperationException( "oops, we are missing something: " + property.toString() );
+	}
+
+
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeImplementor.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeImplementor.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeImplementor.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -0,0 +1,34 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.metamodel;
+
+import javax.persistence.metamodel.Attribute;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public interface AttributeImplementor<X, Y> extends Attribute<X, Y> {
+}

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java	2009-10-25 19:19:48 UTC (rev 17835)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -30,9 +30,12 @@
 /**
  * @author Emmanuel Bernard
  */
-public class EmbeddableTypeImpl<X> extends ManagedTypeImpl<X> implements EmbeddableType<X>, Serializable {
-	EmbeddableTypeImpl(Class<X> clazz, Iterator<Property> properties, MetadataContext context) {
-		super(clazz, properties, context);
+public class EmbeddableTypeImpl<X>
+		extends AbstractManagedType<X>
+		implements EmbeddableType<X>, Serializable {
+
+	public EmbeddableTypeImpl(Class<X> javaType) {
+		super( javaType, null );
 	}
 
 	public PersistenceType getPersistenceType() {

Deleted: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java	2009-10-25 19:19:48 UTC (rev 17835)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2009, 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.ejb.metamodel;
-
-import java.util.Set;
-import java.io.Serializable;
-import javax.persistence.metamodel.Attribute;
-import javax.persistence.metamodel.CollectionAttribute;
-import javax.persistence.metamodel.EntityType;
-import javax.persistence.metamodel.IdentifiableType;
-import javax.persistence.metamodel.ListAttribute;
-import javax.persistence.metamodel.MapAttribute;
-import javax.persistence.metamodel.PluralAttribute;
-import javax.persistence.metamodel.SetAttribute;
-import javax.persistence.metamodel.SingularAttribute;
-import javax.persistence.metamodel.Type;
-
-/**
- * Delegate to an other EntityType<X>
- * Helps break infinite loops when creating entity metamodel related to each other
- * 
- * @author Emmanuel Bernard
- */
-public class EntityTypeDelegator<X> implements EntityType<X>, Serializable {
-	private volatile EntityType<X> delegate;
-
-	void setDelegate(EntityType<X> delegate) {
-		this.delegate = delegate;
-	}
-
-	public String getName() {
-		return delegate.getName();
-	}
-
-	public <Y> SingularAttribute<? super X, Y> getId(Class<Y> type) {
-		return delegate.getId( type );
-	}
-
-	public <Y> SingularAttribute<? super X, Y> getVersion(Class<Y> type) {
-		return delegate.getVersion( type );
-	}
-
-	public <Y> SingularAttribute<X, Y> getDeclaredId(Class<Y> type) {
-		return delegate.getDeclaredId( type );
-	}
-
-	public <Y> SingularAttribute<X, Y> getDeclaredVersion(Class<Y> type) {
-		return delegate.getDeclaredVersion( type );
-	}
-
-	public IdentifiableType<? super X> getSupertype() {
-		return delegate.getSupertype();
-	}
-
-	public boolean hasSingleIdAttribute() {
-		return delegate.hasSingleIdAttribute();
-	}
-
-	public boolean hasVersionAttribute() {
-		return delegate.hasVersionAttribute();
-	}
-
-	public Set<SingularAttribute<? super X, ?>> getIdClassAttributes() {
-		return delegate.getIdClassAttributes();
-	}
-
-	public Type<?> getIdType() {
-		return delegate.getIdType();
-	}
-
-	public Set<Attribute<? super X, ?>> getAttributes() {
-		return delegate.getAttributes();
-	}
-
-	public Set<Attribute<X, ?>> getDeclaredAttributes() {
-		return delegate.getDeclaredAttributes();
-	}
-
-	public <Y> SingularAttribute<? super X, Y> getSingularAttribute(String name, Class<Y> type) {
-		return delegate.getSingularAttribute( name, type );
-	}
-
-	public <Y> SingularAttribute<X, Y> getDeclaredSingularAttribute(String name, Class<Y> type) {
-		return delegate.getDeclaredSingularAttribute( name, type );
-	}
-
-	public Set<SingularAttribute<? super X, ?>> getSingularAttributes() {
-		return delegate.getSingularAttributes();
-	}
-
-	public Set<SingularAttribute<X, ?>> getDeclaredSingularAttributes() {
-		return delegate.getDeclaredSingularAttributes();
-	}
-
-	public <E> CollectionAttribute<? super X, E> getCollection(String name, Class<E> elementType) {
-		return delegate.getCollection( name, elementType );
-	}
-
-	public <E> SetAttribute<? super X, E> getSet(String name, Class<E> elementType) {
-		return delegate.getSet( name, elementType );
-	}
-
-	public <E> ListAttribute<? super X, E> getList(String name, Class<E> elementType) {
-		return delegate.getList( name, elementType );
-	}
-
-	public <K, V> MapAttribute<? super X, K, V> getMap(String name, Class<K> keyType, Class<V> valueType) {
-		return delegate.getMap( name, keyType, valueType );
-	}
-
-	public <E> CollectionAttribute<X, E> getDeclaredCollection(String name, Class<E> elementType) {
-		return delegate.getDeclaredCollection( name, elementType );
-	}
-
-	public <E> SetAttribute<X, E> getDeclaredSet(String name, Class<E> elementType) {
-		return delegate.getDeclaredSet( name, elementType );
-	}
-
-	public <E> ListAttribute<X, E> getDeclaredList(String name, Class<E> elementType) {
-		return delegate.getDeclaredList( name, elementType );
-	}
-
-	public <K, V> MapAttribute<X, K, V> getDeclaredMap(String name, Class<K> keyType, Class<V> valueType) {
-		return delegate.getDeclaredMap( name, keyType, valueType );
-	}
-
-	public Set<PluralAttribute<? super X, ?, ?>> getPluralAttributes() {
-		return delegate.getPluralAttributes();
-	}
-
-	public Set<PluralAttribute<X, ?, ?>> getDeclaredPluralAttributes() {
-		return delegate.getDeclaredPluralAttributes();
-	}
-
-	public Attribute<? super X, ?> getAttribute(String name) {
-		return delegate.getAttribute( name );
-	}
-
-	public Attribute<X, ?> getDeclaredAttribute(String name) {
-		return delegate.getDeclaredAttribute( name );
-	}
-
-	public SingularAttribute<? super X, ?> getSingularAttribute(String name) {
-		return delegate.getSingularAttribute( name );
-	}
-
-	public SingularAttribute<X, ?> getDeclaredSingularAttribute(String name) {
-		return delegate.getDeclaredSingularAttribute( name );
-	}
-
-	public CollectionAttribute<? super X, ?> getCollection(String name) {
-		return delegate.getCollection( name );
-	}
-
-	public SetAttribute<? super X, ?> getSet(String name) {
-		return delegate.getSet( name );
-	}
-
-	public ListAttribute<? super X, ?> getList(String name) {
-		return delegate.getList( name );
-	}
-
-	public MapAttribute<? super X, ?, ?> getMap(String name) {
-		return delegate.getMap( name );
-	}
-
-	public CollectionAttribute<X, ?> getDeclaredCollection(String name) {
-		return delegate.getDeclaredCollection( name );
-	}
-
-	public SetAttribute<X, ?> getDeclaredSet(String name) {
-		return delegate.getDeclaredSet( name );
-	}
-
-	public ListAttribute<X, ?> getDeclaredList(String name) {
-		return delegate.getDeclaredList( name );
-	}
-
-	public MapAttribute<X, ?, ?> getDeclaredMap(String name) {
-		return delegate.getDeclaredMap( name );
-	}
-
-	public PersistenceType getPersistenceType() {
-		return delegate.getPersistenceType();
-	}
-
-	public Class<X> getJavaType() {
-		return delegate.getJavaType();
-	}
-
-	public BindableType getBindableType() {
-		return delegate.getBindableType();
-	}
-
-	public Class<X> getBindableJavaType() {
-		return delegate.getBindableJavaType();
-	}
-}

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java	2009-10-25 19:19:48 UTC (rev 17835)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -21,168 +21,34 @@
  */
 package org.hibernate.ejb.metamodel;
 
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
 import java.io.Serializable;
 import javax.persistence.metamodel.EntityType;
-import javax.persistence.metamodel.IdentifiableType;
-import javax.persistence.metamodel.SingularAttribute;
-import javax.persistence.metamodel.Type;
 
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-
 /**
+ * Defines the Hibernate implementation of the JPA {@link EntityType} contract.
+ *
+ * @author Steve Ebersole
  * @author Emmanuel Bernard
  */
-public class EntityTypeImpl<X> extends ManagedTypeImpl<X> implements EntityType<X>, Serializable {
-
-	private final SingularAttribute<X, ?> id;
-	private final SingularAttribute<X, ?> version;
+public class EntityTypeImpl<X> 
+		extends AbstractIdentifiableType<X>
+		implements EntityType<X>, Serializable {
 	private final String className;
-	private final boolean hasIdentifierProperty;
-	private final boolean isVersioned;
-	private final Set<SingularAttribute<? super X,?>> idClassAttributes;
-	private final IdentifiableType<? super X> supertype;
 
-	public EntityTypeImpl(Class<X> clazz, PersistentClass persistentClass, MetadataContext context) {
-		super(clazz, (Iterator<Property>) persistentClass.getPropertyIterator(), context );
-		this.className = persistentClass.getClassName();
-		this.hasIdentifierProperty = persistentClass.hasIdentifierProperty();
-		this.isVersioned = persistentClass.isVersioned();
-		id = buildIdAttribute( persistentClass );
-		version = buildVersionAttribute( persistentClass );
-		final Set<SingularAttribute<? super X, ?>> attributes = buildIdClassAttributes( persistentClass, context );
-		this.idClassAttributes = attributes != null ? Collections.unmodifiableSet( attributes ) : null;
-
-		PersistentClass superPersistentClass = persistentClass.getSuperclass();
-		if ( superPersistentClass == null ) {
-			supertype = null;
-		}
-		else {
-			final Class<?> superclass = superPersistentClass.getMappedClass();
-			final EntityTypeDelegator<X> entityTypeDelegator = new EntityTypeDelegator<X>();
-			context.addDelegator( entityTypeDelegator, superclass );
-			supertype = entityTypeDelegator;
-		}
+	public EntityTypeImpl(
+			Class<X> javaType,
+			AbstractIdentifiableType<? super X> superType, 
+			String className,
+			boolean hasIdentifierProperty,
+			boolean isVersioned) {
+		super( javaType, superType, hasIdentifierProperty, isVersioned );
+		this.className = className;
 	}
 
-	private <A> SingularAttribute<X, A> buildIdAttribute(PersistentClass persistentClass) {
-		if ( hasIdentifierProperty ) {
-			final Property identifierProperty = persistentClass.getIdentifierProperty();
-			@SuppressWarnings( "unchecked" )
-			Class<A> idClass = identifierProperty.getType().getReturnedClass();
-			final Type<A> attrType = new BasicTypeImpl<A>( idClass,
-															identifierProperty.isComposite() ?
-																	PersistenceType.EMBEDDABLE :
-																	PersistenceType.BASIC);
-			return SingularAttributeImpl.create(this, attrType )
-											.property(identifierProperty)
-											//.member( null ) //TODO member
-											.id()
-											.build();
-		}
-		else {
-			return null;
-		}
-	}
-
-	private <A> SingularAttribute<X, A> buildVersionAttribute(PersistentClass persistentClass) {
-		if ( persistentClass.isVersioned() ) {
-			@SuppressWarnings( "unchecked" )
-			Class<A> versionClass = persistentClass.getVersion().getType().getReturnedClass();
-			Property property = persistentClass.getVersion();
-			final Type<A> attrType = new BasicTypeImpl<A>( versionClass, PersistenceType.BASIC);
-			return SingularAttributeImpl.create(this, attrType )
-										.property(property)
-										//.member( null ) //TODO member
-										.version()
-										.build();
-		}
-		else {
-			return null;
-		}
-	}
-
-	private Set<SingularAttribute<? super X, ?>> buildIdClassAttributes(PersistentClass persistentClass, MetadataContext context) {
-		if ( hasSingleIdAttribute() ) {
-			return null;
-		}
-		@SuppressWarnings( "unchecked")
-		Iterator<Property> properties = persistentClass.getIdentifierMapper().getPropertyIterator();
-		Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>();
-		while ( properties.hasNext() ) {
-			attributes.add(
-					(SingularAttribute<? super X, ?>) MetamodelFactory.getAttribute( this, properties.next(), context, true )
-			);
-		}
-		return attributes;
-	}
-
 	public String getName() {
 		return className;
 	}
 
-	public <Y> SingularAttribute<? super X, Y> getId(Class<Y> type) {
-		//TODO check that type and id.getJavaType() are related
-		checkId();
-		@SuppressWarnings( "unchecked")
-		final SingularAttribute<? super X, Y> result = ( SingularAttribute<? super X, Y> ) id;
-		return result;
-	}
-
-	private void checkId() {
-		if ( ! hasSingleIdAttribute() ) throw new IllegalArgumentException("This is an @IdClass");
-	}
-
-	public <Y> SingularAttribute<? super X, Y> getVersion(Class<Y> type) {
-		//TODO check that type and version.getJavaType() are related
-		@SuppressWarnings( "unchecked")
-		final SingularAttribute<? super X, Y> result = ( SingularAttribute<? super X, Y> ) version;
-		return result;
-	}
-
-	public <Y> SingularAttribute<X, Y> getDeclaredId(Class<Y> type) {
-		checkId();
-		//TODO check that type and id.getJavaType() are related
-		@SuppressWarnings("unchecked")
-		final SingularAttribute<X, Y> result = ( SingularAttribute<X, Y> ) id;
-		return result;
-	}
-
-	public <Y> SingularAttribute<X, Y> getDeclaredVersion(Class<Y> type) {
-		//TODO check that type and version.getJavaType() are related
-		@SuppressWarnings("unchecked")
-		final SingularAttribute<X, Y> result = ( SingularAttribute<X, Y> ) version;
-		return result;
-	}
-
-	public IdentifiableType<? super X> getSupertype() {
-		return supertype;
-	}
-
-	public boolean hasSingleIdAttribute() {
-		return hasIdentifierProperty;
-	}
-
-	public boolean hasVersionAttribute() {
-		return isVersioned;
-	}
-
-	public Set<SingularAttribute<? super X, ?>> getIdClassAttributes() {
-		if ( hasSingleIdAttribute() ) {
-			throw new IllegalArgumentException( "This class does not use @IdClass: " + getName() );
-		}
-		return idClassAttributes;
-	}
-
-	public Type<?> getIdType() {
-		checkId();
-		return id.getType();
-	}
-
 	public BindableType getBindableType() {
 		return BindableType.ENTITY_TYPE;
 	}

Deleted: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java	2009-10-25 19:19:48 UTC (rev 17835)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -1,309 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
- * third-party contributors as indicated by either @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.ejb.metamodel;
-
-import java.util.Iterator;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Collections;
-import java.util.Map;
-import java.util.HashMap;
-import java.io.Serializable;
-
-import javax.persistence.metamodel.ManagedType;
-import javax.persistence.metamodel.Attribute;
-import javax.persistence.metamodel.SingularAttribute;
-import javax.persistence.metamodel.CollectionAttribute;
-import javax.persistence.metamodel.SetAttribute;
-import javax.persistence.metamodel.ListAttribute;
-import javax.persistence.metamodel.MapAttribute;
-import javax.persistence.metamodel.PluralAttribute;
-import javax.persistence.metamodel.Bindable;
-
-import org.hibernate.mapping.Property;
-import org.hibernate.annotations.common.AssertionFailure;
-
-/**
- * @author Emmanuel Bernard
- */
-public abstract class ManagedTypeImpl<X> implements ManagedType<X>, Serializable {
-	private final Class<X> javaClass;
-	private final Map<String,Attribute<X, ?>> declaredAttributes;
-	private final Map<String,SingularAttribute<X, ?>> declaredSingularAttributes;
-	private final Map<String,PluralAttribute<X, ?, ?>> declaredCollections;
-
-	
-
-	ManagedTypeImpl(Class<X> clazz, Iterator<Property> properties, MetadataContext context) {
-		this.javaClass = clazz;
-		Map<String,Attribute<X, ?>> localDeclAttr = new HashMap<String,Attribute<X, ?>>();
-		Map<String,SingularAttribute<X, ?>> localDeclSingAttr = new HashMap<String,SingularAttribute<X, ?>>();
-		Map<String,PluralAttribute<X,?,?>> localDeclPlurAttr = new HashMap<String,PluralAttribute<X,?,?>>();
-
-		while ( properties.hasNext() ) {
-			Property property = properties.next();
-			addProperty( property, context, localDeclAttr, localDeclSingAttr, localDeclPlurAttr );
-		}
-		declaredAttributes = Collections.unmodifiableMap( localDeclAttr );
-		declaredSingularAttributes = Collections.unmodifiableMap( localDeclSingAttr );
-		declaredCollections = Collections.unmodifiableMap( localDeclPlurAttr );
-	}
-
-	private <T> void addProperty(Property property,
-								 MetadataContext context,
-								 Map<String,Attribute<X, ?>> localDeclAttr,
-								 Map<String,SingularAttribute<X, ?>> localDeclSingAttr,
-								 Map<String,PluralAttribute<X,?,?>> localDeclPlurAttr) {
-		final Attribute<X, ?> attribute = MetamodelFactory.getAttribute( this, property, context );
-		localDeclAttr.put(attribute.getName(), attribute );
-		final Bindable.BindableType bindableType = ( ( Bindable<T> ) attribute ).getBindableType();
-		switch ( bindableType ) {
-			case SINGULAR_ATTRIBUTE:
-				localDeclSingAttr.put(attribute.getName(), (SingularAttribute<X, ?>) attribute );
-				break;
-			case PLURAL_ATTRIBUTE:
-				localDeclPlurAttr.put(attribute.getName(), (PluralAttribute<X,?,?>) attribute );
-				break;
-			default:
-				throw new AssertionFailure( "unknown bindable type: " + bindableType );
-		}
-
-	}
-
-	public Set<Attribute<? super X, ?>> getAttributes() {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public Set<Attribute<X, ?>> getDeclaredAttributes() {
-		return new HashSet<Attribute<X, ?>>(declaredAttributes.values());
-	}
-
-	public <Y> SingularAttribute<? super X, Y> getSingularAttribute(String name, Class<Y> type) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public <Y> SingularAttribute<X, Y> getDeclaredSingularAttribute(String name, Class<Y> type) {
-		final SingularAttribute<X, ?> attr = declaredSingularAttributes.get( name );
-		checkTypeForSingleAttribute( "SingularAttribute ", attr, name, type );
-		@SuppressWarnings( "unchecked")
-		final SingularAttribute<X, Y> result = ( SingularAttribute<X, Y> ) attr;
-		return result;
-	}
-
-	private <Y> void checkTypeForSingleAttribute(String error, SingularAttribute<?,?> attr, String name, Class<Y> type) {
-		if (attr == null || ( type != null && !attr.getBindableJavaType().equals( type ) ) ) {
-			throw new IllegalArgumentException(
-					error + " named " + name
-					+ (type != null ? " and of type " + type : "")
-					+ " is not present");
-		}
-	}
-
-	private <Y> void checkTypeForPluralAttributes(String error,
-												  PluralAttribute<?,?,?> attr,
-												  String name,
-												  Class<Y> type,
-												  PluralAttribute.CollectionType collectionType) {
-		if (attr == null
-				|| ( type != null && !attr.getBindableJavaType().equals( type ) )
-				|| attr.getCollectionType() != collectionType ) {
-			throw new IllegalArgumentException(
-					error + " named " + name
-					+ (type != null ? " and of element type " + type : "")
-					+ " is not present");
-		}
-	}
-
-	private <Y> void checkNotNull(String error, Attribute<?,?> attr, String name) {
-		if (attr == null) {
-			throw new IllegalArgumentException(
-					error + " named " + name
-					+ " is not present");
-		}
-	}
-
-	public Set<SingularAttribute<? super X, ?>> getSingularAttributes() {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public Set<SingularAttribute<X, ?>> getDeclaredSingularAttributes() {
-		return new HashSet<SingularAttribute<X, ?>>(declaredSingularAttributes.values());
-	}
-
-	public <E> CollectionAttribute<? super X, E> getCollection(String name, Class<E> elementType) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public <E> SetAttribute<? super X, E> getSet(String name, Class<E> elementType) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public <E> ListAttribute<? super X, E> getList(String name, Class<E> elementType) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public <K, V> MapAttribute<? super X, K, V> getMap(String name, Class<K> keyType, Class<V> valueType) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public <E> CollectionAttribute<X, E> getDeclaredCollection(String name, Class<E> elementType) {
-		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
-		checkTypeForPluralAttributes( "CollectionAttribute ", attr, name, elementType, PluralAttribute.CollectionType.COLLECTION );
-		@SuppressWarnings( "unchecked")
-		final CollectionAttribute<X, E> result = ( CollectionAttribute<X, E> ) attr;
-		return result;
-	}
-
-	public <E> SetAttribute<X, E> getDeclaredSet(String name, Class<E> elementType) {
-		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
-		checkTypeForPluralAttributes( "SetAttribute ", attr, name, elementType, PluralAttribute.CollectionType.SET );
-		@SuppressWarnings( "unchecked")
-		final SetAttribute<X, E> result = ( SetAttribute<X, E> ) attr;
-		return result;
-	}
-
-	public <E> ListAttribute<X, E> getDeclaredList(String name, Class<E> elementType) {
-		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
-		checkTypeForPluralAttributes( "ListAttribute ", attr, name, elementType, PluralAttribute.CollectionType.LIST );
-		@SuppressWarnings( "unchecked")
-		final ListAttribute<X, E> result = ( ListAttribute<X, E> ) attr;
-		return result;
-	}
-
-	public <K, V> MapAttribute<X, K, V> getDeclaredMap(String name, Class<K> keyType, Class<V> valueType) {
-		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
-		final String error = "MapAttribute ";
-		checkTypeForPluralAttributes( error, attr, name, valueType, PluralAttribute.CollectionType.MAP );
-		@SuppressWarnings( "unchecked")
-		final MapAttribute<X, K, V> result = ( MapAttribute<X, K, V> ) attr;
-		if ( result.getKeyJavaType() != keyType ) {
-			throw new IllegalArgumentException(
-					error + " named " + name + " does not support a key of type " + keyType
-			);
-		}
-		return result;
-	}
-
-	public Set<PluralAttribute<? super X, ?, ?>> getPluralAttributes() {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public Set<PluralAttribute<X, ?, ?>> getDeclaredPluralAttributes() {
-		return new HashSet<PluralAttribute<X,?,?>>(declaredCollections.values());
-	}
-
-	public Attribute<? super X, ?> getAttribute(String name) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public Attribute<X, ?> getDeclaredAttribute(String name) {
-		final Attribute<X, ?> attr = declaredSingularAttributes.get( name );
-		checkNotNull( "Attribute ", attr, name );
-		return attr;
-	}
-
-	public SingularAttribute<? super X, ?> getSingularAttribute(String name) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public SingularAttribute<X, ?> getDeclaredSingularAttribute(String name) {
-		final SingularAttribute<X, ?> attr = declaredSingularAttributes.get( name );
-		checkNotNull( "SingularAttribute ", attr, name );
-		return attr;
-	}
-
-	public CollectionAttribute<? super X, ?> getCollection(String name) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public SetAttribute<? super X, ?> getSet(String name) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public ListAttribute<? super X, ?> getList(String name) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public MapAttribute<? super X, ?, ?> getMap(String name) {
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
-	}
-
-	public CollectionAttribute<X, ?> getDeclaredCollection(String name) {
-		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
-		final String error = "CollectionAttribute ";
-		checkNotNull( error, attr, name );
-		if ( ! CollectionAttribute.class.isAssignableFrom( attr.getClass() ) ) {
-			throw new IllegalArgumentException( name
-					+ " is not a " + error + ": " + attr.getClass() );
-		}
-		@SuppressWarnings( "unchecked")
-		final CollectionAttribute<X, ?> result = ( CollectionAttribute<X, ?> ) attr;
-		return result;
-	}
-
-	public SetAttribute<X, ?> getDeclaredSet(String name) {
-		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
-		final String error = "SetAttribute ";
-		checkNotNull( error, attr, name );
-		if ( ! CollectionAttribute.class.isAssignableFrom( attr.getClass() ) ) {
-			throw new IllegalArgumentException( name
-					+ " is not a " + error + ": " + attr.getClass() );
-		}
-		@SuppressWarnings( "unchecked")
-		final SetAttribute<X, ?> result = ( SetAttribute<X, ?> ) attr;
-		return result;
-	}
-
-	public ListAttribute<X, ?> getDeclaredList(String name) {
-		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
-		final String error = "ListAttribute ";
-		checkNotNull( error, attr, name );
-		if ( ! CollectionAttribute.class.isAssignableFrom( attr.getClass() ) ) {
-			throw new IllegalArgumentException( name
-					+ " is not a " + error + ": " + attr.getClass() );
-		}
-		@SuppressWarnings( "unchecked")
-		final ListAttribute<X, ?> result = ( ListAttribute<X, ?> ) attr;
-		return result;
-	}
-
-	public MapAttribute<X, ?, ?> getDeclaredMap(String name) {
-		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
-		final String error = "MapAttribute ";
-		checkNotNull( error, attr, name );
-		if ( ! MapAttribute.class.isAssignableFrom( attr.getClass() ) ) {
-			throw new IllegalArgumentException( name
-					+ " is not a " + error + ": " + attr.getClass() );
-		}
-		@SuppressWarnings( "unchecked")
-		final MapAttribute<X,?,?> result = ( MapAttribute<X,?,?> ) attr;
-		return result;
-	}
-
-	public abstract PersistenceType getPersistenceType();
-
-	public Class<X> getJavaType() {
-		return javaClass;
-	}
-}

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java	2009-10-25 19:19:48 UTC (rev 17835)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -21,43 +21,146 @@
  */
 package org.hibernate.ejb.metamodel;
 
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.Map;
-import javax.persistence.metamodel.Metamodel;
-import javax.persistence.metamodel.EmbeddableType;
+import java.util.Set;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.SingularAttribute;
 
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+
 /**
- * Keep contextual information related tot he metedata building process.
- * In particular keeps data than theens to be processed in a second phase.
+ * Defines a context for storing information during the building of the {@link MetamodelImpl}.
+ * <p/>
+ * This contextual information includes data needing to be processed in a second pass as well as
+ * cross-references into the built metamodel classes.
+ *
+ * @author Steve Ebersole
  * @author Emmanuel Bernard
  */
 class MetadataContext {
-	private Map<EntityTypeDelegator<?>, Class<?>> delegators = new HashMap<EntityTypeDelegator<?>, Class<?>>();
-	private Map<Class<?>, EmbeddableType<?>> embeddables = new HashMap<Class<?>, EmbeddableType<?>>();
+	private final AttributeFactory attributeFactory = new AttributeFactory( this );
 
-	void addDelegator(EntityTypeDelegator<?> type, Class<?> clazz) {
-		delegators.put(type, clazz);
+	private HashMap<Class<?>,EntityTypeImpl<?>> entityTypes
+			= new HashMap<Class<?>, EntityTypeImpl<?>>();
+	private HashMap<String,EntityTypeImpl<?>> entityTypesByEntityName
+			= new HashMap<String, EntityTypeImpl<?>>();
+	private LinkedHashMap<PersistentClass,EntityTypeImpl<?>> entityTypesByPersistentClass
+			= new LinkedHashMap<PersistentClass,EntityTypeImpl<?>>();
+	private HashMap<Class<?>, EmbeddableTypeImpl<?>> embeddables
+			= new HashMap<Class<?>, EmbeddableTypeImpl<?>>();
+
+	/**
+	 * Given a Hibernate {@link PersistentClass}, locate the corresponding JPA {@link org.hibernate.type.EntityType}
+	 * implementation.  May retur null if the given {@link PersistentClass} has not yet been processed.
+	 *
+	 * @param persistentClass The Hibernate (config time) metamodel instance representing an entity.
+	 * @return Tne corresponding JPA {@link org.hibernate.type.EntityType}, or null if not yet processed.
+	 */
+	public EntityTypeImpl<?> locateEntityType(PersistentClass persistentClass) {
+		return entityTypesByPersistentClass.get( persistentClass );
 	}
 
-	void postProcess(Metamodel model) {
-		for ( Map.Entry<EntityTypeDelegator<?>, Class<?>> entry : delegators.entrySet() ) {
-			setDelegate( model, entry );
+	/**
+	 * Given a Java {@link Class}, locate the corresponding JPA {@link org.hibernate.type.EntityType}.  May
+	 * return null which could means that no such mapping exists at least at this time.
+	 *
+	 * @param javaType The java class.
+	 * @return The corresponding JPA {@link org.hibernate.type.EntityType}, or null.
+	 */
+	public EntityTypeImpl<?> locateEntityType(Class<?> javaType) {
+		return entityTypes.get( javaType );
+	}
+
+	/**
+	 * Given an entity-name, locate the corresponding JPA {@link org.hibernate.type.EntityType}.  May
+	 * return null which could means that no such mapping exists at least at this time.
+	 *
+	 * @param entityName The entity-name.
+	 * @return The corresponding JPA {@link org.hibernate.type.EntityType}, or null.
+	 */
+	public EntityTypeImpl<?> locateEntityType(String entityName) {
+		return entityTypesByEntityName.get( entityName );
+	}
+
+	/**
+	 * Retrieves the {@link Class java type} to {@link EntityType} map.
+	 *
+	 * @return The {@link Class java type} to {@link EntityType} map.
+	 */
+	public Map<Class<?>, EntityTypeImpl<?>> getEntityTypeMap() {
+		return Collections.unmodifiableMap( entityTypes );
+	}
+
+	/*package*/ void registerEntityType(PersistentClass persistentClass, EntityTypeImpl<?> entityType) {
+		entityTypes.put( entityType.getBindableJavaType(), entityType );
+		entityTypesByEntityName.put( persistentClass.getEntityName(), entityType );
+		entityTypesByPersistentClass.put( persistentClass, entityType );
+	}
+
+	/*package*/ void registerEmbeddedableType(EmbeddableTypeImpl<?> embeddableType) {
+		embeddables.put( embeddableType.getJavaType(), embeddableType );
+	}
+
+	public Map<Class<?>, EmbeddableTypeImpl<?>> getEmbeddableTypeMap() {
+		return Collections.unmodifiableMap( embeddables );
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	public void wrapUp() {
+		// IMPL NOTE : entityTypesByPersistentClass is a insertion-ordered map, where the insertion order
+		//		ensures that a type's super type is already processed...
+		for ( Map.Entry<PersistentClass,EntityTypeImpl<?>> entry : entityTypesByPersistentClass.entrySet() ) {
+			applyIdMetadata( entry.getKey(), entry.getValue() );
+			applyVersionAttribute( entry.getKey(), entry.getValue() );
+			Iterator<Property> properties = ( Iterator<Property> ) entry.getKey().getPropertyIterator();
+			while ( properties.hasNext() ) {
+				final Property property = properties.next();
+				final Attribute attribute = attributeFactory.buildAttribute( entry.getValue(), property );
+				entry.getValue().getBuilder().addAttribute( attribute );
+			}
+			entry.getValue().lock();
+			// todo : find the X_ style metamodel classes, if present, and inject
 		}
 	}
 
-	private <X> void setDelegate(Metamodel model, Map.Entry<EntityTypeDelegator<?>, Class<?>> entry) {
-		@SuppressWarnings( "unchecked" )
-		final Class<X> entityClass = (Class<X>) entry.getValue();
-		@SuppressWarnings( "unchecked" )
-		final EntityTypeDelegator<X> delegator = (EntityTypeDelegator<X>) entry.getKey();
-		delegator.setDelegate( model.entity( entityClass ) );
+	private <X> void applyIdMetadata(PersistentClass persistentClass, EntityTypeImpl<X> jpaEntityType) {
+		if ( persistentClass.hasIdentifierProperty() ) {
+			jpaEntityType.getBuilder().applyIdAttribute(
+					attributeFactory.buildIdAttribute( jpaEntityType, persistentClass.getIdentifierProperty() ) 
+			);
+		}
+		else {
+			jpaEntityType.getBuilder().applyIdClassAttributes( buildIdClassAttributes( jpaEntityType, persistentClass ) );
+		}
 	}
 
-	<X> void addEmbeddableType(Class<X> clazz, EmbeddableType<X> embeddableType) {
-		embeddables.put( clazz, embeddableType );
+	private <X> void applyVersionAttribute(PersistentClass persistentClass, EntityTypeImpl<X> jpaEntityType) {
+		if ( ! persistentClass.isVersioned() ) {
+			return;
+		}
+		jpaEntityType.getBuilder().applyVersionAttribute(
+				attributeFactory.buildVerisonAttribute( jpaEntityType, persistentClass.getVersion() )
+		);
 	}
 
-	Map<Class<?>, EmbeddableType<?>> getEmbeddableTypes() {
-		return embeddables;
+	@SuppressWarnings( "unchecked")
+	private <X> Set<SingularAttribute<? super X, ?>> buildIdClassAttributes(
+			EntityTypeImpl<X> jpaEntityType,
+			PersistentClass persistentClass) {
+		Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>();
+		Iterator<Property> properties = persistentClass.getIdentifierMapper().getPropertyIterator();
+		while ( properties.hasNext() ) {
+			attributes.add(
+					(SingularAttribute<? super X, ?>) attributeFactory.buildAttribute( jpaEntityType, properties.next() )
+			);
+		}
+		return attributes;
 	}
+
 }

Deleted: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java	2009-10-25 19:19:48 UTC (rev 17835)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -1,349 +0,0 @@
-/*
- * Copyright (c) 2009, 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.ejb.metamodel;
-
-import java.util.Iterator;
-import javax.persistence.metamodel.Attribute;
-import javax.persistence.metamodel.ManagedType;
-import javax.persistence.metamodel.Type;
-import javax.persistence.metamodel.EmbeddableType;
-
-import org.hibernate.annotations.common.AssertionFailure;
-import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.Map;
-import org.hibernate.mapping.OneToMany;
-import org.hibernate.mapping.Property;
-import org.hibernate.mapping.Value;
-
-/**
- * @author Emmanuel Bernard
- */
-class MetamodelFactory {
-
-	static<X, Y, V, K> Attribute<X, Y> getAttribute(ManagedType<X> ownerType, Property property, MetadataContext metadataContext) {
-		return getAttribute( ownerType, property, metadataContext, false );
-	}
-
-	static<X, Y, V, K> Attribute<X, Y> getAttribute(ManagedType<X> ownerType, Property property, MetadataContext metadataContext, boolean isId) {
-		AttributeContext attrContext = getAttributeContext( property );
-		final Attribute<X, Y> attribute;
-		if ( attrContext.isCollection() ) {
-			final Type<V> attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue(), metadataContext );
-			@SuppressWarnings( "unchecked" )
-			final Class<Y> collectionClass = (Class<Y>) attrContext.getCollectionClass();
-			if ( java.util.Map.class.isAssignableFrom( collectionClass ) ) {
-				final Type<K> keyType = getType( attrContext.getKeyTypeStatus(), attrContext.getKeyValue(), metadataContext );
-				attribute = PluralAttributeImpl.create( ownerType, attrType, collectionClass, keyType )
-						// .member(  ); //TODO member
-						.property( property )
-						.persistentAttributeType( attrContext.getElementAttributeType() )
-						.build();
-			}
-			else {
-				attribute =  PluralAttributeImpl.create( ownerType, attrType, collectionClass, null )
-						// .member(  ); //TODO member
-						.property( property )
-						.persistentAttributeType( attrContext.getElementAttributeType() )
-						.build();
-			}
-		}
-		else {
-			final Type<Y> attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue(), metadataContext );
-			final SingularAttributeImpl.Builder<X, Y> xyBuilder = SingularAttributeImpl.create( ownerType, attrType )
-					// .member(  ); //TODO member
-					.property( property )
-					.persistentAttributeType( attrContext.getElementAttributeType() );
-			if (isId) xyBuilder.id();
-			attribute = xyBuilder.build();
-		}
-		return attribute;
-	}
-
-	private static <X> Type<X> getType(AttributeContext.TypeStatus elementTypeStatus, Value value, MetadataContext metadataContext) {
-		final org.hibernate.type.Type type = value.getType();
-		switch ( elementTypeStatus ) {
-			case BASIC:
-				return buildBasicType( type );
-			case EMBEDDABLE:
-				return buildEmbeddableType( value, type, metadataContext );
-			case ENTITY:
-				return buildEntityType( type, metadataContext );
-			default:
-				throw new AssertionFailure( "Unknown AttributeContext.TypeStatus: " + elementTypeStatus );
-
-		}
-	}
-
-	private static class AttributeContext {
-		private final Value elementValue;
-		private final TypeStatus typeStatus;
-		private final Class<?> collectionClass;
-		private final Attribute.PersistentAttributeType attrType;
-		private final Value keyValue;
-		private final TypeStatus keyTypeStatus;
-
-		enum TypeStatus {
-			EMBEDDABLE,
-			ENTITY,
-			BASIC
-		}
-
-		AttributeContext(Value elementValue,
-						 TypeStatus elementTypeStatus,
-						 Attribute.PersistentAttributeType elementPAT,
-						 Class<?> collectionClass,
-						 Value keyValue,
-						 TypeStatus keyTypeStatus) {
-			this.elementValue = elementValue;
-			this.typeStatus = elementTypeStatus;
-			this.collectionClass = collectionClass;
-			this.attrType = elementPAT;
-			this.keyValue = keyValue;
-			this.keyTypeStatus = keyTypeStatus;
-		}
-
-		public Value getElementValue() {
-			return elementValue;
-		}
-
-		public TypeStatus getElementTypeStatus() {
-			return typeStatus;
-		}
-
-		public boolean isCollection() {
-			return collectionClass != null;
-		}
-
-		public Class<?> getCollectionClass() {
-			return collectionClass;
-		}
-
-		public Attribute.PersistentAttributeType getElementAttributeType() {
-			return attrType;
-		}
-
-		public Value getKeyValue() {
-			return keyValue;
-		}
-
-		public TypeStatus getKeyTypeStatus() {
-			return keyTypeStatus;
-		}
-	}
-
-
-	//FIXME the logical level for *To* is different from the Hibernate physical model.
-	//ie a @ManyToOne @AssocTable is a many-to-many for hibernate
-	//and a @OneToMany @AssocTable is a many-to-many for hibernate
-	//FIXME so basically Attribute.PersistentAttributeType is crap at the moment
-	private static AttributeContext getAttributeContext(Property property) {
-		final Value value = property.getValue();
-		org.hibernate.type.Type type = value.getType();
-		if ( type.isAnyType() ) {
-			throw new UnsupportedOperationException( "any not supported yet" );
-		}
-		else if ( type.isAssociationType() ) {
-			//collection or entity
-			if ( type.isCollectionType() ) {
-				//do collection
-				if ( value instanceof Collection ) {
-					final Collection collValue = (Collection) value;
-					final Value elementValue = collValue.getElement();
-					final org.hibernate.type.Type elementType = elementValue.getType();
-					final AttributeContext.TypeStatus elementTypeStatus;
-					final Attribute.PersistentAttributeType elementPAT;
-					final Class<?> collectionClass = collValue.getCollectionType().getReturnedClass();
-
-
-					final Value keyValue;
-					final org.hibernate.type.Type keyType;
-					final AttributeContext.TypeStatus keyTypeStatus;
-					if ( value instanceof Map ) {
-						keyValue = ( (Map) value).getIndex();
-						keyType = keyValue.getType();
-						if ( keyValue instanceof Component ) {
-							keyTypeStatus = AttributeContext.TypeStatus.EMBEDDABLE;
-						}
-						else if ( keyType.isAnyType() ) {
-							throw new UnsupportedOperationException( "collection of any not supported yet" );
-						}
-						else if ( keyType.isAssociationType() ) {
-							keyTypeStatus = AttributeContext.TypeStatus.ENTITY;
-						}
-						else {
-							keyTypeStatus = AttributeContext.TypeStatus.BASIC;
-						}
-					}
-					else {
-						keyValue = null;
-						keyTypeStatus = null;
-					}
-
-					if ( elementValue instanceof Component ) {
-						//collection of components
-						elementTypeStatus = AttributeContext.TypeStatus.EMBEDDABLE;
-						elementPAT = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
-					}
-					else if ( elementType.isAnyType() ) {
-						throw new UnsupportedOperationException( "collection of any not supported yet" );
-					}
-					else if ( elementType.isAssociationType() ) {
-						//collection of entity
-						elementTypeStatus = AttributeContext.TypeStatus.ENTITY;
-						elementPAT = Attribute.PersistentAttributeType.MANY_TO_MANY;
-					}
-					else {
-						//collection of basic type
-						elementTypeStatus = AttributeContext.TypeStatus.BASIC;
-						elementPAT = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
-					}
-					return new AttributeContext(
-								elementValue,
-								elementTypeStatus,
-								elementPAT,
-								collectionClass,
-								keyValue,
-								keyTypeStatus
-						);
-				}
-				else if ( value instanceof OneToMany ) {
-					//one to many with FK => entity
-					return new AttributeContext(
-							value,
-							AttributeContext.TypeStatus.ENTITY,
-							Attribute.PersistentAttributeType.ONE_TO_MANY,
-							null, null, null );
-				}
-
-			}
-			else {
-				//ToOne association
-				return new AttributeContext(
-						value,
-						AttributeContext.TypeStatus.ENTITY,
-						Attribute.PersistentAttributeType.MANY_TO_MANY, //FIXME how to differentiate the logical many to one from the one to one (not physical level)
-						null, null, null);
-			}
-		}
-		else if ( property.isComposite() ) {
-			//embeddable
-			return new AttributeContext(
-					value,
-					AttributeContext.TypeStatus.EMBEDDABLE,
-					Attribute.PersistentAttributeType.EMBEDDED,
-					null, null, null);
-
-		}
-		else {
-			//basic type
-			return new AttributeContext(
-					value,
-					AttributeContext.TypeStatus.BASIC,
-					Attribute.PersistentAttributeType.BASIC,
-					null, null, null);
-		}
-		throw new UnsupportedOperationException("oops, we are missing something: " + property.toString() );
-	}
-
-
-
-	static <X> Type<X> getType(Property property, MetadataContext context) {
-		final Value value = property.getValue();
-		org.hibernate.type.Type type = value.getType();
-		if ( type.isAnyType() ) {
-			throw new UnsupportedOperationException( "any not supported yet" );
-		}
-		else if ( type.isAssociationType() ) {
-			//collection or entity
-			if ( type.isCollectionType() ) {
-				//do collection
-				if ( value instanceof Collection ) {
-					Collection collValue = (Collection) value;
-					collValue.getCollectionType();
-					Value elementValue = collValue.getElement();
-					final org.hibernate.type.Type elementType = elementValue.getType();
-					if ( elementValue instanceof Component ) {
-						//colelction of components
-						return buildEmbeddableType( elementValue, elementType, context );
-					}
-					else if ( elementType.isAnyType() ) {
-						throw new UnsupportedOperationException( "collection of any not supported yet" );
-					}
-					else if ( elementType.isAssociationType() ) {
-						//collection of entity
-						return buildEntityType( elementType, context);
-					}
-					else {
-						//collection of basic type
-						buildBasicType( elementType );
-					}
-				}
-				else if ( value instanceof OneToMany ) {
-					//one to many with FK => entity
-					return buildEntityType( value.getType(), context );
-				}
-				
-			}
-			else {
-				//ToOne association
-				return buildEntityType( type, context );
-			}
-		}
-		else if ( property.isComposite() ) {
-			//embeddable
-			return buildEmbeddableType( value, type, context );
-
-		}
-		else {
-			//basic type
-			return buildBasicType( type );
-		}
-		throw new UnsupportedOperationException("oops, we are missing something: " + property.toString() );
-	}
-
-	private static <X> Type<X> buildBasicType(org.hibernate.type.Type type) {
-		@SuppressWarnings( "unchecked" )
-		final Class<X> clazz = type.getReturnedClass();
-		return new BasicTypeImpl<X>( clazz, Type.PersistenceType.BASIC );
-	}
-
-	private static <X> Type<X> buildEntityType(org.hibernate.type.Type type, MetadataContext context) {
-		@SuppressWarnings( "unchecked" )
-		final Class<X> clazz = type.getReturnedClass();
-		final EntityTypeDelegator<X> entityTypeDelegator = new EntityTypeDelegator<X>();
-		context.addDelegator( entityTypeDelegator, clazz );
-		return entityTypeDelegator;
-	}
-
-	private static <X> Type<X> buildEmbeddableType(Value value, org.hibernate.type.Type type, MetadataContext context) {
-		//build embedable type
-		@SuppressWarnings( "unchecked" )
-		final Class<X> clazz = type.getReturnedClass();
-		Component component = (Component) value;
-		@SuppressWarnings( "unchecked")
-		final Iterator<Property> subProperties = component.getPropertyIterator();
-		final EmbeddableType<X> embeddableType = new EmbeddableTypeImpl<X>( clazz, subProperties, context );
-		context.addEmbeddableType( clazz, embeddableType );
-		return embeddableType;
-	}
-}

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java	2009-10-25 19:19:48 UTC (rev 17835)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -24,8 +24,6 @@
 import java.util.Set;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
 import java.util.HashSet;
 import java.io.Serializable;
 import javax.persistence.metamodel.Metamodel;
@@ -36,33 +34,56 @@
 import org.hibernate.mapping.PersistentClass;
 
 /**
+ * Hibernate implementation of the JPA {@link Metamodel} contract.
+ *
+ * @author Steve Ebersole
  * @author Emmanuel Bernard
  */
 public class MetamodelImpl implements Metamodel, Serializable {
+	private final Map<Class<?>,EntityTypeImpl<?>> entities;
+	private final Map<Class<?>, EmbeddableTypeImpl<?>> embeddables;
 
-	private final Map<Class<?>,EntityType<?>> entities;
-	private Map<Class<?>, EmbeddableType<?>> embeddables;
-
-	public MetamodelImpl(Iterator<PersistentClass> classes) {
-		Map<Class<?>,EntityType<?>> localEntities = new HashMap<Class<?>,EntityType<?>>();
+	/**
+	 * Instantiate the metamodel from the collection of Hibernate {@link PersistentClass} models.
+	 *
+	 * @param persistentClasses An iterator over the Hibernate {@link PersistentClass} models.
+	 */
+	public MetamodelImpl(Iterator<PersistentClass> persistentClasses) {
 		MetadataContext context = new MetadataContext();
-		while ( classes.hasNext() ) {
-			buildEntityType( classes, localEntities, context );
+		while ( persistentClasses.hasNext() ) {
+			locateOrBuildEntityType( persistentClasses.next(), context );
 		}
-		this.entities = Collections.unmodifiableMap( localEntities );
-		this.embeddables = Collections.unmodifiableMap( context.getEmbeddableTypes() );
-		context.postProcess( this );
+		this.entities = context.getEntityTypeMap();
+		context.wrapUp();
+		this.embeddables = context.getEmbeddableTypeMap();
 	}
 
-	private <X> void buildEntityType(Iterator<PersistentClass> classes, Map<Class<?>, EntityType<?>> localEntities, MetadataContext context) {
-		PersistentClass persistentClass = classes.next();
-		@SuppressWarnings( "unchecked" )
-		final Class<X> clazz = persistentClass.getMappedClass();
-		if ( clazz != null ) {
-			localEntities.put( clazz, new EntityTypeImpl<X>(clazz, persistentClass, context) );
+	private EntityTypeImpl<?> locateOrBuildEntityType(PersistentClass persistentClass, MetadataContext context) {
+		EntityTypeImpl<?> entityType = context.locateEntityType( persistentClass );
+		if ( entityType == null ) {
+			entityType = buildEntityType( persistentClass, context );
 		}
+		return entityType;
 	}
 
+	@SuppressWarnings({ "unchecked" })
+	private EntityTypeImpl<?> buildEntityType(PersistentClass persistentClass, MetadataContext context) {
+		final PersistentClass superPersistentClass = persistentClass.getSuperclass();
+		final EntityTypeImpl superEntityType = superPersistentClass == null
+				? null
+				: locateOrBuildEntityType( superPersistentClass, context );
+		final Class javaType = persistentClass.getMappedClass();
+		EntityTypeImpl entityType = new EntityTypeImpl(
+				javaType,
+				superEntityType,
+				persistentClass.getClassName(),
+				persistentClass.hasIdentifierProperty(),
+				persistentClass.isVersioned()
+		);
+		context.registerEntityType( persistentClass, entityType );
+		return entityType;
+	}
+
 	/**
 	 * {@inheritDoc}
 	 */

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java	2009-10-25 19:19:48 UTC (rev 17835)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -21,47 +21,45 @@
  */
 package org.hibernate.ejb.metamodel;
 
+import java.io.Serializable;
 import java.lang.reflect.Member;
-import java.util.Map;
+import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
-import java.util.Collection;
-import java.io.Serializable;
-import javax.persistence.metamodel.PluralAttribute;
-import javax.persistence.metamodel.ManagedType;
-import javax.persistence.metamodel.Type;
-import javax.persistence.metamodel.SetAttribute;
 import javax.persistence.metamodel.CollectionAttribute;
 import javax.persistence.metamodel.ListAttribute;
 import javax.persistence.metamodel.MapAttribute;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.SetAttribute;
+import javax.persistence.metamodel.Type;
 
 import org.hibernate.mapping.Property;
 
 /**
  * @author Emmanuel Bernard
+ * @author Steve Ebersole
  */
-public abstract class PluralAttributeImpl<X, C, E> implements PluralAttribute<X, C, E>, Serializable {
+public abstract class PluralAttributeImpl<X, C, E>
+		extends AbstractAttribute<X,C>
+		implements PluralAttribute<X, C, E>, Serializable {
 
-	private final ManagedType<X> ownerType;
 	private final Type<E> elementType;
-	//FIXME member is not serializable
-	private final Member member;
-	private final String name;
-	private final PersistentAttributeType persistentAttributeType;
-	private final Class<C> collectionClass;
 
 	private PluralAttributeImpl(Builder<X,C,E,?> builder) {
-		this.ownerType = builder.type;
+		super(
+				builder.property.getName(),
+				builder.collectionClass,
+				builder.type,
+				builder.member,
+				builder.persistentAttributeType
+		);
 		this.elementType = builder.attributeType;
-		this.collectionClass = builder.collectionClass;
-		this.member = builder.member;
-		this.name = builder.property.getName();
-		this.persistentAttributeType = builder.persistentAttributeType;
 	}
 
 	public static class Builder<X, C, E, K> {
 		private final Type<E> attributeType;
-		private final ManagedType<X> type;
+		private final AbstractManagedType<X> type;
 		private Member member;
 		private PersistentAttributeType persistentAttributeType;
 		private Property property;
@@ -69,7 +67,7 @@
 		private Type<K> keyType;
 
 
-		private Builder(ManagedType<X> ownerType, Type<E> attrType, Class<C> collectionClass, Type<K> keyType) {
+		private Builder(AbstractManagedType<X> ownerType, Type<E> attrType, Class<C> collectionClass, Type<K> keyType) {
 			this.type = ownerType;
 			this.attributeType = attrType;
 			this.collectionClass = collectionClass;
@@ -91,94 +89,75 @@
 			return this;
 		}
 
+		@SuppressWarnings( "unchecked" )
 		public <K> PluralAttributeImpl<X,C,E> build() {
 			if ( Map.class.isAssignableFrom( collectionClass ) ) {
-				@SuppressWarnings( "unchecked" )
 				final Builder<X,Map<K,E>,E,K> builder = (Builder<X,Map<K,E>,E,K>) this;
-				@SuppressWarnings( "unchecked" )
-				final PluralAttributeImpl<X, C, E> result = ( PluralAttributeImpl<X, C, E> ) new MapAttributeImpl<X,K,E>(
+				return ( PluralAttributeImpl<X, C, E> ) new MapAttributeImpl<X,K,E>(
 						builder
 				);
-				return result;
 			}
 			else if ( Set.class.isAssignableFrom( collectionClass ) ) {
-				@SuppressWarnings( "unchecked" )
 				final Builder<X,Set<E>, E,?> builder = (Builder<X, Set<E>, E,?>) this;
-				@SuppressWarnings( "unchecked" )
-				final PluralAttributeImpl<X, C, E> result = ( PluralAttributeImpl<X, C, E> ) new SetAttributeImpl<X,E>(
+				return ( PluralAttributeImpl<X, C, E> ) new SetAttributeImpl<X,E>(
 						builder
 				);
-				return result;
 			}
 			else if ( List.class.isAssignableFrom( collectionClass ) ) {
-				@SuppressWarnings( "unchecked" )
 				final Builder<X, List<E>, E,?> builder = (Builder<X, List<E>, E,?>) this;
-				@SuppressWarnings( "unchecked" )
-				final PluralAttributeImpl<X, C, E> result = ( PluralAttributeImpl<X, C, E> ) new ListAttributeImpl<X,E>(
+				return ( PluralAttributeImpl<X, C, E> ) new ListAttributeImpl<X,E>(
 						builder
 				);
-				return result;
 			}
 			else if ( Collection.class.isAssignableFrom( collectionClass ) ) {
-				@SuppressWarnings( "unchecked" )
 				final Builder<X, Collection<E>,E,?> builder = (Builder<X, Collection<E>, E,?>) this;
-				@SuppressWarnings( "unchecked" )
-				final PluralAttributeImpl<X, C, E> result = ( PluralAttributeImpl<X, C, E> ) new CollectionAttributeImpl<X, E>(
+				return ( PluralAttributeImpl<X, C, E> ) new CollectionAttributeImpl<X, E>(
 						builder
 				);
-				return result;
 			}
 			throw new UnsupportedOperationException( "Unkown collection: " + collectionClass );
 		}
 	}
 
 	public static <X,C,E,K> Builder<X,C,E,K> create(
-			ManagedType<X> ownerType,
+			AbstractManagedType<X> ownerType,
 			Type<E> attrType,
 			Class<C> collectionClass,
 			Type<K> keyType) {
 		return new Builder<X,C,E,K>(ownerType, attrType, collectionClass, keyType);
 	}
 
-	public String getName() {
-		return name;
-	}
-
-	public PersistentAttributeType getPersistentAttributeType() {
-		return persistentAttributeType;
-	}
-
-	public ManagedType<X> getDeclaringType() {
-		return ownerType;
-	}
-
-	public Class<C> getJavaType() {
-		return collectionClass;
-	}
-
-	public abstract CollectionType getCollectionType();
-
+	/**
+	 * {@inheritDoc}
+	 */
 	public Type<E> getElementType() {
 		return elementType;
 	}
 
-
-	public Member getJavaMember() {
-		return member;
-	}
-
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean isAssociation() {
 		return true;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean isCollection() {
 		return true;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public BindableType getBindableType() {
 		return BindableType.PLURAL_ATTRIBUTE;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public Class<E> getBindableJavaType() {
 		return elementType.getJavaType();
 	}
@@ -188,6 +167,9 @@
 			super( xceBuilder );
 		}
 
+		/**
+		 * {@inheritDoc}
+		 */
 		public CollectionType getCollectionType() {
 			return CollectionType.SET;
 		}
@@ -198,6 +180,9 @@
 			super( xceBuilder );
 		}
 
+		/**
+		 * {@inheritDoc}
+		 */
 		public CollectionType getCollectionType() {
 			return CollectionType.COLLECTION;
 		}
@@ -208,6 +193,9 @@
 			super( xceBuilder );
 		}
 
+		/**
+		 * {@inheritDoc}
+		 */
 		public CollectionType getCollectionType() {
 			return CollectionType.LIST;
 		}
@@ -221,14 +209,23 @@
 			this.keyType = xceBuilder.keyType;
 		}
 
+		/**
+		 * {@inheritDoc}
+		 */
 		public CollectionType getCollectionType() {
 			return CollectionType.MAP;
 		}
 
+		/**
+		 * {@inheritDoc}
+		 */
 		public Class<K> getKeyJavaType() {
 			return keyType.getJavaType();
 		}
 
+		/**
+		 * {@inheritDoc}
+		 */
 		public Type<K> getKeyType() {
 			return keyType;
 		}

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java	2009-10-25 19:19:48 UTC (rev 17835)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java	2009-10-26 05:23:40 UTC (rev 17836)
@@ -23,145 +23,123 @@
 
 import java.lang.reflect.Member;
 import java.io.Serializable;
-import javax.persistence.metamodel.ManagedType;
 import javax.persistence.metamodel.SingularAttribute;
 import javax.persistence.metamodel.Type;
 
-import org.hibernate.mapping.Property;
-
 /**
  * @author Emmanuel Bernard
+ * @author Steve Ebersole
  */
-public class SingularAttributeImpl<X, Y> implements SingularAttribute<X, Y>, Serializable {
-	private final boolean isId;
+public class SingularAttributeImpl<X, Y>
+		extends AbstractAttribute<X,Y>
+		implements SingularAttribute<X, Y>, Serializable {
+	private final boolean isIdentifier;
 	private final boolean isVersion;
 	private final boolean isOptional;
-	private final ManagedType<X> ownerType;
-	private final Type<Y> attrType;
-	//FIXME member is not serializable
-	private final Member member;
-	private final String name;
-	private final PersistentAttributeType persistentAttributeType;
+	private final Type<Y> attributeType;
 
-	private SingularAttributeImpl(Builder<X,Y> builder) {
-		this.ownerType = builder.type;
-		this.attrType = builder.attributeType;
-		this.isId = builder.isId;
-		this.isVersion = builder.isVersion;
-		final Property property = builder.property;
-		this.isOptional = property.isOptional();
-		this.member = builder.member;
-		this.name = property.getName();
-		if ( builder.persistentAttributeType != null) {
-			this.persistentAttributeType = builder.persistentAttributeType;
-		}
-		else {
-			this.persistentAttributeType = property.isComposite() ?
-														PersistentAttributeType.EMBEDDED :
-														PersistentAttributeType.BASIC;
-		}
+	public SingularAttributeImpl(
+			String name,
+			Class<Y> javaType,
+			AbstractManagedType<X> declaringType,
+			Member member,
+			boolean isIdentifier,
+			boolean isVersion,
+			boolean isOptional,
+			Type<Y> attributeType,
+			PersistentAttributeType persistentAttributeType) {
+		super( name, javaType, declaringType, member, persistentAttributeType );
+		this.isIdentifier = isIdentifier;
+		this.isVersion = isVersion;
+		this.isOptional = isOptional;
+		this.attributeType = attributeType;
 	}
 
-	public static class Builder<X,Y> {
-		private boolean isId;
-		private boolean isVersion;
-		//private boolean isOptional = true;
-		private final Type<Y> attributeType;
-		private final ManagedType<X> type;
-		private Member member;
-		//private String name;
-		private PersistentAttributeType persistentAttributeType;
-		private Property property;
-
-
-		private Builder(ManagedType<X> ownerType, Type<Y> attrType) {
-			this.type = ownerType;
-			this.attributeType = attrType;
+	/**
+	 * Subclass used to simply instantiation of singular attributes representing an entity's
+	 * identifier.
+	 */
+	public static class Identifier<X,Y> extends SingularAttributeImpl<X,Y> {
+		public Identifier(
+				String name,
+				Class<Y> javaType,
+				AbstractManagedType<X> declaringType,
+				Member member,
+				Type<Y> attributeType,
+				PersistentAttributeType persistentAttributeType) {
+			super( name, javaType, declaringType, member, true, false, false, attributeType, persistentAttributeType );
 		}
+	}
 
-		public Builder<X,Y> member(Member member) {
-			this.member = member;
-			return this;
+	/**
+	 * Subclass used to simply instantiation of singular attributes representing an entity's
+	 * version.
+	 */
+	public static class Version<X,Y> extends SingularAttributeImpl<X,Y> {
+		public Version(
+				String name,
+				Class<Y> javaType,
+				AbstractManagedType<X> declaringType,
+				Member member,
+				Type<Y> attributeType,
+				PersistentAttributeType persistentAttributeType) {
+			super( name, javaType, declaringType, member, false, true, false, attributeType, persistentAttributeType );
 		}
-
-		public Builder<X, Y> property(Property property) {
-			this.property = property;
-			return this;
-		}
-
-		public Builder<X,Y> id() {
-			isId = true;
-			return this;
-		}
-
-		public Builder<X,Y> version() {
-			isVersion = true;
-			return this;
-		}
-
-		public SingularAttribute<X, Y> build() {
-			return new SingularAttributeImpl<X,Y>(this);
-		}
-
-		public Builder<X, Y> persistentAttributeType(PersistentAttributeType attrType) {
-			this.persistentAttributeType = attrType;
-			return this;
-		}
 	}
 
-	public static <X,Y> Builder<X,Y> create(ManagedType<X> ownerType, Type<Y> attrType) {
-		return new Builder<X,Y>(ownerType, attrType);
-	}
-
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean isId() {
-		return isId;
+		return isIdentifier;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean isVersion() {
 		return isVersion;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean isOptional() {
 		return isOptional;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public Type<Y> getType() {
-		return attrType;
+		return attributeType;
 	}
 
-	public String getName() {
-		return name;
-	}
-
-	public PersistentAttributeType getPersistentAttributeType() {
-		return persistentAttributeType;
-	}
-
-	public ManagedType<X> getDeclaringType() {
-		return ownerType;
-	}
-
-	public Class<Y> getJavaType() {
-		return attrType.getJavaType();
-	}
-
-	public Member getJavaMember() {
-		return member;
-	}
-
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean isAssociation() {
 		return false;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public boolean isCollection() {
 		return false;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public BindableType getBindableType() {
 		return BindableType.SINGULAR_ATTRIBUTE;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public Class<Y> getBindableJavaType() {
-		return attrType.getJavaType();
+		return attributeType.getJavaType();
 	}
 }



More information about the hibernate-commits mailing list