HHH-6480 - Develop component binding for new metamodel

This commit is contained in:
Steve Ebersole 2011-07-25 14:16:48 -05:00
parent 605ce4ba29
commit e540089783
39 changed files with 968 additions and 209 deletions

View File

@ -87,8 +87,8 @@ public class CacheDataDescriptionImpl implements CacheDataDescription {
public static CacheDataDescriptionImpl decode(AbstractPluralAttributeBinding model) { public static CacheDataDescriptionImpl decode(AbstractPluralAttributeBinding model) {
return new CacheDataDescriptionImpl( return new CacheDataDescriptionImpl(
model.isMutable(), model.isMutable(),
model.getEntityBinding().isVersioned(), model.getContainer().seekEntityBinding().isVersioned(),
getVersionComparator( model.getEntityBinding() ) getVersionComparator( model.getContainer().seekEntityBinding() )
); );
} }

View File

@ -36,7 +36,7 @@ import org.hibernate.metamodel.source.MetaAttributeContext;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public abstract class AbstractAttributeBinding implements AttributeBinding { public abstract class AbstractAttributeBinding implements AttributeBinding {
private final EntityBinding entityBinding; private final AttributeBindingContainer container;
private final Attribute attribute; private final Attribute attribute;
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
@ -50,14 +50,14 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
private MetaAttributeContext metaAttributeContext; private MetaAttributeContext metaAttributeContext;
protected AbstractAttributeBinding(EntityBinding entityBinding, Attribute attribute) { protected AbstractAttributeBinding(AttributeBindingContainer container, Attribute attribute) {
this.entityBinding = entityBinding; this.container = container;
this.attribute = attribute; this.attribute = attribute;
} }
@Override @Override
public EntityBinding getEntityBinding() { public AttributeBindingContainer getContainer() {
return entityBinding; return container;
} }
@Override @Override
@ -93,18 +93,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
this.includedInOptimisticLocking = includedInOptimisticLocking; this.includedInOptimisticLocking = includedInOptimisticLocking;
} }
protected boolean forceNonNullable() {
return false;
}
protected boolean forceUnique() {
return false;
}
protected final boolean isPrimaryKey() {
return this == getEntityBinding().getHierarchyDetails().getEntityIdentifier().getValueBinding();
}
@Override @Override
public MetaAttributeContext getMetaAttributeContext() { public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext; return metaAttributeContext;

View File

@ -0,0 +1,114 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.SingularAttribute;
/**
* @author Steve Ebersole
*/
public abstract class AbstractAttributeBindingContainer implements AttributeBindingContainer {
private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
protected void registerAttributeBinding(String name, AttributeBinding attributeBinding) {
attributeBindingMap.put( name, attributeBinding );
}
@Override
public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute) {
return makeSimpleAttributeBinding( attribute, false, false );
}
private SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute, boolean forceNonNullable, boolean forceUnique) {
final SimpleSingularAttributeBinding binding = new SimpleSingularAttributeBinding(
this,
attribute,
forceNonNullable,
forceUnique
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public ComponentAttributeBinding makeComponentAttributeBinding(SingularAttribute attribute) {
final ComponentAttributeBinding binding = new ComponentAttributeBinding( this, attribute );
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) {
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute );
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature) {
final BagBinding binding = new BagBinding( this, attribute, nature );
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public AttributeBinding locateAttributeBinding(String name) {
return attributeBindingMap.get( name );
}
@Override
public Iterable<AttributeBinding> attributeBindings() {
return attributeBindingMap.values();
}
/**
* Gets the number of attribute bindings defined on this class, including the
* identifier attribute binding and attribute bindings defined
* as part of a join.
*
* @return The number of attribute bindings
*/
public int getAttributeBindingClosureSpan() {
// TODO: fix this after HHH-6337 is fixed; for now just return size of attributeBindingMap
// if this is not a root, then need to include the superclass attribute bindings
return attributeBindingMap.size();
}
/**
* Gets the attribute bindings defined on this class, including the
* identifier attribute binding and attribute bindings defined
* as part of a join.
*
* @return The attribute bindings.
*/
public Iterable<AttributeBinding> getAttributeBindingClosure() {
// TODO: fix this after HHH-6337 is fixed. for now, just return attributeBindings
// if this is not a root, then need to include the superclass attribute bindings
return attributeBindings();
}
}

View File

@ -77,10 +77,10 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi
private String loaderName; private String loaderName;
protected AbstractPluralAttributeBinding( protected AbstractPluralAttributeBinding(
EntityBinding entityBinding, AttributeBindingContainer container,
PluralAttribute attribute, PluralAttribute attribute,
CollectionElementNature collectionElementNature) { CollectionElementNature collectionElementNature) {
super( entityBinding, attribute ); super( container, attribute );
this.collectionElement = interpretNature( collectionElementNature ); this.collectionElement = interpretNature( collectionElementNature );
} }

View File

@ -45,8 +45,8 @@ public abstract class AbstractSingularAttributeBinding
private boolean hasDerivedValue; private boolean hasDerivedValue;
private boolean isNullable = true; private boolean isNullable = true;
protected AbstractSingularAttributeBinding(EntityBinding entityBinding, SingularAttribute attribute) { protected AbstractSingularAttributeBinding(AttributeBindingContainer container, SingularAttribute attribute) {
super( entityBinding, attribute ); super( container, attribute );
} }
@Override @Override
@ -79,7 +79,7 @@ public abstract class AbstractSingularAttributeBinding
} }
private String getRole() { private String getRole() {
return getEntityBinding().getEntity().getName() + '.' + getAttribute().getName(); return getContainer().getPathBase() + '.' + getAttribute().getName();
} }
@Override @Override
@ -88,7 +88,7 @@ public abstract class AbstractSingularAttributeBinding
return simpleValueBindings.size(); return simpleValueBindings.size();
} }
private void checkValueBinding() { protected void checkValueBinding() {
if ( value == null ) { if ( value == null ) {
throw new AssertionFailure( "No values yet bound!" ); throw new AssertionFailure( "No values yet bound!" );
} }

View File

@ -39,7 +39,7 @@ public interface AttributeBinding {
* *
* @return The entity binding. * @return The entity binding.
*/ */
public EntityBinding getEntityBinding(); public AttributeBindingContainer getContainer();
/** /**
* Obtain the attribute bound. * Obtain the attribute bound.

View File

@ -0,0 +1,61 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
import org.hibernate.metamodel.domain.AttributeContainer;
import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.source.MetaAttributeContext;
/**
* @author Steve Ebersole
*/
public interface AttributeBindingContainer {
public String getPathBase();
public AttributeContainer getAttributeContainer();
public Iterable<AttributeBinding> attributeBindings();
public AttributeBinding locateAttributeBinding(String name);
public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute);
public ComponentAttributeBinding makeComponentAttributeBinding(SingularAttribute attribute);
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute);
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature);
public EntityBinding seekEntityBinding();
public TableSpecification getPrimaryTable();
public TableSpecification locateTable(String containingTableName);
public Class<?> getClassReference();
public MetaAttributeContext getMetaAttributeContext();
}

View File

@ -31,7 +31,7 @@ import org.hibernate.metamodel.domain.PluralAttribute;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class BagBinding extends AbstractPluralAttributeBinding { public class BagBinding extends AbstractPluralAttributeBinding {
protected BagBinding(EntityBinding entityBinding, PluralAttribute attribute, CollectionElementNature nature) { protected BagBinding(AttributeBindingContainer container, PluralAttribute attribute, CollectionElementNature nature) {
super( entityBinding, attribute, nature ); super( container, attribute, nature );
} }
} }

View File

@ -0,0 +1,167 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.domain.AttributeContainer;
import org.hibernate.metamodel.domain.Component;
import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.source.MetaAttributeContext;
/**
* @author Steve Ebersole
*/
public class ComponentAttributeBinding extends AbstractSingularAttributeBinding implements AttributeBindingContainer {
private final String path;
private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
private SingularAttribute parentReference;
private MetaAttributeContext metaAttributeContext;
public ComponentAttributeBinding(AttributeBindingContainer container, SingularAttribute attribute) {
super( container, attribute );
this.path = container.getPathBase() + '.' + attribute.getName();
}
@Override
public EntityBinding seekEntityBinding() {
return getContainer().seekEntityBinding();
}
@Override
public String getPathBase() {
return path;
}
@Override
public AttributeContainer getAttributeContainer() {
return getComponent();
}
public Component getComponent() {
return (Component) getAttribute().getSingularAttributeType();
}
@Override
public boolean isAssociation() {
return false;
}
@Override
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
}
public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) {
this.metaAttributeContext = metaAttributeContext;
}
@Override
public TableSpecification getPrimaryTable() {
return getContainer().getPrimaryTable();
}
@Override
public TableSpecification locateTable(String containingTableName) {
return getContainer().locateTable( containingTableName );
}
@Override
public AttributeBinding locateAttributeBinding(String name) {
return attributeBindingMap.get( name );
}
@Override
public Iterable<AttributeBinding> attributeBindings() {
return attributeBindingMap.values();
}
@Override
protected void checkValueBinding() {
// do nothing here...
}
@Override
public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute) {
final SimpleSingularAttributeBinding binding = new SimpleSingularAttributeBinding(
this,
attribute,
isNullable(),
isAlternateUniqueKey() // todo : is this accurate?
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
protected void registerAttributeBinding(String name, AttributeBinding attributeBinding) {
// todo : hook this into the EntityBinding notion of "entity referencing attribute bindings"
attributeBindingMap.put( name, attributeBinding );
}
@Override
public ComponentAttributeBinding makeComponentAttributeBinding(SingularAttribute attribute) {
final ComponentAttributeBinding binding = new ComponentAttributeBinding( this, attribute );
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) {
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute );
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature) {
final BagBinding binding = new BagBinding( this, attribute, nature );
registerAttributeBinding( attribute.getName(), binding );
return binding;
}
@Override
public Class<?> getClassReference() {
return getComponent().getClassReference();
}
public SingularAttribute getParentReference() {
return parentReference;
}
public void setParentReference(SingularAttribute parentReference) {
this.parentReference = parentReference;
}
@Override
public PropertyGeneration getGeneration() {
// todo : not sure the correct thing to return here since it essentially relies on the simple sub-attributes.
return null;
}
}

View File

@ -32,9 +32,8 @@ import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.util.Value; import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.domain.AttributeContainer;
import org.hibernate.metamodel.domain.Entity; import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.TableSpecification; import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.source.MetaAttributeContext; import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
@ -47,7 +46,7 @@ import org.hibernate.tuple.entity.EntityTuplizer;
* @author Hardy Ferentschik * @author Hardy Ferentschik
* @author Gail Badner * @author Gail Badner
*/ */
public class EntityBinding { public class EntityBinding extends AbstractAttributeBindingContainer {
private final EntityBinding superEntityBinding; private final EntityBinding superEntityBinding;
private final HierarchyDetails hierarchyDetails; private final HierarchyDetails hierarchyDetails;
@ -64,12 +63,9 @@ public class EntityBinding {
private String discriminatorMatchValue; private String discriminatorMatchValue;
private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
private Set<FilterDefinition> filterDefinitions = new HashSet<FilterDefinition>(); private Set<FilterDefinition> filterDefinitions = new HashSet<FilterDefinition>();
private Set<SingularAssociationAttributeBinding> entityReferencingAttributeBindings = new HashSet<SingularAssociationAttributeBinding>(); private Set<SingularAssociationAttributeBinding> entityReferencingAttributeBindings = new HashSet<SingularAssociationAttributeBinding>();
private MetaAttributeContext metaAttributeContext; private MetaAttributeContext metaAttributeContext;
private boolean lazy; private boolean lazy;
@ -135,7 +131,8 @@ public class EntityBinding {
this.entity = entity; this.entity = entity;
} }
public TableSpecification getBaseTable() { @Override
public TableSpecification getPrimaryTable() {
return baseTable; return baseTable;
} }
@ -143,7 +140,7 @@ public class EntityBinding {
this.baseTable = baseTable; this.baseTable = baseTable;
} }
public TableSpecification getTable(String tableName) { public TableSpecification locateTable(String tableName) {
if ( tableName == null ) { if ( tableName == null ) {
return baseTable; return baseTable;
} }
@ -171,40 +168,6 @@ public class EntityBinding {
this.discriminatorMatchValue = discriminatorMatchValue; this.discriminatorMatchValue = discriminatorMatchValue;
} }
public Iterable<AttributeBinding> getAttributeBindings() {
return attributeBindingMap.values();
}
public AttributeBinding getAttributeBinding(String name) {
return attributeBindingMap.get( name );
}
/**
* Gets the number of attribute bindings defined on this class, including the
* identifier attribute binding and attribute bindings defined
* as part of a join.
*
* @return The number of attribute bindings
*/
public int getAttributeBindingClosureSpan() {
// TODO: fix this after HHH-6337 is fixed; for now just return size of attributeBindingMap
// if this is not a root, then need to include the superclass attribute bindings
return attributeBindingMap.size();
}
/**
* Gets the attribute bindings defined on this class, including the
* identifier attribute binding and attribute bindings defined
* as part of a join.
*
* @return The attribute bindings.
*/
public Iterable<AttributeBinding> getAttributeBindingClosure() {
// TODO: fix this after HHH-6337 is fixed. for now, just return attributeBindings
// if this is not a root, then need to include the superclass attribute bindings
return getAttributeBindings();
}
public Iterable<FilterDefinition> getFilterDefinitions() { public Iterable<FilterDefinition> getFilterDefinitions() {
return filterDefinitions; return filterDefinitions;
} }
@ -217,42 +180,35 @@ public class EntityBinding {
return entityReferencingAttributeBindings; return entityReferencingAttributeBindings;
} }
public SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute) { @Override
return makeSimpleAttributeBinding( attribute, false, false ); public EntityBinding seekEntityBinding() {
return this;
} }
private SimpleSingularAttributeBinding makeSimpleAttributeBinding(SingularAttribute attribute, boolean forceNonNullable, boolean forceUnique) { @Override
final SimpleSingularAttributeBinding binding = new SimpleSingularAttributeBinding( public String getPathBase() {
this, return getEntity().getName();
attribute,
forceNonNullable,
forceUnique
);
registerAttributeBinding( attribute.getName(), binding );
return binding;
} }
public ManyToOneAttributeBinding makeManyToOneAttributeBinding(SingularAttribute attribute) { @Override
final ManyToOneAttributeBinding binding = new ManyToOneAttributeBinding( this, attribute ); public Class<?> getClassReference() {
registerAttributeBinding( attribute.getName(), binding ); return getEntity().getClassReference();
return binding;
} }
public BagBinding makeBagAttributeBinding(PluralAttribute attribute, CollectionElementNature nature) { @Override
final BagBinding binding = new BagBinding( this, attribute, nature ); public AttributeContainer getAttributeContainer() {
registerAttributeBinding( attribute.getName(), binding ); return getEntity();
return binding;
} }
private void registerAttributeBinding(String name, SingularAssociationAttributeBinding attributeBinding) { @Override
entityReferencingAttributeBindings.add( attributeBinding ); protected void registerAttributeBinding(String name, AttributeBinding attributeBinding) {
registerAttributeBinding( name, (AttributeBinding) attributeBinding ); if ( SingularAssociationAttributeBinding.class.isInstance( attributeBinding ) ) {
} entityReferencingAttributeBindings.add( (SingularAssociationAttributeBinding) attributeBinding );
}
private void registerAttributeBinding(String name, AttributeBinding attributeBinding) { super.registerAttributeBinding( name, attributeBinding );
attributeBindingMap.put( name, attributeBinding );
} }
@Override
public MetaAttributeContext getMetaAttributeContext() { public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext; return metaAttributeContext;
} }

View File

@ -26,6 +26,7 @@ package org.hibernate.metamodel.binding;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode; import org.hibernate.FetchMode;
import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.domain.SingularAttribute;
@ -47,8 +48,8 @@ public class ManyToOneAttributeBinding extends SimpleSingularAttributeBinding im
private CascadeStyle cascadeStyle; private CascadeStyle cascadeStyle;
private FetchMode fetchMode; private FetchMode fetchMode;
ManyToOneAttributeBinding(EntityBinding entityBinding, SingularAttribute attribute) { ManyToOneAttributeBinding(AttributeBindingContainer container, SingularAttribute attribute) {
super( entityBinding, attribute, false, false ); super( container, attribute, false, false );
} }
@Override @Override
@ -124,10 +125,14 @@ public class ManyToOneAttributeBinding extends SimpleSingularAttributeBinding im
@Override @Override
public final void resolveReference(AttributeBinding referencedAttributeBinding) { public final void resolveReference(AttributeBinding referencedAttributeBinding) {
if ( !referencedEntityName.equals( referencedAttributeBinding.getEntityBinding().getEntity().getName() ) ) { if ( ! EntityBinding.class.isInstance( referencedAttributeBinding.getContainer() ) ) {
throw new AssertionFailure( "Illegal attempt to resolve many-to-one reference based on non-entity attribute" );
}
final EntityBinding entityBinding = (EntityBinding) referencedAttributeBinding.getContainer();
if ( !referencedEntityName.equals( entityBinding.getEntity().getName() ) ) {
throw new IllegalStateException( throw new IllegalStateException(
"attempt to set EntityBinding with name: [" + "attempt to set EntityBinding with name: [" +
referencedAttributeBinding.getEntityBinding().getEntity().getName() + entityBinding.getEntity().getName() +
"; entity name should be: " + referencedEntityName "; entity name should be: " + referencedEntityName
); );
} }
@ -154,7 +159,7 @@ public class ManyToOneAttributeBinding extends SimpleSingularAttributeBinding im
@Override @Override
public final EntityBinding getReferencedEntityBinding() { public final EntityBinding getReferencedEntityBinding() {
return referencedAttributeBinding.getEntityBinding(); return (EntityBinding) referencedAttributeBinding.getContainer();
} }
// private void buildForeignKey() { // private void buildForeignKey() {

View File

@ -56,11 +56,11 @@ public class SimpleSingularAttributeBinding
private MetaAttributeContext metaAttributeContext; private MetaAttributeContext metaAttributeContext;
SimpleSingularAttributeBinding( SimpleSingularAttributeBinding(
EntityBinding entityBinding, AttributeBindingContainer container,
SingularAttribute attribute, SingularAttribute attribute,
boolean forceNonNullable, boolean forceNonNullable,
boolean forceUnique) { boolean forceUnique) {
super( entityBinding, attribute ); super( container, attribute );
this.forceNonNullable = forceNonNullable; this.forceNonNullable = forceNonNullable;
this.forceUnique = forceUnique; this.forceUnique = forceUnique;
} }
@ -144,7 +144,7 @@ public class SimpleSingularAttributeBinding
// TODO: not sure how this works for collection IDs... // TODO: not sure how this works for collection IDs...
//pass the entity-name, if not a collection-id //pass the entity-name, if not a collection-id
//if ( rootClass!=null) { //if ( rootClass!=null) {
params.setProperty( IdentifierGenerator.ENTITY_NAME, getEntityBinding().getEntity().getName() ); params.setProperty( IdentifierGenerator.ENTITY_NAME, getContainer().seekEntityBinding().getEntity().getName() );
//} //}
//init the table here instead of earlier, so that we can get a quoted table name //init the table here instead of earlier, so that we can get a quoted table name

View File

@ -112,7 +112,8 @@ public abstract class AbstractAttributeContainer implements AttributeContainer,
@Override @Override
public SingularAttribute createComponentAttribute(String name, Component component) { public SingularAttribute createComponentAttribute(String name, Component component) {
SingularAttributeImpl attribute = new SingularAttributeImpl( name, component ); SingularAttributeImpl attribute = new SingularAttributeImpl( name, this );
attribute.resolveType( component );
addAttribute( attribute ); addAttribute( attribute );
return attribute; return attribute;
} }

View File

@ -58,11 +58,13 @@ public class EntitySourceImpl implements EntitySource {
private final EntityClass entityClass; private final EntityClass entityClass;
private final Set<SubclassEntitySource> subclassEntitySources; private final Set<SubclassEntitySource> subclassEntitySources;
private final Origin origin; private final Origin origin;
private final LocalBindingContextImpl localBindingContext;
public EntitySourceImpl(EntityClass entityClass) { public EntitySourceImpl(EntityClass entityClass) {
this.entityClass = entityClass; this.entityClass = entityClass;
this.subclassEntitySources = new HashSet<SubclassEntitySource>(); this.subclassEntitySources = new HashSet<SubclassEntitySource>();
this.origin = new Origin( SourceType.ANNOTATION, entityClass.getName() ); this.origin = new Origin( SourceType.ANNOTATION, entityClass.getName() );
this.localBindingContext = new LocalBindingContextImpl( entityClass.getContext() );
} }
public EntityClass getEntityClass() { public EntityClass getEntityClass() {
@ -75,8 +77,8 @@ public class EntitySourceImpl implements EntitySource {
} }
@Override @Override
public LocalBindingContext getBindingContext() { public LocalBindingContext getLocalBindingContext() {
return new LocalBindingContextImpl( entityClass.getContext() ); return localBindingContext;
} }
@Override @Override
@ -174,6 +176,11 @@ public class EntitySourceImpl implements EntitySource {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override
public String getPath() {
return entityClass.getName();
}
@Override @Override
public Iterable<AttributeSource> attributeSources() { public Iterable<AttributeSource> attributeSources() {
List<AttributeSource> attributeList = new ArrayList<AttributeSource>(); List<AttributeSource> attributeList = new ArrayList<AttributeSource>();

View File

@ -23,6 +23,8 @@
*/ */
package org.hibernate.metamodel.source.binder; package org.hibernate.metamodel.source.binder;
import org.hibernate.metamodel.source.LocalBindingContext;
/** /**
* Contract for a container of {@link AttributeSource} references. Both entities and components contain * Contract for a container of {@link AttributeSource} references. Both entities and components contain
* attributes. * attributes.
@ -31,9 +33,23 @@ package org.hibernate.metamodel.source.binder;
*/ */
public interface AttributeSourceContainer { public interface AttributeSourceContainer {
/** /**
Obtain this container's attribute sources. * Obtain the path used to uniquely identify this container.
* *
* @return TYhe attribute sources. * @return The unique identifier path
*/
public String getPath();
/**
* Obtain this container's attribute sources.
*
* @return The attribute sources.
*/ */
public Iterable<AttributeSource> attributeSources(); public Iterable<AttributeSource> attributeSources();
/**
* Obtain the local binding context associated with this container.
*
* @return The local binding context
*/
public LocalBindingContext getLocalBindingContext();
} }

View File

@ -34,10 +34,11 @@ import org.hibernate.EntityMode;
import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.beans.BeanInfoHelper; import org.hibernate.internal.util.beans.BeanInfoHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding; import org.hibernate.metamodel.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.AttributeBindingContainer;
import org.hibernate.metamodel.binding.CollectionElementNature; import org.hibernate.metamodel.binding.CollectionElementNature;
import org.hibernate.metamodel.binding.ComponentAttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.EntityDiscriminator; import org.hibernate.metamodel.binding.EntityDiscriminator;
import org.hibernate.metamodel.binding.InheritanceType; import org.hibernate.metamodel.binding.InheritanceType;
@ -48,6 +49,7 @@ import org.hibernate.metamodel.binding.SimpleValueBinding;
import org.hibernate.metamodel.binding.SingularAttributeBinding; import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef; import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.domain.Attribute; import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.Component;
import org.hibernate.metamodel.domain.Entity; import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.PluralAttribute; import org.hibernate.metamodel.domain.PluralAttribute;
import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.domain.SingularAttribute;
@ -116,7 +118,7 @@ public class Binder {
return metadata.getEntityBinding( entitySource.getEntityName() ); return metadata.getEntityBinding( entitySource.getEntityName() );
} }
currentBindingContext = entitySource.getBindingContext(); currentBindingContext = entitySource.getLocalBindingContext();
try { try {
final EntityBinding entityBinding = doCreateEntityBinding( entitySource, superEntityBinding ); final EntityBinding entityBinding = doCreateEntityBinding( entitySource, superEntityBinding );
@ -266,7 +268,7 @@ public class Binder {
private EntityBinding makeDiscriminatedSubclassBinding(SubclassEntitySource entitySource, EntityBinding superEntityBinding) { private EntityBinding makeDiscriminatedSubclassBinding(SubclassEntitySource entitySource, EntityBinding superEntityBinding) {
final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, superEntityBinding ); final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, superEntityBinding );
entityBinding.setBaseTable( superEntityBinding.getBaseTable() ); entityBinding.setBaseTable( superEntityBinding.getPrimaryTable() );
bindDiscriminatorValue( entitySource, entityBinding ); bindDiscriminatorValue( entitySource, entityBinding );
@ -332,12 +334,12 @@ public class Binder {
// this should never ever happen.. // this should never ever happen..
throw new AssertionFailure( "Simple-id was not a column." ); throw new AssertionFailure( "Simple-id was not a column." );
} }
entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( relationalValue ) ); entityBinding.getPrimaryTable().getPrimaryKey().addColumn( Column.class.cast( relationalValue ) );
} }
else { else {
for ( SimpleValue subValue : ( (Tuple) relationalValue ).values() ) { for ( SimpleValue subValue : ( (Tuple) relationalValue ).values() ) {
if ( Column.class.isInstance( subValue ) ) { if ( Column.class.isInstance( subValue ) ) {
entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( subValue ) ); entityBinding.getPrimaryTable().getPrimaryKey().addColumn( Column.class.cast( subValue ) );
} }
} }
} }
@ -388,7 +390,7 @@ public class Binder {
entityBinding.setDiscriminatorMatchValue( discriminatorValue ); entityBinding.setDiscriminatorMatchValue( discriminatorValue );
} }
private void bindAttributes(AttributeSourceContainer attributeSourceContainer, EntityBinding entityBinding) { private void bindAttributes(AttributeSourceContainer attributeSourceContainer, AttributeBindingContainer attributeBindingContainer) {
// todo : we really need the notion of a Stack here for the table from which the columns come for binding these attributes. // todo : we really need the notion of a Stack here for the table from which the columns come for binding these attributes.
// todo : adding the concept (interface) of a source of attribute metadata would allow reuse of this method for entity, component, unique-key, etc // todo : adding the concept (interface) of a source of attribute metadata would allow reuse of this method for entity, component, unique-key, etc
// for now, simply assume all columns come from the base table.... // for now, simply assume all columns come from the base table....
@ -397,32 +399,54 @@ public class Binder {
if ( attributeSource.isSingular() ) { if ( attributeSource.isSingular() ) {
final SingularAttributeSource singularAttributeSource = (SingularAttributeSource) attributeSource; final SingularAttributeSource singularAttributeSource = (SingularAttributeSource) attributeSource;
if ( singularAttributeSource.getNature() == SingularAttributeNature.COMPONENT ) { if ( singularAttributeSource.getNature() == SingularAttributeNature.COMPONENT ) {
bindComponent( singularAttributeSource, entityBinding ); bindComponent( (ComponentAttributeSource) singularAttributeSource, attributeBindingContainer );
} }
else { else {
doBasicSingularAttributeBindingCreation( singularAttributeSource, entityBinding ); doBasicSingularAttributeBindingCreation( singularAttributeSource, attributeBindingContainer );
} }
} }
else { else {
bindPersistentCollection( (PluralAttributeSource) attributeSource, entityBinding ); bindPersistentCollection( (PluralAttributeSource) attributeSource, attributeBindingContainer );
} }
} }
} }
private void bindComponent(SingularAttributeSource singularAttributeSource, EntityBinding entityBinding) { private void bindComponent(ComponentAttributeSource attributeSource, AttributeBindingContainer container) {
throw new NotYetImplementedException( "Component binding not yet implemented :(" ); final String attributeName = attributeSource.getName();
SingularAttribute attribute = container.getAttributeContainer().locateComponentAttribute( attributeName );
if ( attribute == null ) {
final Component component = new Component(
attributeSource.getPath(),
attributeSource.getClassName(),
attributeSource.getClassReference(),
null // component inheritance not YET supported
);
attribute = container.getAttributeContainer().createComponentAttribute( attributeName, component );
}
ComponentAttributeBinding componentAttributeBinding = container.makeComponentAttributeBinding( attribute );
if ( StringHelper.isNotEmpty( attributeSource.getParentReferenceAttributeName() ) ) {
final SingularAttribute parentReferenceAttribute =
componentAttributeBinding.getComponent().createSingularAttribute( attributeSource.getParentReferenceAttributeName() );
componentAttributeBinding.setParentReference( parentReferenceAttribute );
}
componentAttributeBinding.setMetaAttributeContext(
buildMetaAttributeContext( attributeSource.metaAttributes(), container.getMetaAttributeContext() )
);
bindAttributes( attributeSource, componentAttributeBinding );
} }
private void bindPersistentCollection(PluralAttributeSource attributeSource, EntityBinding entityBinding) { private void bindPersistentCollection(PluralAttributeSource attributeSource, AttributeBindingContainer attributeBindingContainer) {
final PluralAttribute existingAttribute = entityBinding.getEntity() final PluralAttribute existingAttribute = attributeBindingContainer.getAttributeContainer().locatePluralAttribute( attributeSource.getName() );
.locatePluralAttribute( attributeSource.getName() );
final AbstractPluralAttributeBinding pluralAttributeBinding; final AbstractPluralAttributeBinding pluralAttributeBinding;
if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) { if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) {
final PluralAttribute attribute = existingAttribute != null final PluralAttribute attribute = existingAttribute != null
? existingAttribute ? existingAttribute
: entityBinding.getEntity().createBag( attributeSource.getName() ); : attributeBindingContainer.getAttributeContainer().createBag( attributeSource.getName() );
pluralAttributeBinding = entityBinding.makeBagAttributeBinding( pluralAttributeBinding = attributeBindingContainer.makeBagAttributeBinding(
attribute, attribute,
convert( attributeSource.getPluralAttributeElementNature() ) convert( attributeSource.getPluralAttributeElementNature() )
); );
@ -446,27 +470,26 @@ public class Binder {
private SimpleSingularAttributeBinding doBasicSingularAttributeBindingCreation( private SimpleSingularAttributeBinding doBasicSingularAttributeBindingCreation(
SingularAttributeSource attributeSource, SingularAttributeSource attributeSource,
EntityBinding entityBinding) { AttributeBindingContainer attributeBindingContainer) {
final SingularAttribute existingAttribute = entityBinding.getEntity() final SingularAttribute existingAttribute = attributeBindingContainer.getAttributeContainer().locateSingularAttribute( attributeSource.getName() );
.locateSingularAttribute( attributeSource.getName() );
final SingularAttribute attribute; final SingularAttribute attribute;
if ( existingAttribute != null ) { if ( existingAttribute != null ) {
attribute = existingAttribute; attribute = existingAttribute;
} }
else if ( attributeSource.isVirtualAttribute() ) { else if ( attributeSource.isVirtualAttribute() ) {
attribute = entityBinding.getEntity().createVirtualSingularAttribute( attributeSource.getName() ); attribute = attributeBindingContainer.getAttributeContainer().createVirtualSingularAttribute( attributeSource.getName() );
} }
else { else {
attribute = entityBinding.getEntity().createSingularAttribute( attributeSource.getName() ); attribute = attributeBindingContainer.getAttributeContainer().createSingularAttribute( attributeSource.getName() );
} }
final SimpleSingularAttributeBinding attributeBinding; final SimpleSingularAttributeBinding attributeBinding;
if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) { if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) {
attributeBinding = entityBinding.makeSimpleAttributeBinding( attribute ); attributeBinding = attributeBindingContainer.makeSimpleAttributeBinding( attribute );
resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding ); resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding );
} }
else if ( attributeSource.getNature() == SingularAttributeNature.MANY_TO_ONE ) { else if ( attributeSource.getNature() == SingularAttributeNature.MANY_TO_ONE ) {
attributeBinding = entityBinding.makeManyToOneAttributeBinding( attribute ); attributeBinding = attributeBindingContainer.makeManyToOneAttributeBinding( attribute );
resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding ); resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding );
resolveToOneInformation( resolveToOneInformation(
(ToOneAttributeSource) attributeSource, (ToOneAttributeSource) attributeSource,
@ -492,7 +515,7 @@ public class Binder {
bindRelationalValues( attributeSource, attributeBinding ); bindRelationalValues( attributeSource, attributeBinding );
attributeBinding.setMetaAttributeContext( attributeBinding.setMetaAttributeContext(
buildMetaAttributeContext( attributeSource.metaAttributes(), entityBinding.getMetaAttributeContext() ) buildMetaAttributeContext( attributeSource.metaAttributes(), attributeBindingContainer.getMetaAttributeContext() )
); );
return attributeBinding; return attributeBinding;
@ -660,7 +683,7 @@ public class Binder {
private void bindTableUniqueConstraints(EntitySource entitySource, EntityBinding entityBinding) { private void bindTableUniqueConstraints(EntitySource entitySource, EntityBinding entityBinding) {
for ( ConstraintSource constraintSource : entitySource.getConstraints() ) { for ( ConstraintSource constraintSource : entitySource.getConstraints() ) {
if ( constraintSource instanceof UniqueConstraintSource ) { if ( constraintSource instanceof UniqueConstraintSource ) {
TableSpecification table = entityBinding.getTable( constraintSource.getTableName() ); TableSpecification table = entityBinding.locateTable( constraintSource.getTableName() );
if ( table == null ) { if ( table == null ) {
// throw exception !? // throw exception !?
} }
@ -685,8 +708,8 @@ public class Binder {
if ( relationalValueSourceContainer.relationalValueSources().size() > 0 ) { if ( relationalValueSourceContainer.relationalValueSources().size() > 0 ) {
for ( RelationalValueSource valueSource : relationalValueSourceContainer.relationalValueSources() ) { for ( RelationalValueSource valueSource : relationalValueSourceContainer.relationalValueSources() ) {
final TableSpecification table = attributeBinding.getEntityBinding() final TableSpecification table = attributeBinding.getContainer()
.getTable( valueSource.getContainingTableName() ); .locateTable( valueSource.getContainingTableName() );
if ( ColumnSource.class.isInstance( valueSource ) ) { if ( ColumnSource.class.isInstance( valueSource ) ) {
final ColumnSource columnSource = ColumnSource.class.cast( valueSource ); final ColumnSource columnSource = ColumnSource.class.cast( valueSource );
@ -714,7 +737,7 @@ public class Binder {
.propertyToColumnName( attributeBinding.getAttribute().getName() ); .propertyToColumnName( attributeBinding.getAttribute().getName() );
valueBindings.add( valueBindings.add(
new SimpleValueBinding( new SimpleValueBinding(
attributeBinding.getEntityBinding().getBaseTable().locateOrCreateColumn( name ) attributeBinding.getContainer().getPrimaryTable().locateOrCreateColumn( name )
) )
); );
} }
@ -724,7 +747,7 @@ public class Binder {
private SimpleValue makeSimpleValue( private SimpleValue makeSimpleValue(
EntityBinding entityBinding, EntityBinding entityBinding,
RelationalValueSource valueSource) { RelationalValueSource valueSource) {
final TableSpecification table = entityBinding.getTable( valueSource.getContainingTableName() ); final TableSpecification table = entityBinding.locateTable( valueSource.getContainingTableName() );
if ( ColumnSource.class.isInstance( valueSource ) ) { if ( ColumnSource.class.isInstance( valueSource ) ) {
return makeColumn( (ColumnSource) valueSource, table ); return makeColumn( (ColumnSource) valueSource, table );

View File

@ -0,0 +1,36 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.source.binder;
import org.hibernate.internal.util.Value;
/**
* @author Steve Ebersole
*/
public interface ComponentAttributeSource extends SingularAttributeSource, AttributeSourceContainer {
public String getClassName();
public Value<Class<?>> getClassReference();
public String getParentReferenceAttributeName();
}

View File

@ -47,7 +47,7 @@ public interface EntitySource extends SubclassEntityContainer, AttributeSourceCo
* *
* @return The local binding context * @return The local binding context
*/ */
public LocalBindingContext getBindingContext(); public LocalBindingContext getLocalBindingContext();
/** /**
* Obtain the entity name * Obtain the entity name

View File

@ -41,6 +41,7 @@ import org.hibernate.metamodel.source.binder.SubclassEntitySource;
import org.hibernate.metamodel.source.binder.TableSource; import org.hibernate.metamodel.source.binder.TableSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLAnyElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLAnyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLComponentElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToManyElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToManyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLOneToManyElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLOneToManyElement;
@ -78,7 +79,7 @@ public abstract class AbstractEntitySourceImpl implements EntitySource {
} }
@Override @Override
public LocalBindingContext getBindingContext() { public LocalBindingContext getLocalBindingContext() {
return sourceMappingDocument.getMappingLocalBindingContext(); return sourceMappingDocument.getMappingLocalBindingContext();
} }
@ -91,7 +92,7 @@ public abstract class AbstractEntitySourceImpl implements EntitySource {
@Override @Override
public String getClassName() { public String getClassName() {
return getBindingContext().qualifyClassName( entityElement.getName() ); return getLocalBindingContext().qualifyClassName( entityElement.getName() );
} }
@Override @Override
@ -154,7 +155,7 @@ public abstract class AbstractEntitySourceImpl implements EntitySource {
@Override @Override
public String getCustomPersisterClassName() { public String getCustomPersisterClassName() {
return getBindingContext().qualifyClassName( entityElement.getPersister() ); return getLocalBindingContext().qualifyClassName( entityElement.getPersister() );
} }
@Override @Override
@ -191,6 +192,11 @@ public abstract class AbstractEntitySourceImpl implements EntitySource {
return Helper.buildMetaAttributeSources( entityElement.getMeta() ); return Helper.buildMetaAttributeSources( entityElement.getMeta() );
} }
@Override
public String getPath() {
return sourceMappingDocument.getMappingLocalBindingContext().determineEntityName( entityElement );
}
@Override @Override
public Iterable<AttributeSource> attributeSources() { public Iterable<AttributeSource> attributeSources() {
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>(); List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
@ -203,6 +209,15 @@ public abstract class AbstractEntitySourceImpl implements EntitySource {
) )
); );
} }
else if ( XMLComponentElement.class.isInstance( attributeElement ) ) {
attributeSources.add(
new ComponentAttributeSourceImpl(
(XMLComponentElement) attributeElement,
this,
sourceMappingDocument.getMappingLocalBindingContext()
)
);
}
else if ( XMLManyToOneElement.class.isInstance( attributeElement ) ) { else if ( XMLManyToOneElement.class.isInstance( attributeElement ) ) {
attributeSources.add( attributeSources.add(
new ManyToOneAttributeSourceImpl( new ManyToOneAttributeSourceImpl(

View File

@ -0,0 +1,220 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.source.hbm;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.internal.util.Value;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.binder.AttributeSource;
import org.hibernate.metamodel.source.binder.AttributeSourceContainer;
import org.hibernate.metamodel.source.binder.ComponentAttributeSource;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.RelationalValueSource;
import org.hibernate.metamodel.source.binder.SingularAttributeNature;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLAnyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLComponentElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToManyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLManyToOneElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLOneToManyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLOneToOneElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLPropertyElement;
/**
* @author Steve Ebersole
*/
public class ComponentAttributeSourceImpl implements ComponentAttributeSource {
private final XMLComponentElement componentElement;
private final AttributeSourceContainer parentContainer;
private final Value<Class<?>> componentClassReference;
private final String path;
public ComponentAttributeSourceImpl(
XMLComponentElement componentElement,
AttributeSourceContainer parentContainer,
LocalBindingContext bindingContext) {
this.componentElement = componentElement;
this.parentContainer = parentContainer;
this.componentClassReference = bindingContext.makeClassReference( componentElement.getClazz() );
this.path = parentContainer.getPath() + '.' + componentElement.getName();
}
@Override
public String getClassName() {
return componentElement.getClazz();
}
@Override
public Value<Class<?>> getClassReference() {
return componentClassReference;
}
@Override
public String getPath() {
return path;
}
@Override
public LocalBindingContext getLocalBindingContext() {
return parentContainer.getLocalBindingContext();
}
@Override
public String getParentReferenceAttributeName() {
return componentElement.getParent() == null ? null : componentElement.getParent().getName();
}
@Override
public Iterable<AttributeSource> attributeSources() {
List<AttributeSource> attributeSources = new ArrayList<AttributeSource>();
for ( Object attributeElement : componentElement.getPropertyOrManyToOneOrOneToOne() ) {
if ( XMLPropertyElement.class.isInstance( attributeElement ) ) {
attributeSources.add(
new PropertyAttributeSourceImpl(
XMLPropertyElement.class.cast( attributeElement ),
getLocalBindingContext()
)
);
}
else if ( XMLComponentElement.class.isInstance( attributeElement ) ) {
attributeSources.add(
new ComponentAttributeSourceImpl(
(XMLComponentElement) attributeElement,
this,
getLocalBindingContext()
)
);
}
else if ( XMLManyToOneElement.class.isInstance( attributeElement ) ) {
attributeSources.add(
new ManyToOneAttributeSourceImpl(
XMLManyToOneElement.class.cast( attributeElement ),
getLocalBindingContext()
)
);
}
else if ( XMLOneToOneElement.class.isInstance( attributeElement ) ) {
// todo : implement
}
else if ( XMLAnyElement.class.isInstance( attributeElement ) ) {
// todo : implement
}
else if ( XMLOneToManyElement.class.isInstance( attributeElement ) ) {
// todo : implement
}
else if ( XMLManyToManyElement.class.isInstance( attributeElement ) ) {
// todo : implement
}
}
return attributeSources;
}
@Override
public boolean isVirtualAttribute() {
return false;
}
@Override
public SingularAttributeNature getNature() {
return SingularAttributeNature.COMPONENT;
}
@Override
public ExplicitHibernateTypeSource getTypeInformation() {
// <component/> does not support type information.
return null;
}
@Override
public String getName() {
return componentElement.getName();
}
@Override
public boolean isSingular() {
return true;
}
@Override
public String getPropertyAccessorName() {
return componentElement.getAccess();
}
@Override
public boolean isInsertable() {
return componentElement.isInsert();
}
@Override
public boolean isUpdatable() {
return componentElement.isUpdate();
}
@Override
public PropertyGeneration getGeneration() {
// todo : is this correct here?
return null;
}
@Override
public boolean isLazy() {
return componentElement.isLazy();
}
@Override
public boolean isIncludedInOptimisticLocking() {
return componentElement.isOptimisticLock();
}
@Override
public Iterable<MetaAttributeSource> metaAttributes() {
return Helper.buildMetaAttributeSources( componentElement.getMeta() );
}
@Override
public boolean areValuesIncludedInInsertByDefault() {
return isInsertable();
}
@Override
public boolean areValuesIncludedInUpdateByDefault() {
return isUpdatable();
}
@Override
public boolean areValuesNullableByDefault() {
return true;
}
@Override
public List<RelationalValueSource> relationalValueSources() {
// none, they are defined on the simple sub-attributes
return null;
}
}

View File

@ -190,6 +190,11 @@ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements Ro
}; };
} }
@Override
public String getDiscriminatorMatchValue() {
return entityElement().getDiscriminatorValue();
}
@Override @Override
public DiscriminatorSource getDiscriminatorSource() { public DiscriminatorSource getDiscriminatorSource() {
final XMLHibernateMapping.XMLClass.XMLDiscriminator discriminatorElement = entityElement().getDiscriminator(); final XMLHibernateMapping.XMLClass.XMLDiscriminator discriminatorElement = entityElement().getDiscriminator();

View File

@ -27,6 +27,7 @@ import org.hibernate.metamodel.source.binder.SubclassEntitySource;
import org.hibernate.metamodel.source.binder.TableSource; import org.hibernate.metamodel.source.binder.TableSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLJoinedSubclassElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLJoinedSubclassElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLSubclassElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLUnionSubclassElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLUnionSubclassElement;
/** /**
@ -89,4 +90,11 @@ public class SubclassEntitySourceImpl extends AbstractEntitySourceImpl implement
} }
return null; return null;
} }
@Override
public String getDiscriminatorMatchValue() {
return XMLSubclassElement.class.isInstance( entityElement() )
? ( (XMLSubclassElement) entityElement() ).getDiscriminatorValue()
: null;
}
} }

View File

@ -60,7 +60,7 @@ class AssociationResolver {
} }
AttributeBinding referencedAttributeBinding = AttributeBinding referencedAttributeBinding =
attributeBinding.isPropertyReference() ? attributeBinding.isPropertyReference() ?
entityBinding.getAttributeBinding( attributeBinding.getReferencedAttributeName() ) : entityBinding.locateAttributeBinding( attributeBinding.getReferencedAttributeName() ) :
entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding(); entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding();
if ( referencedAttributeBinding == null ) { if ( referencedAttributeBinding == null ) {
// TODO: does attribute name include path w/ entity name? // TODO: does attribute name include path w/ entity name?

View File

@ -52,7 +52,7 @@ class AttributeTypeResolver {
void resolve() { void resolve() {
for ( EntityBinding entityBinding : metadata.getEntityBindings() ) { for ( EntityBinding entityBinding : metadata.getEntityBindings() ) {
for ( AttributeBinding attributeBinding : entityBinding.getAttributeBindings() ) { for ( AttributeBinding attributeBinding : entityBinding.attributeBindings() ) {
resolveTypeInformation( attributeBinding ); resolveTypeInformation( attributeBinding );
} }
} }

View File

@ -424,7 +424,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
} }
public void addCollection(AbstractPluralAttributeBinding pluralAttributeBinding) { public void addCollection(AbstractPluralAttributeBinding pluralAttributeBinding) {
final String owningEntityName = pluralAttributeBinding.getEntityBinding().getEntity().getName(); final String owningEntityName = pluralAttributeBinding.getContainer().getPathBase();
final String attributeName = pluralAttributeBinding.getAttribute().getName(); final String attributeName = pluralAttributeBinding.getAttribute().getName();
final String collectionRole = owningEntityName + '.' + attributeName; final String collectionRole = owningEntityName + '.' + attributeName;
if ( collectionBindingMap.containsKey( collectionRole ) ) { if ( collectionBindingMap.containsKey( collectionRole ) ) {
@ -535,7 +535,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
throw new MappingException( "Entity binding not known: " + entityName ); throw new MappingException( "Entity binding not known: " + entityName );
} }
// TODO: should this call EntityBinding.getReferencedAttributeBindingString), which does not exist yet? // TODO: should this call EntityBinding.getReferencedAttributeBindingString), which does not exist yet?
AttributeBinding attributeBinding = entityBinding.getAttributeBinding( propertyName ); AttributeBinding attributeBinding = entityBinding.locateAttributeBinding( propertyName );
if ( attributeBinding == null ) { if ( attributeBinding == null ) {
throw new MappingException( "unknown property: " + entityName + '.' + propertyName ); throw new MappingException( "unknown property: " + entityName + '.' + propertyName );
} }

View File

@ -100,7 +100,6 @@ import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.SimpleValueBinding; import org.hibernate.metamodel.binding.SimpleValueBinding;
import org.hibernate.metamodel.binding.SingularAttributeBinding; import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.metamodel.relational.DerivedValue; import org.hibernate.metamodel.relational.DerivedValue;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Value; import org.hibernate.metamodel.relational.Value;
import org.hibernate.pretty.MessageHelper; import org.hibernate.pretty.MessageHelper;
import org.hibernate.property.BackrefPropertyAccessor; import org.hibernate.property.BackrefPropertyAccessor;
@ -802,7 +801,7 @@ public abstract class AbstractEntityPersister
loaderName = entityBinding.getCustomLoaderName(); loaderName = entityBinding.getCustomLoaderName();
int i = 0; int i = 0;
for ( org.hibernate.metamodel.relational.Column col : entityBinding.getBaseTable().getPrimaryKey().getColumns() ) { for ( org.hibernate.metamodel.relational.Column col : entityBinding.getPrimaryTable().getPrimaryKey().getColumns() ) {
rootTableKeyColumnNames[i] = col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ); rootTableKeyColumnNames[i] = col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() );
if ( col.getReadFragment() == null ) { if ( col.getReadFragment() == null ) {
rootTableKeyColumnReaders[i] = rootTableKeyColumnNames[i]; rootTableKeyColumnReaders[i] = rootTableKeyColumnNames[i];
@ -813,7 +812,7 @@ public abstract class AbstractEntityPersister
rootTableKeyColumnReaderTemplates[i] = getTemplateFromString( col.getReadFragment(), factory ); rootTableKeyColumnReaderTemplates[i] = getTemplateFromString( col.getReadFragment(), factory );
} }
// TODO: Fix when HHH-6337 is fixed; for now assume entityBinding is the root // TODO: Fix when HHH-6337 is fixed; for now assume entityBinding is the root
// identifierAliases[i] = col.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getBaseTable() ); // identifierAliases[i] = col.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getPrimaryTable() );
identifierAliases[i] = col.getAlias( factory.getDialect() ); identifierAliases[i] = col.getAlias( factory.getDialect() );
i++; i++;
} }
@ -878,7 +877,7 @@ public abstract class AbstractEntityPersister
thisClassProperties.add( singularAttributeBinding ); thisClassProperties.add( singularAttributeBinding );
propertySubclassNames[i] = singularAttributeBinding.getEntityBinding().getEntity().getName(); propertySubclassNames[i] = ( (EntityBinding) singularAttributeBinding.getContainer() ).getEntity().getName();
int span = singularAttributeBinding.getSimpleValueSpan(); int span = singularAttributeBinding.getSimpleValueSpan();
propertyColumnSpans[i] = span; propertyColumnSpans[i] = span;
@ -983,7 +982,7 @@ public abstract class AbstractEntityPersister
final SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding; final SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding;
names.add( singularAttributeBinding.getAttribute().getName() ); names.add( singularAttributeBinding.getAttribute().getName() );
classes.add( singularAttributeBinding.getEntityBinding().getEntity().getName() ); classes.add( ( (EntityBinding) singularAttributeBinding.getContainer() ).getEntity().getName() );
boolean isDefinedBySubclass = ! thisClassProperties.contains( singularAttributeBinding ); boolean isDefinedBySubclass = ! thisClassProperties.contains( singularAttributeBinding );
definedBySubclass.add( isDefinedBySubclass ); definedBySubclass.add( isDefinedBySubclass );
propNullables.add( singularAttributeBinding.isNullable() || isDefinedBySubclass ); //TODO: is this completely correct? propNullables.add( singularAttributeBinding.isNullable() || isDefinedBySubclass ); //TODO: is this completely correct?

View File

@ -467,8 +467,8 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
keyColumnNames = new String[joinSpan][]; keyColumnNames = new String[joinSpan][];
// TODO: fix when EntityBinhding.getRootEntityBinding() exists (HHH-6337) // TODO: fix when EntityBinhding.getRootEntityBinding() exists (HHH-6337)
//final Table table = entityBinding.getRootEntityBinding().getBaseTable(); //final Table table = entityBinding.getRootEntityBinding().getPrimaryTable();
final TableSpecification table = entityBinding.getBaseTable(); final TableSpecification table = entityBinding.getPrimaryTable();
qualifiedTableNames[0] = table.getQualifiedName( factory.getDialect() ); qualifiedTableNames[0] = table.getQualifiedName( factory.getDialect() );
isInverseTable[0] = false; isInverseTable[0] = false;
isNullableTable[0] = false; isNullableTable[0] = false;
@ -571,7 +571,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
discriminatorColumnReaderTemplate = getTemplateFromColumn( column, factory ); discriminatorColumnReaderTemplate = getTemplateFromColumn( column, factory );
// TODO: fix this when EntityBinding.getRootEntityBinding() is implemented; // TODO: fix this when EntityBinding.getRootEntityBinding() is implemented;
// for now, assume entityBinding is the root // for now, assume entityBinding is the root
//discriminatorAlias = column.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getBaseTable ); //discriminatorAlias = column.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getPrimaryTable );
discriminatorAlias = column.getAlias( factory.getDialect() ); discriminatorAlias = column.getAlias( factory.getDialect() );
discriminatorFormula = null; discriminatorFormula = null;
discriminatorFormulaTemplate = null; discriminatorFormulaTemplate = null;
@ -663,7 +663,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
//propertyTableNumbersByName.put( singularAttributeBinding.getName(), join ); //propertyTableNumbersByName.put( singularAttributeBinding.getName(), join );
propertyTableNumbersByNameAndSubclass.put( propertyTableNumbersByNameAndSubclass.put(
singularAttributeBinding.getEntityBinding().getEntity().getName() + '.' + singularAttributeBinding.getAttribute().getName(), singularAttributeBinding.getContainer().getPathBase() + '.' + singularAttributeBinding.getAttribute().getName(),
join join
); );

View File

@ -199,7 +199,7 @@ public class PropertyFactory {
mappedUnsavedValue, mappedUnsavedValue,
getGetter( property ), getGetter( property ),
(VersionType) property.getHibernateTypeDescriptor().getResolvedTypeMapping(), (VersionType) property.getHibernateTypeDescriptor().getResolvedTypeMapping(),
getConstructor( property.getEntityBinding() ) getConstructor( (EntityBinding) property.getContainer() )
); );
boolean lazy = lazyAvailable && property.isLazy(); boolean lazy = lazyAvailable && property.isLazy();
@ -390,13 +390,13 @@ public class PropertyFactory {
} }
private static Getter getGetter(AttributeBinding mappingProperty) { private static Getter getGetter(AttributeBinding mappingProperty) {
if ( mappingProperty == null || mappingProperty.getEntityBinding().getEntity() == null ) { if ( mappingProperty == null || mappingProperty.getContainer().getClassReference() == null ) {
return null; return null;
} }
PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO ); PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO );
return pa.getGetter( return pa.getGetter(
mappingProperty.getEntityBinding().getEntity().getClassReference(), mappingProperty.getContainer().getClassReference(),
mappingProperty.getAttribute().getName() mappingProperty.getAttribute().getName()
); );
} }

View File

@ -294,7 +294,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
// } // }
//} //}
for ( AttributeBinding property : entityBinding.getAttributeBindings() ) { for ( AttributeBinding property : entityBinding.attributeBindings() ) {
Method method = getGetter( property ).getMethod(); Method method = getGetter( property ).getMethod();
if ( method != null && Modifier.isFinal( method.getModifiers() ) ) { if ( method != null && Modifier.isFinal( method.getModifiers() ) ) {
LOG.gettersOfLazyClassesCannotBeFinal(entityBinding.getEntity().getName(), property.getAttribute().getName()); LOG.gettersOfLazyClassesCannotBeFinal(entityBinding.getEntity().getName(), property.getAttribute().getName());
@ -462,14 +462,14 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
private Getter getGetter(AttributeBinding mappedProperty) throws PropertyNotFoundException, MappingException { private Getter getGetter(AttributeBinding mappedProperty) throws PropertyNotFoundException, MappingException {
return getPropertyAccessor( mappedProperty ).getGetter( return getPropertyAccessor( mappedProperty ).getGetter(
mappedProperty.getEntityBinding().getEntity().getClassReference(), mappedProperty.getContainer().getClassReference(),
mappedProperty.getAttribute().getName() mappedProperty.getAttribute().getName()
); );
} }
private Setter getSetter(AttributeBinding mappedProperty) throws PropertyNotFoundException, MappingException { private Setter getSetter(AttributeBinding mappedProperty) throws PropertyNotFoundException, MappingException {
return getPropertyAccessor( mappedProperty ).getSetter( return getPropertyAccessor( mappedProperty ).getSetter(
mappedProperty.getEntityBinding().getEntity().getClassReference(), mappedProperty.getContainer().getClassReference(),
mappedProperty.getAttribute().getName() mappedProperty.getAttribute().getName()
); );
} }
@ -477,7 +477,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
private PropertyAccessor getPropertyAccessor(AttributeBinding mappedProperty) throws MappingException { private PropertyAccessor getPropertyAccessor(AttributeBinding mappedProperty) throws MappingException {
// TODO: Fix this then backrefs are working in new metamodel // TODO: Fix this then backrefs are working in new metamodel
return PropertyAccessorFactory.getPropertyAccessor( return PropertyAccessorFactory.getPropertyAccessor(
mappedProperty.getEntityBinding().getEntity().getClassReference(), mappedProperty.getContainer().getClassReference(),
mappedProperty.getPropertyAccessorName() mappedProperty.getPropertyAccessorName()
); );
} }

View File

@ -28,6 +28,7 @@ import java.util.Iterator;
import java.util.Set; import java.util.Set;
import org.junit.After; import org.junit.After;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -61,12 +62,10 @@ import static org.junit.Assert.assertTrue;
public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
private BasicServiceRegistryImpl serviceRegistry; private BasicServiceRegistryImpl serviceRegistry;
private MetadataSources sources;
@Before @Before
public void setUp() { public void setUp() {
serviceRegistry = (BasicServiceRegistryImpl) new ServiceRegistryBuilder().buildServiceRegistry(); serviceRegistry = (BasicServiceRegistryImpl) new ServiceRegistryBuilder().buildServiceRegistry();
sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
} }
@After @After
@ -80,7 +79,9 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
@Test @Test
public void testSimpleEntityMapping() { public void testSimpleEntityMapping() {
MetadataImpl metadata = addSourcesForSimpleEntityBinding( sources ); MetadataSources sources = new MetadataSources( serviceRegistry );
addSourcesForSimpleEntityBinding( sources );
MetadataImpl metadata = (MetadataImpl) sources.buildMetadata();
EntityBinding entityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() ); EntityBinding entityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() );
assertRoot( metadata, entityBinding ); assertRoot( metadata, entityBinding );
assertIdAndSimpleProperty( entityBinding ); assertIdAndSimpleProperty( entityBinding );
@ -90,7 +91,9 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
@Test @Test
public void testSimpleVersionedEntityMapping() { public void testSimpleVersionedEntityMapping() {
MetadataImpl metadata = addSourcesForSimpleVersionedEntityBinding( sources ); MetadataSources sources = new MetadataSources( serviceRegistry );
addSourcesForSimpleVersionedEntityBinding( sources );
MetadataImpl metadata = (MetadataImpl) sources.buildMetadata();
EntityBinding entityBinding = metadata.getEntityBinding( SimpleVersionedEntity.class.getName() ); EntityBinding entityBinding = metadata.getEntityBinding( SimpleVersionedEntity.class.getName() );
assertIdAndSimpleProperty( entityBinding ); assertIdAndSimpleProperty( entityBinding );
@ -100,12 +103,15 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
@Test @Test
public void testEntityWithManyToOneMapping() { public void testEntityWithManyToOneMapping() {
MetadataImpl metadata = addSourcesForManyToOne( sources ); MetadataSources sources = new MetadataSources( serviceRegistry );
addSourcesForSimpleEntityBinding( sources );
addSourcesForManyToOne( sources );
MetadataImpl metadata = (MetadataImpl) sources.buildMetadata();
EntityBinding simpleEntityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() ); EntityBinding simpleEntityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() );
assertIdAndSimpleProperty( simpleEntityBinding ); assertIdAndSimpleProperty( simpleEntityBinding );
Set<SingularAssociationAttributeBinding> referenceBindings = simpleEntityBinding.getAttributeBinding( "id" ) Set<SingularAssociationAttributeBinding> referenceBindings = simpleEntityBinding.locateAttributeBinding( "id" )
.getEntityReferencingAttributeBindings(); .getEntityReferencingAttributeBindings();
assertEquals( "There should be only one reference binding", 1, referenceBindings.size() ); assertEquals( "There should be only one reference binding", 1, referenceBindings.size() );
@ -118,22 +124,41 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
Iterator<SingularAssociationAttributeBinding> it = entityWithManyToOneBinding.getEntityReferencingAttributeBindings() Iterator<SingularAssociationAttributeBinding> it = entityWithManyToOneBinding.getEntityReferencingAttributeBindings()
.iterator(); .iterator();
assertTrue( it.hasNext() ); assertTrue( it.hasNext() );
assertSame( entityWithManyToOneBinding.getAttributeBinding( "simpleEntity" ), it.next() ); assertSame( entityWithManyToOneBinding.locateAttributeBinding( "simpleEntity" ), it.next() );
assertFalse( it.hasNext() ); assertFalse( it.hasNext() );
} }
public abstract MetadataImpl addSourcesForSimpleVersionedEntityBinding(MetadataSources sources); @Test
public void testSimpleEntityWithSimpleComponentMapping() {
MetadataSources sources = new MetadataSources( serviceRegistry );
addSourcesForComponentBinding( sources );
MetadataImpl metadata = (MetadataImpl) sources.buildMetadata();
EntityBinding entityBinding = metadata.getEntityBinding( SimpleEntityWithSimpleComponent.class.getName() );
assertRoot( metadata, entityBinding );
assertIdAndSimpleProperty( entityBinding );
public abstract MetadataImpl addSourcesForSimpleEntityBinding(MetadataSources sources); ComponentAttributeBinding componentAttributeBinding = (ComponentAttributeBinding) entityBinding.locateAttributeBinding( "simpleComponent" );
assertNotNull( componentAttributeBinding );
assertSame( componentAttributeBinding.getAttribute().getSingularAttributeType(), componentAttributeBinding.getAttributeContainer() );
assertEquals( SimpleEntityWithSimpleComponent.class.getName() + ".simpleComponent", componentAttributeBinding.getPathBase() );
assertSame( entityBinding.getPrimaryTable(), componentAttributeBinding.getPrimaryTable() );
assertNotNull( componentAttributeBinding.getComponent() );
}
public abstract MetadataImpl addSourcesForManyToOne(MetadataSources sources); public abstract void addSourcesForSimpleVersionedEntityBinding(MetadataSources sources);
public abstract void addSourcesForSimpleEntityBinding(MetadataSources sources);
public abstract void addSourcesForManyToOne(MetadataSources sources);
public abstract void addSourcesForComponentBinding(MetadataSources sources);
protected void assertIdAndSimpleProperty(EntityBinding entityBinding) { protected void assertIdAndSimpleProperty(EntityBinding entityBinding) {
assertNotNull( entityBinding ); assertNotNull( entityBinding );
assertNotNull( entityBinding.getHierarchyDetails().getEntityIdentifier() ); assertNotNull( entityBinding.getHierarchyDetails().getEntityIdentifier() );
assertNotNull( entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ); assertNotNull( entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() );
AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" ); AttributeBinding idAttributeBinding = entityBinding.locateAttributeBinding( "id" );
assertNotNull( idAttributeBinding ); assertNotNull( idAttributeBinding );
assertSame( idAttributeBinding, entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ); assertSame( idAttributeBinding, entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() );
assertSame( LongType.INSTANCE, idAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() ); assertSame( LongType.INSTANCE, idAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() );
@ -152,11 +177,11 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
assertSame( Types.BIGINT, idDataType.getTypeCode() ); assertSame( Types.BIGINT, idDataType.getTypeCode() );
assertSame( LongType.INSTANCE.getName(), idDataType.getTypeName() ); assertSame( LongType.INSTANCE.getName(), idDataType.getTypeName() );
assertNotNull( entityBinding.getAttributeBinding( "name" ) ); assertNotNull( entityBinding.locateAttributeBinding( "name" ) );
assertNotNull( entityBinding.getAttributeBinding( "name" ).getAttribute() ); assertNotNull( entityBinding.locateAttributeBinding( "name" ).getAttribute() );
assertTrue( entityBinding.getAttributeBinding( "name" ).getAttribute().isSingular() ); assertTrue( entityBinding.locateAttributeBinding( "name" ).getAttribute().isSingular() );
SingularAttributeBinding nameBinding = (SingularAttributeBinding) entityBinding.getAttributeBinding( "name" ); SingularAttributeBinding nameBinding = (SingularAttributeBinding) entityBinding.locateAttributeBinding( "name" );
assertSame( StringType.INSTANCE, nameBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() ); assertSame( StringType.INSTANCE, nameBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() );
assertNotNull( nameBinding.getAttribute() ); assertNotNull( nameBinding.getAttribute() );
assertNotNull( nameBinding.getValue() ); assertNotNull( nameBinding.getValue() );

View File

@ -32,19 +32,23 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class BasicAnnotationBindingTests extends AbstractBasicBindingTests { public class BasicAnnotationBindingTests extends AbstractBasicBindingTests {
public MetadataImpl addSourcesForSimpleEntityBinding(MetadataSources sources) { @Override
public void addSourcesForSimpleEntityBinding(MetadataSources sources) {
sources.addAnnotatedClass( SimpleEntity.class ); sources.addAnnotatedClass( SimpleEntity.class );
return (MetadataImpl) sources.buildMetadata();
} }
public MetadataImpl addSourcesForSimpleVersionedEntityBinding(MetadataSources sources) { @Override
public void addSourcesForSimpleVersionedEntityBinding(MetadataSources sources) {
sources.addAnnotatedClass( SimpleVersionedEntity.class ); sources.addAnnotatedClass( SimpleVersionedEntity.class );
return (MetadataImpl) sources.buildMetadata();
} }
public MetadataImpl addSourcesForManyToOne(MetadataSources sources) { @Override
public void addSourcesForManyToOne(MetadataSources sources) {
sources.addAnnotatedClass( ManyToOneEntity.class ); sources.addAnnotatedClass( ManyToOneEntity.class );
sources.addAnnotatedClass( SimpleEntity.class ); }
return (MetadataImpl) sources.buildMetadata();
@Override
public void addSourcesForComponentBinding(MetadataSources sources) {
sources.addAnnotatedClass( SimpleEntityWithSimpleComponent.class );
} }
} }

View File

@ -24,7 +24,6 @@
package org.hibernate.metamodel.binding; package org.hibernate.metamodel.binding;
import org.hibernate.metamodel.MetadataSources; import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.source.internal.MetadataImpl;
/** /**
* Basic tests of {@code hbm.xml} binding code * Basic tests of {@code hbm.xml} binding code
@ -32,19 +31,19 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class BasicHbmBindingTests extends AbstractBasicBindingTests { public class BasicHbmBindingTests extends AbstractBasicBindingTests {
public MetadataImpl addSourcesForSimpleEntityBinding(MetadataSources sources) { public void addSourcesForSimpleEntityBinding(MetadataSources sources) {
sources.addResource( "org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" ); sources.addResource( "org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" );
return (MetadataImpl) sources.buildMetadata();
} }
public MetadataImpl addSourcesForSimpleVersionedEntityBinding(MetadataSources sources) { public void addSourcesForSimpleVersionedEntityBinding(MetadataSources sources) {
sources.addResource( "org/hibernate/metamodel/binding/SimpleVersionedEntity.hbm.xml" ); sources.addResource( "org/hibernate/metamodel/binding/SimpleVersionedEntity.hbm.xml" );
return (MetadataImpl) sources.buildMetadata();
} }
public MetadataImpl addSourcesForManyToOne(MetadataSources sources) { public void addSourcesForManyToOne(MetadataSources sources) {
sources.addResource( "org/hibernate/metamodel/binding/ManyToOneEntity.hbm.xml" ); sources.addResource( "org/hibernate/metamodel/binding/ManyToOneEntity.hbm.xml" );
sources.addResource( "org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" ); }
return (MetadataImpl) sources.buildMetadata();
public void addSourcesForComponentBinding(MetadataSources sources) {
sources.addResource( "org/hibernate/metamodel/binding/SimpleEntityWithSimpleComponent.hbm.xml" );
} }
} }

View File

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<hibernate-mapping
xmlns="http://www.hibernate.org/xsd/hibernate-mapping"
xsi:schemaLocation="http://www.hibernate.org/xsd/hibernate-mapping hibernate-mapping-4.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
package="org.hibernate.metamodel.binding">
<class name="SimpleEntityWithSimpleComponent">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
<component name="simpleComponent" class="SimpleEntityWithSimpleComponent$SimpleComponent">
<property name="value1"/>
<property name="value2"/>
</component>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,92 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author Steve Ebersole
*/
@Entity
public class SimpleEntityWithSimpleComponent {
@Id
private Long id;
private String name;
private SimpleComponent simpleComponent;
public SimpleEntityWithSimpleComponent() {
}
public SimpleEntityWithSimpleComponent(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public SimpleComponent getSimpleComponent() {
return simpleComponent;
}
public void setSimpleComponent(SimpleComponent simpleComponent) {
this.simpleComponent = simpleComponent;
}
@Embeddable
public static class SimpleComponent {
private String value1;
private String value2;
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
}
}

View File

@ -52,7 +52,7 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase {
@Resources(annotatedClasses = { FieldAccess.class }) @Resources(annotatedClasses = { FieldAccess.class })
public void testDefaultFieldAccess() { public void testDefaultFieldAccess() {
EntityBinding binding = getEntityBinding( FieldAccess.class ); EntityBinding binding = getEntityBinding( FieldAccess.class );
assertEquals( "Wrong access type", "field", binding.getAttributeBinding( "id" ).getPropertyAccessorName() ); assertEquals( "Wrong access type", "field", binding.locateAttributeBinding( "id" ).getPropertyAccessorName() );
} }
@Entity @Entity
@ -69,7 +69,7 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase {
@Resources(annotatedClasses = { PropertyAccess.class }) @Resources(annotatedClasses = { PropertyAccess.class })
public void testDefaultPropertyAccess() { public void testDefaultPropertyAccess() {
EntityBinding binding = getEntityBinding( PropertyAccess.class ); EntityBinding binding = getEntityBinding( PropertyAccess.class );
assertEquals( "Wrong access type", "property", binding.getAttributeBinding( "id" ).getPropertyAccessorName() ); assertEquals( "Wrong access type", "property", binding.locateAttributeBinding( "id" ).getPropertyAccessorName() );
} }
@ -105,11 +105,11 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase {
@Resources(annotatedClasses = { MixedAccess.class }) @Resources(annotatedClasses = { MixedAccess.class })
public void testMixedAccess() { public void testMixedAccess() {
EntityBinding binding = getEntityBinding( MixedAccess.class ); EntityBinding binding = getEntityBinding( MixedAccess.class );
assertEquals( "Wrong access type", "field", binding.getAttributeBinding( "id" ).getPropertyAccessorName() ); assertEquals( "Wrong access type", "field", binding.locateAttributeBinding( "id" ).getPropertyAccessorName() );
assertEquals( assertEquals(
"Wrong access type", "Wrong access type",
"property", "property",
binding.getAttributeBinding( "name" ).getPropertyAccessorName() binding.locateAttributeBinding( "name" ).getPropertyAccessorName()
); );
} }
@ -136,7 +136,7 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase {
assertEquals( assertEquals(
"Wrong access type", "Wrong access type",
"field", "field",
binding.getAttributeBinding( "id" ).getPropertyAccessorName() binding.locateAttributeBinding( "id" ).getPropertyAccessorName()
); );
@ -144,7 +144,7 @@ public class AccessBindingTest extends BaseAnnotationBindingTestCase {
assertEquals( assertEquals(
"Wrong access type", "Wrong access type",
"property", "property",
binding.getAttributeBinding( "name" ).getPropertyAccessorName() binding.locateAttributeBinding( "name" ).getPropertyAccessorName()
); );
} }

View File

@ -31,7 +31,6 @@ import javax.persistence.MappedSuperclass;
import org.junit.Test; import org.junit.Test;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.SingularAttributeBinding; import org.hibernate.metamodel.binding.SingularAttributeBinding;
import org.hibernate.metamodel.domain.NonEntity; import org.hibernate.metamodel.domain.NonEntity;
@ -54,7 +53,7 @@ public class MappedSuperclassTest extends BaseAnnotationBindingTestCase {
// @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class }) // @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class })
public void testSimpleAttributeOverrideInMappedSuperclass() { public void testSimpleAttributeOverrideInMappedSuperclass() {
EntityBinding binding = getEntityBinding( MyEntity.class ); EntityBinding binding = getEntityBinding( MyEntity.class );
SingularAttributeBinding nameBinding = (SingularAttributeBinding) binding.getAttributeBinding( "name" ); SingularAttributeBinding nameBinding = (SingularAttributeBinding) binding.locateAttributeBinding( "name" );
assertNotNull( "the name attribute should be bound to MyEntity", nameBinding ); assertNotNull( "the name attribute should be bound to MyEntity", nameBinding );
Column column = (Column) nameBinding.getValue(); Column column = (Column) nameBinding.getValue();
@ -65,7 +64,7 @@ public class MappedSuperclassTest extends BaseAnnotationBindingTestCase {
// @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class }) // @Resources(annotatedClasses = { MyMappedSuperClass.class, MyEntity.class, MyMappedSuperClassBase.class })
public void testLastAttributeOverrideWins() { public void testLastAttributeOverrideWins() {
EntityBinding binding = getEntityBinding( MyEntity.class ); EntityBinding binding = getEntityBinding( MyEntity.class );
SingularAttributeBinding fooBinding = (SingularAttributeBinding) binding.getAttributeBinding( "foo" ); SingularAttributeBinding fooBinding = (SingularAttributeBinding) binding.locateAttributeBinding( "foo" );
assertNotNull( "the foo attribute should be bound to MyEntity", fooBinding ); assertNotNull( "the foo attribute should be bound to MyEntity", fooBinding );
Column column = (Column) fooBinding.getValue(); Column column = (Column) fooBinding.getValue();

View File

@ -34,7 +34,7 @@ public class QuotedIdentifierTest extends BaseAnnotationBindingTestCase {
} }
private void assertIdentifierEquals(String expected, EntityBinding realValue) { private void assertIdentifierEquals(String expected, EntityBinding realValue) {
org.hibernate.metamodel.relational.Table table = (org.hibernate.metamodel.relational.Table) realValue.getBaseTable(); org.hibernate.metamodel.relational.Table table = (org.hibernate.metamodel.relational.Table) realValue.getPrimaryTable();
assertEquals( Identifier.toIdentifier( expected ), table.getTableName() ); assertEquals( Identifier.toIdentifier( expected ), table.getTableName() );
} }

View File

@ -60,7 +60,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase {
assertEquals( assertEquals(
"wrong table name", "wrong table name",
"TableNameTest$A", "TableNameTest$A",
( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName()
); );
binding = getEntityBinding( B.class ); binding = getEntityBinding( B.class );
@ -68,7 +68,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase {
assertEquals( assertEquals(
"wrong table name", "wrong table name",
"TableNameTest$A", "TableNameTest$A",
( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName()
); );
} }
@ -93,7 +93,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase {
assertEquals( assertEquals(
"wrong table name", "wrong table name",
"FOO", "FOO",
( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName()
); );
binding = getEntityBinding( JoinedB.class ); binding = getEntityBinding( JoinedB.class );
@ -101,7 +101,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase {
assertEquals( assertEquals(
"wrong table name", "wrong table name",
"TableNameTest$JoinedB", "TableNameTest$JoinedB",
( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName()
); );
} }
@ -126,7 +126,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase {
assertEquals( assertEquals(
"wrong table name", "wrong table name",
"TableNameTest$TablePerClassA", "TableNameTest$TablePerClassA",
( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName()
); );
binding = getEntityBinding( TablePerClassB.class ); binding = getEntityBinding( TablePerClassB.class );
@ -134,7 +134,7 @@ public class TableNameTest extends BaseAnnotationBindingTestCase {
assertEquals( assertEquals(
"wrong table name", "wrong table name",
"TableNameTest$TablePerClassB", "TableNameTest$TablePerClassB",
( (org.hibernate.metamodel.relational.Table) binding.getBaseTable() ).getTableName().getName() ( (org.hibernate.metamodel.relational.Table) binding.getPrimaryTable() ).getTableName().getName()
); );
} }
} }

View File

@ -50,7 +50,7 @@ public class UniqueConstraintBindingTest extends BaseAnnotationBindingTestCase {
@Resources(annotatedClasses = TableWithUniqueConstraint.class) @Resources(annotatedClasses = TableWithUniqueConstraint.class)
public void testTableUniqueConstraints() { public void testTableUniqueConstraints() {
EntityBinding binding = getEntityBinding( TableWithUniqueConstraint.class ); EntityBinding binding = getEntityBinding( TableWithUniqueConstraint.class );
TableSpecification table = binding.getBaseTable(); TableSpecification table = binding.getPrimaryTable();
Iterable<UniqueKey> uniqueKeyIterable = table.getUniqueKeys(); Iterable<UniqueKey> uniqueKeyIterable = table.getUniqueKeys();
assertNotNull( uniqueKeyIterable ); assertNotNull( uniqueKeyIterable );
int i = 0; int i = 0;