HHH-6371 - Develop metamodel binding creation using a push approach

This commit is contained in:
Steve Ebersole 2011-07-11 00:33:39 -05:00
parent a7179fbc49
commit c4c8c28a3b
35 changed files with 1474 additions and 499 deletions

View File

@ -54,6 +54,14 @@ public class BeanInfoHelper {
throw new BeanIntrospectionException( "Bean [" + bean + "] was not of declared bean type [" + beanClass.getName() + "]" );
}
visitBeanInfo( beanClass, stopClass, delegate );
}
public static void visitBeanInfo(Class beanClass, BeanInfoDelegate delegate) {
visitBeanInfo( beanClass, Object.class, delegate );
}
public static void visitBeanInfo(Class beanClass, Class stopClass, BeanInfoDelegate delegate) {
try {
BeanInfo info = Introspector.getBeanInfo( beanClass, stopClass );
try {
@ -76,4 +84,6 @@ public class BeanInfoHelper {
throw new BeanIntrospectionException( "Unable to determine bean info from class [" + beanClass.getName() + "]", e );
}
}
}

View File

@ -76,6 +76,8 @@ public interface Metadata {
public Iterable<PluralAttributeBinding> getCollectionBindings();
public TypeDef getTypeDefinition(String name);
public Iterable<TypeDef> getTypeDefinitions();
public Iterable<FilterDefinition> getFilterDefinitions();

View File

@ -25,7 +25,7 @@ package org.hibernate.metamodel.binder.source;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.domain.JavaType;
import org.hibernate.metamodel.domain.Type;
import org.hibernate.service.ServiceRegistry;
/**
@ -42,7 +42,7 @@ public interface BindingContext {
public <T> Class<T> locateClassByName(String name);
public JavaType makeJavaType(String className);
public Type makeJavaType(String className);
public boolean isGloballyQuotedIdentifiers();

View File

@ -71,8 +71,6 @@ public interface MetadataImplementor extends Metadata, BindingContext, Mapping {
public void addResultSetMapping(ResultSetMappingDefinition resultSetMappingDefinition);
public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject);
// todo : this needs to move to AnnotationBindingContext
public void setGloballyQuotedIdentifiers(boolean b);

View File

@ -36,7 +36,7 @@ import org.hibernate.metamodel.binder.source.MetadataImplementor;
import org.hibernate.metamodel.binder.source.annotations.entity.ConfiguredClass;
import org.hibernate.metamodel.binder.source.annotations.entity.EntityBinder;
import org.hibernate.metamodel.binder.source.internal.OverriddenMappingDefaults;
import org.hibernate.metamodel.domain.JavaType;
import org.hibernate.metamodel.domain.Type;
import org.hibernate.service.ServiceRegistry;
/**
@ -120,7 +120,7 @@ public class AnnotationsMetadataProcessor implements AnnotationsBindingContext {
}
@Override
public JavaType makeJavaType(String className) {
public Type makeJavaType(String className) {
return parentBindingContext.makeJavaType( className );
}

View File

@ -63,7 +63,7 @@ import org.hibernate.metamodel.binder.source.internal.JaxbRoot;
import org.hibernate.metamodel.binder.source.internal.MetadataImpl;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.domain.Hierarchical;
import org.hibernate.metamodel.domain.JavaType;
import org.hibernate.metamodel.domain.Type;
import org.hibernate.metamodel.domain.NonEntity;
import org.hibernate.metamodel.domain.Superclass;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings;
@ -270,18 +270,13 @@ public class AnnotationsSourceProcessor implements SourceProcessor, AnnotationsB
return classLoaderService.getValue().classForName( name );
}
@Override
public boolean isGloballyQuotedIdentifiers() {
return metadata.isGloballyQuotedIdentifiers();
}
private Map<String,JavaType> nameToJavaTypeMap = new HashMap<String, JavaType>();
private Map<String,Type> nameToJavaTypeMap = new HashMap<String, Type>();
@Override
public JavaType makeJavaType(String className) {
JavaType javaType = nameToJavaTypeMap.get( className );
public Type makeJavaType(String className) {
Type javaType = nameToJavaTypeMap.get( className );
if ( javaType == null ) {
javaType = new JavaType( locateClassByName( className ) );
javaType = metadata.makeJavaType( className );
nameToJavaTypeMap.put( className, javaType );
}
return javaType;
@ -291,6 +286,11 @@ public class AnnotationsSourceProcessor implements SourceProcessor, AnnotationsB
public Value<Class<?>> makeClassReference(String className) {
return new Value<Class<?>>( locateClassByName( className ) );
}
@Override
public boolean isGloballyQuotedIdentifiers() {
return metadata.isGloballyQuotedIdentifiers();
}
}

View File

@ -585,7 +585,7 @@ public class EntityBinder {
//todo throw exception?
}
for ( String columnName : columnNames ) {
uniqueKey.addColumn( table.getOrCreateColumn( columnName ) );
uniqueKey.addColumn( table.locateOrCreateColumn( columnName ) );
}
}
}
@ -620,8 +620,7 @@ public class EntityBinder {
throw new AssertionFailure( "Unexpected attribute type for id attribute" );
}
SingularAttribute attribute = entityBinding.getEntity().getOrCreateComponentAttribute( idName );
SingularAttribute attribute = entityBinding.getEntity().locateOrCreateComponentAttribute( idName );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleIdAttributeBinding( attribute );
@ -669,7 +668,7 @@ public class EntityBinder {
// now that we have the id attribute we can create the attribute and binding
MappedAttribute idAttribute = iter.next();
Attribute attribute = container.getOrCreateSingularAttribute( idAttribute.getName() );
Attribute attribute = container.locateOrCreateSingularAttribute( idAttribute.getName() );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleIdAttributeBinding( attribute );
attributeBinding.initialize( new AttributeBindingStateImpl( (SimpleAttribute) idAttribute ) );
@ -821,7 +820,7 @@ public class EntityBinder {
for ( Map.Entry<String, EmbeddableClass> entry : configuredClass.getEmbeddedClasses().entrySet() ) {
String attributeName = entry.getKey();
EmbeddableClass embeddedClass = entry.getValue();
SingularAttribute component = attributeContainer.getOrCreateComponentAttribute( attributeName );
SingularAttribute component = attributeContainer.locateOrCreateComponentAttribute( attributeName );
for ( SimpleAttribute simpleAttribute : embeddedClass.getSimpleAttributes() ) {
bindSingleMappedAttribute(
entityBinding,
@ -845,7 +844,7 @@ public class EntityBinder {
AssociationAttribute associationAttribute) {
switch ( associationAttribute.getAssociationType() ) {
case MANY_TO_ONE: {
container.getOrCreateSingularAttribute( associationAttribute.getName() );
entityBinding.getEntity().locateOrCreateSingularAttribute( associationAttribute.getName() );
ManyToOneAttributeBinding manyToOneAttributeBinding = entityBinding.makeManyToOneAttributeBinding(
associationAttribute.getName()
);
@ -877,7 +876,8 @@ public class EntityBinder {
return;
}
Attribute attribute = container.getOrCreateSingularAttribute( simpleAttribute.getName() );
String attributeName = simpleAttribute.getName();
SingularAttribute attribute = entityBinding.getEntity().locateOrCreateSingularAttribute( attributeName );
SimpleAttributeBinding attributeBinding;
if ( simpleAttribute.isDiscriminator() ) {

View File

@ -0,0 +1,48 @@
/*
* 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.binder.source.hbm;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Steve Ebersole
*/
public class AbstractSubEntityContainer implements SubEntityContainer {
private List<EntityHierarchySubEntity> subEntityDescriptors;
public void addSubEntityDescriptor(EntityHierarchySubEntity subEntityDescriptor) {
if ( subEntityDescriptors == null ) {
subEntityDescriptors = new ArrayList<EntityHierarchySubEntity>();
}
subEntityDescriptors.add( subEntityDescriptor );
}
public Iterable<EntityHierarchySubEntity> subEntityDescriptors() {
return subEntityDescriptors == null
? Collections.<EntityHierarchySubEntity>emptyList()
: subEntityDescriptors;
}
}

View File

@ -23,23 +23,59 @@
*/
package org.hibernate.metamodel.binder.source.hbm;
import java.beans.BeanInfo;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.hibernate.EntityMode;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.internal.util.Value;
import org.hibernate.internal.util.beans.BeanInfoHelper;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.binder.MappingException;
import org.hibernate.metamodel.binder.source.MetadataImplementor;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.JoinElementSource;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement;
import org.hibernate.metamodel.binding.BagBinding;
import org.hibernate.metamodel.binding.Caching;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.domain.AbstractAttributeContainer;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Identifier;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Size;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.Tuple;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLAnyElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLBagElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLCacheElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLColumnElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLComponentElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLDynamicComponentElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLIdbagElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinedSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLListElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLManyToOneElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLMapElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLOneToOneElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLParamElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLPropertiesElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLPropertyElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSetElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlDeleteElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlInsertElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlUpdateElement;
@ -54,72 +90,96 @@ import org.hibernate.tuple.entity.EntityTuplizer;
* @author Steve Ebersole
*/
public class BindingCreator {
private final HbmBindingContext bindingContext;
private final MetadataImplementor metadata;
private final List<String> processedEntityNames;
public BindingCreator(HbmBindingContext bindingContext, List<String> processedEntityNames) {
this.bindingContext = bindingContext;
private InheritanceType currentInheritanceType;
private HbmBindingContext currentBindingContext;
public BindingCreator(MetadataImplementor metadata, List<String> processedEntityNames) {
this.metadata = metadata;
this.processedEntityNames = processedEntityNames;
}
public EntityBinding createEntityBinding(EntityElement entityElement, String containingSuperEntityName) {
final String entityName = bindingContext.determineEntityName( entityElement );
if ( processedEntityNames.contains( entityName ) ) {
return bindingContext.getMetadataImplementor().getEntityBinding( entityName );
// todo : currently this does not allow inheritance across hbm/annotations. Do we need to?
public void processEntityHierarchy(EntityHierarchy entityHierarchy) {
currentInheritanceType = entityHierarchy.getHierarchyInheritanceType();
EntityBinding rootEntityBinding = createEntityBinding( entityHierarchy.getEntitySourceInformation(), null );
if ( currentInheritanceType != InheritanceType.NO_INHERITANCE ) {
processHierarchySubEntities( entityHierarchy, rootEntityBinding );
}
}
final EntityBinding entityBinding = doEntityBindingCreation( entityElement, containingSuperEntityName );
private void processHierarchySubEntities(SubEntityContainer subEntityContainer, EntityBinding superEntityBinding) {
for ( EntityHierarchySubEntity subEntity : subEntityContainer.subEntityDescriptors() ) {
EntityBinding entityBinding = createEntityBinding( subEntity.getEntitySourceInformation(), superEntityBinding );
processHierarchySubEntities( subEntity, entityBinding );
}
}
bindingContext.getMetadataImplementor().addEntity( entityBinding );
private EntityBinding createEntityBinding(EntitySourceInformation entitySourceInfo, EntityBinding superEntityBinding) {
if ( processedEntityNames.contains( entitySourceInfo.getMappedEntityName() ) ) {
return metadata.getEntityBinding( entitySourceInfo.getMappedEntityName() );
}
currentBindingContext = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext();
try {
final EntityBinding entityBinding = doCreateEntityBinding( entitySourceInfo, superEntityBinding );
metadata.addEntity( entityBinding );
processedEntityNames.add( entityBinding.getEntity().getName() );
return entityBinding;
}
finally {
currentBindingContext = null;
}
}
private EntityBinding doEntityBindingCreation(EntityElement entityElement, String containingSuperEntityName) {
if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) {
return makeEntityBinding( (XMLHibernateMapping.XMLClass) entityElement );
private EntityBinding doCreateEntityBinding(EntitySourceInformation entitySourceInfo, EntityBinding superEntityBinding) {
final EntityBinding entityBinding = createBasicEntityBinding( entitySourceInfo, superEntityBinding );
bindPrimaryTable( entitySourceInfo, entityBinding );
bindAttributes( entitySourceInfo, entityBinding );
bindSecondaryTables( entitySourceInfo, entityBinding );
bindTableUniqueConstraints( entityBinding );
return entityBinding;
}
private EntityBinding createBasicEntityBinding(
EntitySourceInformation entitySourceInfo,
EntityBinding superEntityBinding) {
if ( superEntityBinding == null ) {
return makeRootEntityBinding( entitySourceInfo );
}
else {
String superEntityName = containingSuperEntityName;
if ( superEntityName == null ) {
final SubclassEntityElement subclass = (SubclassEntityElement) entityElement;
superEntityName = bindingContext.qualifyClassName( subclass.getExtends() );
if ( currentInheritanceType == InheritanceType.SINGLE_TABLE ) {
return makeDiscriminatedSubclassBinding( entitySourceInfo, superEntityBinding );
}
if ( superEntityName == null) {
throw new MappingException(
"Encountered inheritance strategy, but no super type found",
bindingContext.getOrigin()
);
else if ( currentInheritanceType == InheritanceType.JOINED ) {
return makeJoinedSubclassBinding( entitySourceInfo, superEntityBinding );
}
if ( XMLSubclassElement.class.isInstance( entityElement ) ) {
return makeEntityBinding( (XMLSubclassElement) entityElement, superEntityName );
}
else if ( XMLJoinedSubclassElement.class.isInstance( entityElement ) ) {
return makeEntityBinding( (XMLJoinedSubclassElement) entityElement, superEntityName );
}
else if ( XMLUnionSubclassElement.class.isInstance( entityElement ) ) {
return makeEntityBinding( (XMLUnionSubclassElement) entityElement, superEntityName );
else if ( currentInheritanceType == InheritanceType.TABLE_PER_CLASS ) {
return makeUnionedSubclassBinding( entitySourceInfo, superEntityBinding );
}
else {
throw new MappingException(
"unknown type of class or subclass: " + entityElement.getClass().getName(),
bindingContext.getOrigin()
);
// extreme internal error!
throw new RuntimeException( "Internal condition failure" );
}
}
}
protected EntityBinding makeEntityBinding(XMLHibernateMapping.XMLClass xmlClass) {
private EntityBinding makeRootEntityBinding(EntitySourceInformation entitySourceInfo) {
final EntityBinding entityBinding = new EntityBinding();
// todo : this is actually not correct
// the problem is that we need to know whether we have mapped subclasses which happens later
// one option would be to simply reset the InheritanceType at that time.
entityBinding.setInheritanceType( InheritanceType.NO_INHERITANCE );
entityBinding.setInheritanceType( currentInheritanceType );
entityBinding.setRoot( true );
final String entityName = bindingContext.determineEntityName( xmlClass );
final XMLHibernateMapping.XMLClass xmlClass = (XMLHibernateMapping.XMLClass) entitySourceInfo.getEntityElement();
final String entityName = entitySourceInfo.getMappedEntityName();
final String verbatimClassName = xmlClass.getName();
final EntityMode entityMode = verbatimClassName == null ? EntityMode.MAP : EntityMode.POJO;
@ -127,41 +187,37 @@ public class BindingCreator {
final String className;
if ( entityMode == EntityMode.POJO ) {
className = bindingContext.qualifyClassName( verbatimClassName );
className = entitySourceInfo.getSourceMappingDocument()
.getMappingLocalBindingContext()
.qualifyClassName( verbatimClassName );
}
else {
className = null;
}
Entity entity = new Entity( entityName, className, bindingContext.makeClassReference( className ), null );
Entity entity = new Entity(
entityName,
className,
entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext().makeClassReference( className ),
null
);
entityBinding.setEntity( entity );
performBasicEntityBind( entityBinding, xmlClass );
performBasicEntityBind( entityBinding, entitySourceInfo );
entityBinding.setMutable( xmlClass.isMutable() );
entityBinding.setExplicitPolymorphism( "explicit".equals( xmlClass.getPolymorphism() ) );
entityBinding.setWhereFilter( xmlClass.getWhere() );
entityBinding.setRowId( xmlClass.getRowid() );
entityBinding.setOptimisticLockStyle( interpretOptimisticLockStyle( xmlClass ) );
entityBinding.setCaching( interpretCaching( xmlClass, entityName ) );
entityBinding.setOptimisticLockStyle( interpretOptimisticLockStyle( entitySourceInfo ) );
entityBinding.setCaching( interpretCaching( entitySourceInfo ) );
return entityBinding;
}
private static Caching interpretCaching(XMLHibernateMapping.XMLClass xmlClass, String entityName) {
final XMLCacheElement cache = xmlClass.getCache();
if ( cache == null ) {
return null;
}
final String region = cache.getRegion() != null ? cache.getRegion() : entityName;
final AccessType accessType = Enum.valueOf( AccessType.class, cache.getUsage() );
final boolean cacheLazyProps = !"non-lazy".equals( cache.getInclude() );
return new Caching( region, accessType, cacheLazyProps );
}
private OptimisticLockStyle interpretOptimisticLockStyle(XMLHibernateMapping.XMLClass entityClazz) {
private OptimisticLockStyle interpretOptimisticLockStyle(EntitySourceInformation entitySourceInfo) {
final String optimisticLockModeString = Helper.getStringValue(
entityClazz.getOptimisticLock(),
( (XMLHibernateMapping.XMLClass) entitySourceInfo.getEntityElement() ).getOptimisticLock(),
"version"
);
try {
@ -170,45 +226,69 @@ public class BindingCreator {
catch (Exception e) {
throw new MappingException(
"Unknown optimistic-lock value : " + optimisticLockModeString,
bindingContext.getOrigin()
entitySourceInfo.getSourceMappingDocument().getOrigin()
);
}
}
protected EntityBinding makeEntityBinding(XMLSubclassElement subclassElement, String superEntityName) {
private static Caching interpretCaching(EntitySourceInformation entitySourceInfo) {
final XMLCacheElement cache = ( (XMLHibernateMapping.XMLClass) entitySourceInfo.getEntityElement() ).getCache();
if ( cache == null ) {
return null;
}
final String region = cache.getRegion() != null ? cache.getRegion() : entitySourceInfo.getMappedEntityName();
final AccessType accessType = Enum.valueOf( AccessType.class, cache.getUsage() );
final boolean cacheLazyProps = !"non-lazy".equals( cache.getInclude() );
return new Caching( region, accessType, cacheLazyProps );
}
private EntityBinding makeDiscriminatedSubclassBinding(
EntitySourceInformation entitySourceInfo,
EntityBinding superEntityBinding) {
// temporary!!!
final EntityBinding entityBinding = new EntityBinding();
entityBinding.setInheritanceType( InheritanceType.SINGLE_TABLE );
bindSuperType( entityBinding, superEntityBinding );
final String entityName = bindingContext.determineEntityName( subclassElement );
final String verbatimClassName = subclassElement.getName();
final String verbatimClassName = entitySourceInfo.getEntityElement().getName();
final EntityMode entityMode = verbatimClassName == null ? EntityMode.MAP : EntityMode.POJO;
entityBinding.setEntityMode( entityMode );
final String className;
if ( entityMode == EntityMode.POJO ) {
className = bindingContext.qualifyClassName( verbatimClassName );
className = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext().qualifyClassName( verbatimClassName );
}
else {
className = null;
}
final Entity entity = new Entity( entityName, className, bindingContext.makeClassReference( className ), null );
final Entity entity = new Entity(
entitySourceInfo.getMappedEntityName(),
className,
entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext().makeClassReference( className ),
null
);
entityBinding.setEntity( entity );
performBasicEntityBind( entityBinding, subclassElement );
performBasicEntityBind( entityBinding, entitySourceInfo );
return entityBinding;
}
protected EntityBinding makeEntityBinding(XMLJoinedSubclassElement joinedEntityElement, String superEntityName) {
private EntityBinding makeJoinedSubclassBinding(
EntitySourceInformation entitySourceInfo,
EntityBinding superEntityBinding) {
// temporary!!!
final EntityBinding entityBinding = new EntityBinding();
entityBinding.setInheritanceType( InheritanceType.JOINED );
bindSuperType( entityBinding, superEntityBinding );
final XMLJoinedSubclassElement joinedEntityElement = (XMLJoinedSubclassElement) entitySourceInfo.getEntityElement();
final HbmBindingContext bindingContext = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext();
final String entityName = bindingContext.determineEntityName( joinedEntityElement );
final String verbatimClassName = joinedEntityElement.getName();
@ -227,16 +307,22 @@ public class BindingCreator {
final Entity entity = new Entity( entityName, className, bindingContext.makeClassReference( className ), null );
entityBinding.setEntity( entity );
performBasicEntityBind( entityBinding, joinedEntityElement );
performBasicEntityBind( entityBinding, entitySourceInfo );
return entityBinding;
}
protected EntityBinding makeEntityBinding(XMLUnionSubclassElement unionEntityElement, String superEntityName) {
private EntityBinding makeUnionedSubclassBinding(
EntitySourceInformation entitySourceInfo,
EntityBinding superEntityBinding) {
// temporary!!!
final EntityBinding entityBinding = new EntityBinding();
entityBinding.setInheritanceType( InheritanceType.TABLE_PER_CLASS );
bindSuperType( entityBinding, superEntityBinding );
final XMLUnionSubclassElement unionEntityElement = (XMLUnionSubclassElement) entitySourceInfo.getEntityElement();
final HbmBindingContext bindingContext = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext();
final String entityName = bindingContext.determineEntityName( unionEntityElement );
final String verbatimClassName = unionEntityElement.getName();
@ -255,15 +341,23 @@ public class BindingCreator {
final Entity entity = new Entity( entityName, className, bindingContext.makeClassReference( className ), null );
entityBinding.setEntity( entity );
performBasicEntityBind( entityBinding, unionEntityElement );
performBasicEntityBind( entityBinding, entitySourceInfo );
return entityBinding;
}
private void bindSuperType(EntityBinding entityBinding, EntityBinding superEntityBinding) {
// entityBinding.setSuperEntityBinding( superEntityBinding );
// // not sure what to do with the domain model super type...
}
@SuppressWarnings( {"unchecked"})
protected void performBasicEntityBind(EntityBinding entityBinding, EntityElement entityElement) {
private void performBasicEntityBind(EntityBinding entityBinding, EntitySourceInformation entitySourceInfo) {
entityBinding.setJpaEntityName( null );
final EntityElement entityElement = entitySourceInfo.getEntityElement();
final HbmBindingContext bindingContext = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext();
final String proxy = entityElement.getProxy();
final boolean isLazy = entityElement.isLazy() == null
? true
@ -287,7 +381,10 @@ public class BindingCreator {
entityBinding.setLazy( isLazy );
}
final String customTuplizerClassName = extractCustomTuplizerClassName( entityElement, entityBinding.getEntityMode() );
final String customTuplizerClassName = extractCustomTuplizerClassName(
entityElement,
entityBinding.getEntityMode()
);
if ( customTuplizerClassName != null ) {
entityBinding.setCustomEntityTuplizerClass( bindingContext.<EntityTuplizer>locateClassByName( customTuplizerClassName ) );
}
@ -345,4 +442,422 @@ public class BindingCreator {
}
return null;
}
private void bindPrimaryTable(EntitySourceInformation entitySourceInformation, EntityBinding entityBinding) {
final EntityElement entityElement = entitySourceInformation.getEntityElement();
final HbmBindingContext bindingContext = entitySourceInformation.getSourceMappingDocument().getMappingLocalBindingContext();
if ( XMLSubclassElement.class.isInstance( entityElement ) ) {
// todo : need to look it up from root entity, or have persister manage it
}
else {
// todo : add mixin interface
final String explicitTableName;
final String explicitSchemaName;
final String explicitCatalogName;
if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) {
explicitTableName = ( (XMLHibernateMapping.XMLClass) entityElement ).getTable();
explicitSchemaName = ( (XMLHibernateMapping.XMLClass) entityElement ).getSchema();
explicitCatalogName = ( (XMLHibernateMapping.XMLClass) entityElement ).getCatalog();
}
else if ( XMLJoinedSubclassElement.class.isInstance( entityElement ) ) {
explicitTableName = ( (XMLJoinedSubclassElement) entityElement ).getTable();
explicitSchemaName = ( (XMLJoinedSubclassElement) entityElement ).getSchema();
explicitCatalogName = ( (XMLJoinedSubclassElement) entityElement ).getCatalog();
}
else if ( XMLUnionSubclassElement.class.isInstance( entityElement ) ) {
explicitTableName = ( (XMLUnionSubclassElement) entityElement ).getTable();
explicitSchemaName = ( (XMLUnionSubclassElement) entityElement ).getSchema();
explicitCatalogName = ( (XMLUnionSubclassElement) entityElement ).getCatalog();
}
else {
// throw up
explicitTableName = null;
explicitSchemaName = null;
explicitCatalogName = null;
}
final NamingStrategy namingStrategy = bindingContext.getMetadataImplementor()
.getOptions()
.getNamingStrategy();
final String tableName = explicitTableName != null
? namingStrategy.tableName( explicitTableName )
: namingStrategy.tableName( namingStrategy.classToTableName( entityBinding.getEntity().getName() ) );
final String schemaName = explicitSchemaName == null
? bindingContext.getMappingDefaults().getSchemaName()
: explicitSchemaName;
final String catalogName = explicitCatalogName == null
? bindingContext.getMappingDefaults().getCatalogName()
: explicitCatalogName;
final Schema schema = metadata.getDatabase().getSchema( new Schema.Name( schemaName, catalogName ) );
entityBinding.setBaseTable( schema.locateOrCreateTable( Identifier.toIdentifier( tableName ) ) );
}
}
private Stack<TableSpecification> attributeColumnTableStack = new Stack<TableSpecification>();
private void bindAttributes(final EntitySourceInformation entitySourceInformation, EntityBinding entityBinding) {
// 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
// for now, simply assume all columns come from the base table....
attributeColumnTableStack.push( entityBinding.getBaseTable() );
try {
bindAttributes(
new AttributeMetadataContainer() {
@Override
public List<Object> getAttributeElements() {
return entitySourceInformation.getEntityElement().getPropertyOrManyToOneOrOneToOne();
}
},
entityBinding
);
}
finally {
attributeColumnTableStack.pop();
}
}
private void bindAttributes(AttributeMetadataContainer attributeMetadataContainer, EntityBinding entityBinding) {
for ( Object attribute : attributeMetadataContainer.getAttributeElements() ) {
if ( XMLPropertyElement.class.isInstance( attribute ) ) {
XMLPropertyElement property = XMLPropertyElement.class.cast( attribute );
bindProperty( property, entityBinding );
}
else if ( XMLManyToOneElement.class.isInstance( attribute ) ) {
XMLManyToOneElement manyToOne = XMLManyToOneElement.class.cast( attribute );
makeManyToOneAttributeBinding( manyToOne, entityBinding );
}
else if ( XMLOneToOneElement.class.isInstance( attribute ) ) {
// todo : implement
// value = new OneToOne( mappings, table, persistentClass );
// bindOneToOne( subElement, (OneToOne) value, propertyName, true, mappings );
}
else if ( XMLBagElement.class.isInstance( attribute ) ) {
XMLBagElement collection = XMLBagElement.class.cast( attribute );
BagBinding collectionBinding = makeBagAttributeBinding( collection, entityBinding );
metadata.addCollection( collectionBinding );
}
else if ( XMLIdbagElement.class.isInstance( attribute ) ) {
XMLIdbagElement collection = XMLIdbagElement.class.cast( attribute );
//BagBinding collectionBinding = entityBinding.makeBagAttributeBinding( collection.getName() );
//bindIdbag( collection, bagBinding, entityBinding, PluralAttributeNature.BAG, collection.getName() );
// todo: handle identifier
//attributeBinding = collectionBinding;
//hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding );
}
else if ( XMLSetElement.class.isInstance( attribute ) ) {
XMLSetElement collection = XMLSetElement.class.cast( attribute );
//BagBinding collectionBinding = entityBinding.makeBagAttributeBinding( collection.getName() );
//bindSet( collection, collectionBinding, entityBinding, PluralAttributeNature.SET, collection.getName() );
//attributeBinding = collectionBinding;
//hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding );
}
else if ( XMLListElement.class.isInstance( attribute ) ) {
XMLListElement collection = XMLListElement.class.cast( attribute );
//ListBinding collectionBinding = entityBinding.makeBagAttributeBinding( collection.getName() );
//bindList( collection, bagBinding, entityBinding, PluralAttributeNature.LIST, collection.getName() );
// todo : handle list index
//attributeBinding = collectionBinding;
//hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding );
}
else if ( XMLMapElement.class.isInstance( attribute ) ) {
XMLMapElement collection = XMLMapElement.class.cast( attribute );
//BagBinding bagBinding = entityBinding.makeBagAttributeBinding( collection.getName() );
//bindMap( collection, bagBinding, entityBinding, PluralAttributeNature.MAP, collection.getName() );
// todo : handle map key
//hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding );
}
else if ( XMLAnyElement.class.isInstance( attribute ) ) {
// todo : implement
// value = new Any( mappings, table );
// bindAny( subElement, (Any) value, nullable, mappings );
}
else if ( XMLComponentElement.class.isInstance( attribute )
|| XMLDynamicComponentElement.class.isInstance( attribute )
|| XMLPropertiesElement.class.isInstance( attribute ) ) {
// todo : implement
// String subpath = StringHelper.qualify( entityName, propertyName );
// value = new Component( mappings, persistentClass );
//
// bindComponent(
// subElement,
// (Component) value,
// persistentClass.getClassName(),
// propertyName,
// subpath,
// true,
// "properties".equals( subElementName ),
// mappings,
// inheritedMetas,
// false
// );
}
}
}
private void bindProperty(XMLPropertyElement property, EntityBinding entityBinding) {
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( property.getName() );
resolveTypeInformation( property, attributeBinding );
attributeBinding.setInsertable( Helper.getBooleanValue( property.isInsert(), true ) );
attributeBinding.setInsertable( Helper.getBooleanValue( property.isUpdate(), true ) );
attributeBinding.setGeneration( PropertyGeneration.parse( property.getGenerated() ) );
attributeBinding.setLazy( property.isLazy() );
attributeBinding.setIncludedInOptimisticLocking( property.isOptimisticLock() );
attributeBinding.setPropertyAccessorName(
Helper.getPropertyAccessorName(
property.getAccess(),
false,
currentBindingContext.getMappingDefaults().getPropertyAccessorName()
)
);
attributeBinding.setMetaAttributeContext(
Helper.extractMetaAttributeContext( property.getMeta(), entityBinding.getMetaAttributeContext() )
);
// todo : implement. Is this meant to indicate the natural-id?
// attributeBinding.setAlternateUniqueKey( ... );
attributeBinding.setValue( makeValue( property, attributeBinding ) );
}
private void resolveTypeInformation(XMLPropertyElement property, final SimpleAttributeBinding attributeBinding) {
final Class<?> attributeJavaType = determineJavaType( attributeBinding.getAttribute() );
if ( attributeJavaType != null ) {
( (AbstractAttributeContainer.SingularAttributeImpl) attributeBinding.getAttribute() ).resolveType(
currentBindingContext.makeJavaType( attributeJavaType.getName() )
);
}
// prefer type attribute over nested <type/> element
if ( property.getTypeAttribute() != null ) {
final String explicitTypeName = property.getTypeAttribute();
final TypeDef typeDef = currentBindingContext.getMetadataImplementor().getTypeDefinition( explicitTypeName );
if ( typeDef != null ) {
attributeBinding.getHibernateTypeDescriptor().setTypeName( typeDef.getTypeClass() );
attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( typeDef.getParameters() );
}
else {
attributeBinding.getHibernateTypeDescriptor().setTypeName( explicitTypeName );
}
}
else if ( property.getType() != null ) {
// todo : consider changing in-line type definitions to implicitly generate uniquely-named type-defs
attributeBinding.getHibernateTypeDescriptor().setTypeName( property.getType().getName() );
for ( XMLParamElement xmlParamElement : property.getType().getParam() ) {
attributeBinding.getHibernateTypeDescriptor().getTypeParameters().put(
xmlParamElement.getName(),
xmlParamElement.getValue()
);
}
}
else {
// see if we can reflect to determine the appropriate type
try {
final String attributeName = attributeBinding.getAttribute().getName();
final Class ownerClass = attributeBinding.getAttribute().getAttributeContainer().getClassReference();
BeanInfoHelper.visitBeanInfo(
ownerClass,
new BeanInfoHelper.BeanInfoDelegate() {
@Override
public void processBeanInfo(BeanInfo beanInfo) throws Exception {
for ( PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors() ) {
if ( propertyDescriptor.getName().equals( attributeName ) ) {
attributeBinding.getHibernateTypeDescriptor().setTypeName(
propertyDescriptor.getPropertyType().getName()
);
break;
}
}
}
}
);
}
catch ( Exception e ) {
// todo : log it?
}
}
}
private Class<?> determineJavaType(final Attribute attribute) {
try {
final Class ownerClass = attribute.getAttributeContainer().getClassReference();
AttributeJavaTypeDeterminerDelegate delegate = new AttributeJavaTypeDeterminerDelegate( attribute.getName() );
BeanInfoHelper.visitBeanInfo( ownerClass, delegate );
return delegate.javaType;
}
catch ( Exception e ) {
// todo : log it?
}
return null;
}
private static class AttributeJavaTypeDeterminerDelegate implements BeanInfoHelper.BeanInfoDelegate {
private final String attributeName;
private Class<?> javaType = null;
private AttributeJavaTypeDeterminerDelegate(String attributeName) {
this.attributeName = attributeName;
}
@Override
public void processBeanInfo(BeanInfo beanInfo) throws Exception {
for ( PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors() ) {
if ( propertyDescriptor.getName().equals( attributeName ) ) {
javaType = propertyDescriptor.getPropertyType();
break;
}
}
}
}
private org.hibernate.metamodel.relational.Value makeValue(
XMLPropertyElement property,
SimpleAttributeBinding attributeBinding) {
// todo : to be completely correct, we need to know which table the value belongs to.
// There is a note about this somewhere else with ideas on the subject.
// For now, just use the entity's base table.
final TableSpecification valueSource = attributeBinding.getEntityBinding().getBaseTable();
if ( property.getColumn() != null && ! property.getColumn().isEmpty() ) {
if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) {
throw new MappingException(
"column/formula attribute may not be used together with <column>/<formula> subelement",
currentBindingContext.getOrigin()
);
}
if ( property.getFormula() != null ) {
throw new MappingException(
"column and formula attributes may not be used together",
currentBindingContext.getOrigin()
);
}
return valueSource.locateOrCreateColumn( property.getColumn() );
}
else if ( property.getFormula() != null && ! property.getFormula().isEmpty() ) {
if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) {
throw new MappingException(
"column/formula attribute may not be used together with <column>/<formula> subelement",
currentBindingContext.getOrigin()
);
}
return valueSource.locateOrCreateDerivedValue( property.getFormula() );
}
else if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) {
List<SimpleValue> values = new ArrayList<SimpleValue>();
for ( Object columnOrFormula : property.getColumnOrFormula() ) {
final SimpleValue value;
if ( XMLColumnElement.class.isInstance( columnOrFormula ) ) {
final XMLColumnElement columnElement = (XMLColumnElement) columnOrFormula;
final Column column = valueSource.locateOrCreateColumn( columnElement.getName() );
column.setNullable( ! columnElement.isNotNull() );
column.setDefaultValue( columnElement.getDefault() );
column.setSqlType( columnElement.getSqlType() );
column.setSize(
new Size(
Helper.getIntValue( columnElement.getPrecision(), -1 ),
Helper.getIntValue( columnElement.getScale(), -1 ),
Helper.getLongValue( columnElement.getLength(), -1 ),
Size.LobMultiplier.NONE
)
);
column.setDatatype( null ); // todo : ???
column.setReadFragment( columnElement.getRead() );
column.setWriteFragment( columnElement.getWrite() );
column.setUnique( columnElement.isUnique() );
column.setCheckCondition( columnElement.getCheck() );
column.setComment( columnElement.getComment() );
value = column;
}
else {
// todo : ??? Seems jaxb is not generating this class ?!?!?!
// final XMLFormulaElement formulaElement = (XMLFormulaElement) columnOrFormula;
value = null;
}
if ( value != null ) {
values.add( value );
}
}
if ( values.size() == 1 ) {
return values.get( 0 );
}
final Tuple tuple = valueSource.createTuple(
attributeBinding.getEntityBinding().getEntity().getName() + '.'
+ attributeBinding.getAttribute().getName()
);
for ( SimpleValue value : values ) {
tuple.addValue( value );
}
return tuple;
}
else {
// assume a column named based on the NamingStrategy
final String name = metadata.getOptions()
.getNamingStrategy()
.propertyToColumnName( attributeBinding.getAttribute().getName() );
return valueSource.locateOrCreateColumn( name );
}
// // TODO: not sure I like this here...
// if ( isPrimaryKey() ) {
// if ( SimpleValue.class.isInstance( value ) ) {
// if ( !Column.class.isInstance( value ) ) {
// // this should never ever happen..
// throw new org.hibernate.MappingException( "Simple ID is not a column." );
// }
// entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( value ) );
// }
// else {
// for ( SimpleValueRelationalState val : TupleRelationalState.class.cast( state )
// .getRelationalStates() ) {
// if ( Column.class.isInstance( val ) ) {
// entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( val ) );
// }
// }
// }
// }
}
private void makeManyToOneAttributeBinding(XMLManyToOneElement manyToOne, EntityBinding entityBinding) {
//To change body of created methods use File | Settings | File Templates.
}
private BagBinding makeBagAttributeBinding(XMLBagElement collection, EntityBinding entityBinding) {
return null; //To change body of created methods use File | Settings | File Templates.
}
private void bindSecondaryTables(EntitySourceInformation entitySourceInfo, EntityBinding entityBinding) {
final EntityElement entityElement = entitySourceInfo.getEntityElement();
if ( ! ( entityElement instanceof JoinElementSource ) ) {
return;
}
for ( XMLJoinElement join : ( (JoinElementSource) entityElement ).getJoin() ) {
// todo : implement
// Join join = new Join();
// join.setPersistentClass( persistentClass );
// bindJoin( subElement, join, mappings, inheritedMetas );
// persistentClass.addJoin( join );
}
}
private void bindTableUniqueConstraints(EntityBinding entityBinding) {
//To change body of created methods use File | Settings | File Templates.
}
private static interface AttributeMetadataContainer {
public List<Object> getAttributeElements();
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.binder.source.hbm;
import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
/**
* Models the source view of an entity hierarchy.
*
* @author Steve Ebersole
*/
public class EntityHierarchy extends AbstractSubEntityContainer {
private final EntitySourceInformation entitySourceInformation;
private InheritanceType hierarchyInheritanceType = InheritanceType.NO_INHERITANCE;
public EntityHierarchy(XMLHibernateMapping.XMLClass rootEntity, MappingDocument sourceMappingDocument) {
this.entitySourceInformation = new EntitySourceInformation( rootEntity, sourceMappingDocument );
}
public EntitySourceInformation getEntitySourceInformation() {
return entitySourceInformation;
}
public InheritanceType getHierarchyInheritanceType() {
return hierarchyInheritanceType;
}
@Override
public void addSubEntityDescriptor(EntityHierarchySubEntity subEntityDescriptor) {
super.addSubEntityDescriptor( subEntityDescriptor );
// check inheritance type consistency
final InheritanceType inheritanceType = Helper.interpretInheritanceType(
subEntityDescriptor.getEntitySourceInformation().getEntityElement()
);
if ( this.hierarchyInheritanceType != InheritanceType.NO_INHERITANCE
&& this.hierarchyInheritanceType != inheritanceType ) {
// throw exception
}
this.hierarchyInheritanceType = inheritanceType;
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.binder.source.hbm;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement;
/**
* A sub entity within an entity hierarchy.
*
* @author Steve Ebersole
*/
public class EntityHierarchySubEntity extends AbstractSubEntityContainer {
private final EntitySourceInformation entitySourceInformation;
public EntityHierarchySubEntity(EntityElement entityElement, MappingDocument sourceMappingDocument) {
this.entitySourceInformation = new EntitySourceInformation( entityElement, sourceMappingDocument );
}
public EntitySourceInformation getEntitySourceInformation() {
return entitySourceInformation;
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.binder.source.hbm;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement;
/**
* An aggregation of information about the source of an entity mapping.
*
* @author Steve Ebersole
*/
public class EntitySourceInformation {
private final EntityElement entityElement;
private final MappingDocument sourceMappingDocument;
private final String mappedEntityName;
public EntitySourceInformation(EntityElement entityElement, MappingDocument sourceMappingDocument) {
this.entityElement = entityElement;
this.sourceMappingDocument = sourceMappingDocument;
this.mappedEntityName = sourceMappingDocument.getMappingLocalBindingContext().determineEntityName( entityElement );
}
public EntityElement getEntityElement() {
return entityElement;
}
public MappingDocument getSourceMappingDocument() {
return sourceMappingDocument;
}
public String getMappedEntityName() {
return mappedEntityName;
}
}

View File

@ -24,35 +24,24 @@
package org.hibernate.metamodel.binder.source.hbm;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.MappingException;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.binder.source.BindingContext;
import org.hibernate.metamodel.binder.source.MappingDefaults;
import org.hibernate.metamodel.binder.source.MetadataImplementor;
import org.hibernate.metamodel.binder.source.SourceProcessor;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement;
import org.hibernate.metamodel.binder.source.internal.JaxbRoot;
import org.hibernate.metamodel.domain.JavaType;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
import org.hibernate.service.ServiceRegistry;
/**
* The {@link SourceProcessor} implementation responsible for processing {@code hbm.xml} sources.
*
* @author Steve Ebersole
*/
public class HbmSourceProcessorImpl implements SourceProcessor, BindingContext {
public class HbmSourceProcessorImpl implements SourceProcessor {
private final MetadataImplementor metadata;
private List<HibernateMappingProcessor> processors;
private List<HibernateMappingProcessor> processors = new ArrayList<HibernateMappingProcessor>();
private List<EntityHierarchy> entityHierarchies;
public HbmSourceProcessorImpl(MetadataImplementor metadata) {
this.metadata = metadata;
@ -61,12 +50,20 @@ public class HbmSourceProcessorImpl implements SourceProcessor, BindingContext {
@Override
@SuppressWarnings( {"unchecked"})
public void prepare(MetadataSources sources) {
this.processors = new ArrayList<HibernateMappingProcessor>();
final HierarchyBuilder hierarchyBuilder = new HierarchyBuilder( metadata );
for ( JaxbRoot jaxbRoot : sources.getJaxbRootList() ) {
if ( jaxbRoot.getRoot() instanceof XMLHibernateMapping ) {
processors.add( new HibernateMappingProcessor( this, (JaxbRoot<XMLHibernateMapping>) jaxbRoot ) );
if ( ! XMLHibernateMapping.class.isInstance( jaxbRoot.getRoot() ) ) {
continue;
}
final MappingDocument mappingDocument = new MappingDocument( jaxbRoot, metadata );
processors.add( new HibernateMappingProcessor( metadata, mappingDocument ) );
hierarchyBuilder.processMappingDocument( mappingDocument );
}
this.entityHierarchies = hierarchyBuilder.groupEntityHierarchies();
}
@Override
@ -85,93 +82,9 @@ public class HbmSourceProcessorImpl implements SourceProcessor, BindingContext {
@Override
public void processMappingMetadata(MetadataSources sources, List<String> processedEntityNames) {
// Lets get the entities (the mapping processors really) into a better order for processing based on
// inheritance hierarchy to avoid the need for an "extends queue". Really, correctly speaking, we are
// localizing the "extends queue" to just this method stack.
// 'orderedProcessors' represents the processors we know are not waiting on any super-types in the entity
// hierarchy to be found. 'extendsQueue', conversely, holds processors (and other information) relating
// we know have to wait on at least one of the super-types in their entity hierarchy to be found.
final LinkedHashSet<HibernateMappingProcessor> orderedProcessors = new LinkedHashSet<HibernateMappingProcessor>();
final Set<ExtendsQueueEntry> extendsQueue = new HashSet<ExtendsQueueEntry>();
// 'availableEntityNames' holds all of the available entity names. This means the incoming set of
// 'processedEntityNames' as well as any entity-names found here as they are added to 'orderedProcessors'
final Set<String> availableEntityNames = new HashSet<String>();
availableEntityNames.addAll( processedEntityNames );
// this loop is essentially splitting processors into those that can be processed immediately and those that
// have to wait on entities not yet seen. Those that have to wait go in the extendsQueue. Those that can be
// processed immediately go into 'orderedProcessors'.
for ( HibernateMappingProcessor processor : processors ) {
final HibernateMappingInformation hibernateMappingInformation = new HibernateMappingInformation( processor );
ExtendsQueueEntry extendsQueueEntry = null;
for ( Object entityElementO : processor.getHibernateMapping().getClazzOrSubclassOrJoinedSubclass() ) {
final EntityElement entityElement = (EntityElement) entityElementO;
final String entityName = processor.determineEntityName( entityElement );
hibernateMappingInformation.includedEntityNames.add( entityName );
if ( SubclassEntityElement.class.isInstance( entityElement ) ) {
final String entityItExtends = ( (SubclassEntityElement) entityElement ).getExtends();
if ( ! availableEntityNames.contains( entityItExtends ) ) {
if ( extendsQueueEntry == null ) {
extendsQueueEntry = new ExtendsQueueEntry( hibernateMappingInformation );
extendsQueue.add( extendsQueueEntry );
}
extendsQueueEntry.waitingOnEntityNames.add( entityItExtends );
}
}
}
if ( extendsQueueEntry == null ) {
// we found no extends names that we have to wait on
orderedProcessors.add( processor );
availableEntityNames.addAll( hibernateMappingInformation.includedEntityNames );
}
}
// This loop tries to move entries from 'extendsQueue' into 'orderedProcessors', stopping when we cannot
// process any more or they have all been processed.
while ( ! extendsQueue.isEmpty() ) {
// set up a pass over the queue
int numberOfMappingsProcessed = 0;
Iterator<ExtendsQueueEntry> iterator = extendsQueue.iterator();
while ( iterator.hasNext() ) {
final ExtendsQueueEntry entry = iterator.next();
if ( availableEntityNames.containsAll( entry.waitingOnEntityNames ) ) {
// all the entity names this entry was waiting on have been made available
iterator.remove();
orderedProcessors.add( entry.hibernateMappingInformation.processor );
availableEntityNames.addAll( entry.hibernateMappingInformation.includedEntityNames );
numberOfMappingsProcessed++;
}
}
if ( numberOfMappingsProcessed == 0 ) {
// todo : we could log the waiting dependencies...
throw new MappingException( "Unable to process extends dependencies in hbm files" );
}
}
// This loop executes the processors.
for ( HibernateMappingProcessor processor : orderedProcessors ) {
processor.processMappingMetadata( processedEntityNames );
}
}
private static class HibernateMappingInformation {
private final HibernateMappingProcessor processor;
private final Set<String> includedEntityNames = new HashSet<String>();
private HibernateMappingInformation(HibernateMappingProcessor processor) {
this.processor = processor;
}
}
private static class ExtendsQueueEntry {
private HibernateMappingInformation hibernateMappingInformation;
private final Set<String> waitingOnEntityNames = new HashSet<String>();
private ExtendsQueueEntry(HibernateMappingInformation hibernateMappingInformation) {
this.hibernateMappingInformation = hibernateMappingInformation;
BindingCreator bindingCreator = new BindingCreator( metadata, processedEntityNames );
for ( EntityHierarchy entityHierarchy : entityHierarchies ) {
bindingCreator.processEntityHierarchy( entityHierarchy );
}
}
@ -181,39 +94,4 @@ public class HbmSourceProcessorImpl implements SourceProcessor, BindingContext {
processor.processMappingDependentMetadata();
}
}
@Override
public ServiceRegistry getServiceRegistry() {
return metadata.getServiceRegistry();
}
@Override
public NamingStrategy getNamingStrategy() {
return metadata.getNamingStrategy();
}
@Override
public MappingDefaults getMappingDefaults() {
return metadata.getMappingDefaults();
}
@Override
public MetadataImplementor getMetadataImplementor() {
return metadata;
}
@Override
public <T> Class<T> locateClassByName(String name) {
return metadata.locateClassByName( name );
}
@Override
public JavaType makeJavaType(String className) {
return metadata.makeJavaType( className );
}
@Override
public Value<Class<?>> makeClassReference(String className) {
return metadata.makeClassReference( className );
}
}

View File

@ -35,8 +35,12 @@ import org.hibernate.metamodel.binder.source.MetaAttributeContext;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.CustomSqlElement;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement;
import org.hibernate.metamodel.binding.CustomSQL;
import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.binding.MetaAttribute;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinedSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLMetaElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLUnionSubclassElement;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.classloading.spi.ClassLoadingException;
@ -46,6 +50,20 @@ import org.hibernate.service.classloading.spi.ClassLoadingException;
* @author Gail Badner
*/
public class Helper {
public static InheritanceType interpretInheritanceType(EntityElement entityElement) {
if ( XMLSubclassElement.class.isInstance( entityElement ) ) {
return InheritanceType.SINGLE_TABLE;
}
else if ( XMLJoinedSubclassElement.class.isInstance( entityElement ) ) {
return InheritanceType.JOINED;
}
else if ( XMLUnionSubclassElement.class.isInstance( entityElement ) ) {
return InheritanceType.TABLE_PER_CLASS;
}
else {
return InheritanceType.NO_INHERITANCE;
}
}
/**
* Given a user-specified description of how to perform custom SQL, build the {@link CustomSQL} representation.
@ -140,6 +158,10 @@ public class Helper {
return value == null ? defaultValue : Integer.parseInt( value );
}
public static long getLongValue(String value, long defaultValue) {
return value == null ? defaultValue : Long.parseLong( value );
}
public static boolean getBooleanValue(String value, boolean defaultValue) {
return value == null ? defaultValue : Boolean.valueOf( value );
}

View File

@ -29,22 +29,14 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.binder.MappingException;
import org.hibernate.metamodel.binder.Origin;
import org.hibernate.metamodel.binder.source.MappingDefaults;
import org.hibernate.metamodel.binder.source.MetaAttributeContext;
import org.hibernate.metamodel.binder.source.MetadataImplementor;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement;
import org.hibernate.metamodel.binder.source.internal.JaxbRoot;
import org.hibernate.metamodel.binder.source.internal.OverriddenMappingDefaults;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.domain.JavaType;
import org.hibernate.metamodel.relational.AuxiliaryDatabaseObject;
import org.hibernate.metamodel.relational.BasicAuxiliaryDatabaseObjectImpl;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLFetchProfileElement;
@ -67,106 +59,38 @@ import org.hibernate.type.Type;
*
* @author Steve Ebersole
*/
public class HibernateMappingProcessor implements HbmBindingContext {
private final HbmSourceProcessorImpl hbmHandler;
private final JaxbRoot<XMLHibernateMapping> jaxbRoot;
public class HibernateMappingProcessor {
private final MetadataImplementor metadata;
private final MappingDocument mappingDocument;
private final XMLHibernateMapping hibernateMapping;
private final MappingDefaults mappingDefaults;
private final MetaAttributeContext metaAttributeContext;
private final boolean autoImport;
public HibernateMappingProcessor(HbmSourceProcessorImpl hbmHandler, JaxbRoot<XMLHibernateMapping> jaxbRoot) {
this.hbmHandler = hbmHandler;
this.jaxbRoot = jaxbRoot;
this.hibernateMapping = jaxbRoot.getRoot();
this.mappingDefaults = new OverriddenMappingDefaults(
hbmHandler.getMappingDefaults(),
hibernateMapping.getPackage(),
hibernateMapping.getSchema(),
hibernateMapping.getCatalog(),
null, // idColumnName
null, // discriminatorColumnName
hibernateMapping.getDefaultCascade(),
hibernateMapping.getDefaultAccess(),
hibernateMapping.isDefaultLazy()
private Value<ClassLoaderService> classLoaderService = new Value<ClassLoaderService>(
new Value.DeferredInitializer<ClassLoaderService>() {
@Override
public ClassLoaderService initialize() {
return metadata.getServiceRegistry().getService( ClassLoaderService.class );
}
}
);
this.autoImport = hibernateMapping.isAutoImport();
this.metaAttributeContext = extractMetaAttributes();
public HibernateMappingProcessor(MetadataImplementor metadata, MappingDocument mappingDocument) {
this.metadata = metadata;
this.mappingDocument = mappingDocument;
}
private MetaAttributeContext extractMetaAttributes() {
return hibernateMapping.getMeta() == null
? new MetaAttributeContext( hbmHandler.getMetadataImplementor().getGlobalMetaAttributeContext() )
: Helper.extractMetaAttributeContext(
hibernateMapping.getMeta(),
true,
hbmHandler.getMetadataImplementor()
.getGlobalMetaAttributeContext()
);
private XMLHibernateMapping mappingRoot() {
return mappingDocument.getMappingRoot();
}
XMLHibernateMapping getHibernateMapping() {
return hibernateMapping;
private Origin origin() {
return mappingDocument.getOrigin();
}
@Override
public boolean isAutoImport() {
return autoImport;
private HbmBindingContext bindingContext() {
return mappingDocument.getMappingLocalBindingContext();
}
@Override
public Origin getOrigin() {
return jaxbRoot.getOrigin();
}
@Override
public ServiceRegistry getServiceRegistry() {
return getMetadataImplementor().getServiceRegistry();
}
@Override
public NamingStrategy getNamingStrategy() {
return getMetadataImplementor().getOptions().getNamingStrategy();
}
@Override
public boolean isGloballyQuotedIdentifiers() {
return getMetadataImplementor().isGloballyQuotedIdentifiers();
}
@Override
public MappingDefaults getMappingDefaults() {
return mappingDefaults;
}
@Override
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
}
@Override
public MetadataImplementor getMetadataImplementor() {
return hbmHandler.getMetadataImplementor();
}
@Override
public <T> Class<T> locateClassByName(String name) {
return getMetadataImplementor().locateClassByName( name );
}
@Override
public JavaType makeJavaType(String className) {
return getMetadataImplementor().makeJavaType( className );
}
@Override
public Value<Class<?>> makeClassReference(String className) {
return getMetadataImplementor().makeClassReference( className );
private <T> Class<T> classForName(String name) {
return classLoaderService.getValue().classForName( bindingContext().qualifyClassName( name ) );
}
public void processIndependentMetadata() {
@ -175,15 +99,16 @@ public class HibernateMappingProcessor implements HbmBindingContext {
}
private void processDatabaseObjectDefinitions() {
if ( hibernateMapping.getDatabaseObject() == null ) {
if ( mappingRoot().getDatabaseObject() == null ) {
return;
}
for ( XMLHibernateMapping.XMLDatabaseObject databaseObjectElement : hibernateMapping.getDatabaseObject() ) {
for ( XMLHibernateMapping.XMLDatabaseObject databaseObjectElement : mappingRoot().getDatabaseObject() ) {
final AuxiliaryDatabaseObject auxiliaryDatabaseObject;
if ( databaseObjectElement.getDefinition() != null ) {
final String className = databaseObjectElement.getDefinition().getClazz();
try {
auxiliaryDatabaseObject = (AuxiliaryDatabaseObject) classLoaderService.getValue().classForName( className ).newInstance();
auxiliaryDatabaseObject = (AuxiliaryDatabaseObject) classForName( className ).newInstance();
}
catch (ClassLoadingException e) {
throw e;
@ -191,7 +116,7 @@ public class HibernateMappingProcessor implements HbmBindingContext {
catch (Exception e) {
throw new MappingException(
"could not instantiate custom database object class [" + className + "]",
jaxbRoot.getOrigin()
origin()
);
}
}
@ -208,20 +133,21 @@ public class HibernateMappingProcessor implements HbmBindingContext {
dialectScopes
);
}
getMetadataImplementor().addAuxiliaryDatabaseObject( auxiliaryDatabaseObject );
metadata.addAuxiliaryDatabaseObject( auxiliaryDatabaseObject );
}
}
private void processTypeDefinitions() {
if ( hibernateMapping.getTypedef() == null ) {
if ( mappingRoot().getTypedef() == null ) {
return;
}
for ( XMLHibernateMapping.XMLTypedef typedef : hibernateMapping.getTypedef() ) {
for ( XMLHibernateMapping.XMLTypedef typedef : mappingRoot().getTypedef() ) {
final Map<String, String> parameters = new HashMap<String, String>();
for ( XMLParamElement paramElement : typedef.getParam() ) {
parameters.put( paramElement.getName(), paramElement.getValue() );
}
getMetadataImplementor().addTypeDefinition(
metadata.addTypeDefinition(
new TypeDef(
typedef.getName(),
typedef.getClazz(),
@ -237,10 +163,11 @@ public class HibernateMappingProcessor implements HbmBindingContext {
}
private void processFilterDefinitions() {
if(hibernateMapping.getFilterDef() == null){
if ( mappingRoot().getFilterDef() == null ) {
return;
}
for ( XMLHibernateMapping.XMLFilterDef filterDefinition : hibernateMapping.getFilterDef() ) {
for ( XMLHibernateMapping.XMLFilterDef filterDefinition : mappingRoot().getFilterDef() ) {
final String name = filterDefinition.getName();
final Map<String,Type> parameters = new HashMap<String, Type>();
String condition = null;
@ -257,45 +184,33 @@ public class HibernateMappingProcessor implements HbmBindingContext {
// todo : should really delay this resolution until later to allow typedef names
parameters.put(
paramElement.getName(),
getMetadataImplementor().getTypeResolver().heuristicType( paramElement.getType() )
metadata.getTypeResolver().heuristicType( paramElement.getType() )
);
}
else {
throw new MappingException( "Unrecognized nested filter content", jaxbRoot.getOrigin() );
throw new MappingException( "Unrecognized nested filter content", origin() );
}
}
if ( condition == null ) {
condition = filterDefinition.getCondition();
}
getMetadataImplementor().addFilterDefinition( new FilterDefinition( name, condition, parameters ) );
metadata.addFilterDefinition( new FilterDefinition( name, condition, parameters ) );
}
}
private void processIdentifierGenerators() {
if ( hibernateMapping.getIdentifierGenerator() == null ) {
if ( mappingRoot().getIdentifierGenerator() == null ) {
return;
}
for ( XMLHibernateMapping.XMLIdentifierGenerator identifierGeneratorElement : hibernateMapping.getIdentifierGenerator() ) {
getMetadataImplementor().registerIdentifierGenerator(
for ( XMLHibernateMapping.XMLIdentifierGenerator identifierGeneratorElement : mappingRoot().getIdentifierGenerator() ) {
metadata.registerIdentifierGenerator(
identifierGeneratorElement.getName(),
identifierGeneratorElement.getClazz()
);
}
}
public void processMappingMetadata(List<String> processedEntityNames) {
if ( hibernateMapping.getClazzOrSubclassOrJoinedSubclass() == null ) {
return;
}
final BindingCreator bindingCreator = new BindingCreator( this, processedEntityNames );
for ( Object entityElementO : hibernateMapping.getClazzOrSubclassOrJoinedSubclass() ) {
final EntityElement entityElement = (EntityElement) entityElementO;
bindingCreator.createEntityBinding( entityElement, null );
}
}
public void processMappingDependentMetadata() {
processFetchProfiles();
processImports();
@ -304,10 +219,11 @@ public class HibernateMappingProcessor implements HbmBindingContext {
}
private void processFetchProfiles(){
if ( hibernateMapping.getFetchProfile() == null ) {
if ( mappingRoot().getFetchProfile() == null ) {
return;
}
processFetchProfiles( hibernateMapping.getFetchProfile(), null );
processFetchProfiles( mappingRoot().getFetchProfile(), null );
}
public void processFetchProfiles(List<XMLFetchProfileElement> fetchProfiles, String containingEntityName) {
@ -320,39 +236,42 @@ public class HibernateMappingProcessor implements HbmBindingContext {
throw new MappingException(
"could not determine entity for fetch-profile fetch [" + profileName + "]:[" +
fetch.getAssociation() + "]",
jaxbRoot.getOrigin()
origin()
);
}
fetches.add( new FetchProfile.Fetch( entityName, fetch.getAssociation(), fetch.getStyle() ) );
}
getMetadataImplementor().addFetchProfile( new FetchProfile( profileName, fetches ) );
metadata.addFetchProfile( new FetchProfile( profileName, fetches ) );
}
}
private void processImports() {
if ( hibernateMapping.getImport() == null ) {
if ( mappingRoot().getImport() == null ) {
return;
}
for ( XMLHibernateMapping.XMLImport importValue : hibernateMapping.getImport() ) {
String className = qualifyClassName( importValue.getClazz() );
for ( XMLHibernateMapping.XMLImport importValue : mappingRoot().getImport() ) {
String className = mappingDocument.getMappingLocalBindingContext().qualifyClassName( importValue.getClazz() );
String rename = importValue.getRename();
rename = ( rename == null ) ? StringHelper.unqualify( className ) : rename;
getMetadataImplementor().addImport( className, rename );
metadata.addImport( className, rename );
}
}
private void processResultSetMappings() {
if ( hibernateMapping.getResultset() == null ) {
if ( mappingRoot().getResultset() == null ) {
return;
}
// bindResultSetMappingDefinitions( element, null, mappings );
}
private void processNamedQueries() {
if ( hibernateMapping.getQueryOrSqlQuery() == null ) {
if ( mappingRoot().getQueryOrSqlQuery() == null ) {
return;
}
for ( Object queryOrSqlQuery : hibernateMapping.getQueryOrSqlQuery() ) {
for ( Object queryOrSqlQuery : mappingRoot().getQueryOrSqlQuery() ) {
if ( XMLQueryElement.class.isInstance( queryOrSqlQuery ) ) {
// bindNamedQuery( element, null, mappings );
}
@ -362,28 +281,9 @@ public class HibernateMappingProcessor implements HbmBindingContext {
else {
throw new MappingException(
"unknown type of query: " +
queryOrSqlQuery.getClass().getName(), jaxbRoot.getOrigin()
queryOrSqlQuery.getClass().getName(), origin()
);
}
}
}
private Value<ClassLoaderService> classLoaderService = new Value<ClassLoaderService>(
new Value.DeferredInitializer<ClassLoaderService>() {
@Override
public ClassLoaderService initialize() {
return getMetadataImplementor().getServiceRegistry().getService( ClassLoaderService.class );
}
}
);
@Override
public String qualifyClassName(String unqualifiedName) {
return Helper.qualifyIfNeeded( unqualifiedName, mappingDefaults.getPackageName() );
}
@Override
public String determineEntityName(EntityElement entityElement) {
return Helper.determineEntityName( entityElement, mappingDefaults.getPackageName() );
}
}

View File

@ -0,0 +1,175 @@
/*
* 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.binder.source.hbm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.hibernate.MappingException;
import org.hibernate.metamodel.binder.source.MetadataImplementor;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinedSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLUnionSubclassElement;
/**
* @author Steve Ebersole
*/
public class HierarchyBuilder {
private final MetadataImplementor metadata;
private final List<EntityHierarchy> entityHierarchies = new ArrayList<EntityHierarchy>();
// process state
private final Map<String,SubEntityContainer> subEntityContainerMap = new HashMap<String, SubEntityContainer>();
private final List<ExtendsQueueEntry> extendsQueue = new ArrayList<ExtendsQueueEntry>();
// mapping file specific state
private MappingDocument currentMappingDocument;
public HierarchyBuilder(MetadataImplementor metadata) {
this.metadata = metadata;
}
public void processMappingDocument(MappingDocument mappingDocument) {
this.currentMappingDocument = mappingDocument;
try {
processCurrentMappingDocument();
}
finally {
this.currentMappingDocument = null;
}
}
private void processCurrentMappingDocument() {
for ( Object entityElementO : currentMappingDocument.getMappingRoot().getClazzOrSubclassOrJoinedSubclass() ) {
final EntityElement entityElement = (EntityElement) entityElementO;
if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) {
// we can immediately handle <class/> elements in terms of creating the hierarchy entry
final XMLHibernateMapping.XMLClass xmlClass = (XMLHibernateMapping.XMLClass) entityElement;
final EntityHierarchy hierarchy = new EntityHierarchy( xmlClass, currentMappingDocument );
entityHierarchies.add( hierarchy );
subEntityContainerMap.put( hierarchy.getEntitySourceInformation().getMappedEntityName(), hierarchy );
processSubElements( entityElement, hierarchy );
}
else {
// we have to see if this things super-type has been found yet, and if not add it to the
// extends queue
final EntityHierarchySubEntity subEntityDescriptor = new EntityHierarchySubEntity(
entityElement,
currentMappingDocument
);
final String entityName = subEntityDescriptor.getEntitySourceInformation().getMappedEntityName();
subEntityContainerMap.put( entityName, subEntityDescriptor );
final String entityItExtends = currentMappingDocument.getMappingLocalBindingContext().qualifyClassName(
((SubEntityElement) entityElement).getExtends()
);
processSubElements( entityElement, subEntityDescriptor );
final SubEntityContainer container = subEntityContainerMap.get( entityItExtends );
if ( container != null ) {
// we already have this entity's super, attach it and continue
container.addSubEntityDescriptor( subEntityDescriptor );
}
else {
// we do not yet have the super and have to wait, so add it fto the extends queue
extendsQueue.add( new ExtendsQueueEntry( subEntityDescriptor, entityItExtends ) );
}
}
}
}
public List<EntityHierarchy> groupEntityHierarchies() {
while ( ! extendsQueue.isEmpty() ) {
// set up a pass over the queue
int numberOfMappingsProcessed = 0;
Iterator<ExtendsQueueEntry> iterator = extendsQueue.iterator();
while ( iterator.hasNext() ) {
final ExtendsQueueEntry entry = iterator.next();
final SubEntityContainer container = subEntityContainerMap.get( entry.entityItExtends );
if ( container != null ) {
// we now have this entity's super, attach it and remove entry from extends queue
container.addSubEntityDescriptor( entry.subEntityDescriptor );
iterator.remove();
numberOfMappingsProcessed++;
}
}
if ( numberOfMappingsProcessed == 0 ) {
// todo : we could log the waiting dependencies...
throw new MappingException( "Unable to process extends dependencies in hbm files" );
}
}
return entityHierarchies;
}
private void processSubElements(EntityElement entityElement, SubEntityContainer container) {
if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) {
final XMLHibernateMapping.XMLClass xmlClass = (XMLHibernateMapping.XMLClass) entityElement;
processElements( xmlClass.getJoinedSubclass(), container );
processElements( xmlClass.getSubclass(), container );
processElements( xmlClass.getUnionSubclass(), container );
}
else if ( XMLSubclassElement.class.isInstance( entityElement ) ) {
final XMLSubclassElement xmlSubclass = (XMLSubclassElement) entityElement;
processElements( xmlSubclass.getSubclass(), container );
}
else if ( XMLJoinedSubclassElement.class.isInstance( entityElement ) ) {
final XMLJoinedSubclassElement xmlJoinedSubclass = (XMLJoinedSubclassElement) entityElement;
processElements( xmlJoinedSubclass.getJoinedSubclass(), container );
}
else if ( XMLUnionSubclassElement.class.isInstance( entityElement ) ) {
final XMLUnionSubclassElement xmlUnionSubclass = (XMLUnionSubclassElement) entityElement;
processElements( xmlUnionSubclass.getUnionSubclass(), container );
}
}
private void processElements(List subElements, SubEntityContainer container) {
for ( Object subElementO : subElements ) {
final SubEntityElement subElement = (SubEntityElement) subElementO;
final EntityHierarchySubEntity subEntityDescriptor = new EntityHierarchySubEntity(
subElement,
currentMappingDocument
);
container.addSubEntityDescriptor( subEntityDescriptor );
final String subEntityName = subEntityDescriptor.getEntitySourceInformation().getMappedEntityName();
subEntityContainerMap.put( subEntityName, subEntityDescriptor );
}
}
private static class ExtendsQueueEntry {
private final EntityHierarchySubEntity subEntityDescriptor;
private final String entityItExtends;
private ExtendsQueueEntry(EntityHierarchySubEntity subEntityDescriptor, String entityItExtends) {
this.subEntityDescriptor = subEntityDescriptor;
this.entityItExtends = entityItExtends;
}
}
}

View File

@ -0,0 +1,154 @@
/*
* 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.binder.source.hbm;
import java.util.List;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.binder.Origin;
import org.hibernate.metamodel.binder.source.MappingDefaults;
import org.hibernate.metamodel.binder.source.MetaAttributeContext;
import org.hibernate.metamodel.binder.source.MetadataImplementor;
import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement;
import org.hibernate.metamodel.binder.source.internal.JaxbRoot;
import org.hibernate.metamodel.domain.Type;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
import org.hibernate.service.ServiceRegistry;
/**
* Aggregates together information about a mapping document.
*
* @author Steve Ebersole
*/
public class MappingDocument {
private final JaxbRoot<XMLHibernateMapping> hbmJaxbRoot;
private final LocalBindingContextImpl mappingLocalBindingContext;
public MappingDocument(JaxbRoot<XMLHibernateMapping> hbmJaxbRoot, MetadataImplementor metadata) {
this.hbmJaxbRoot = hbmJaxbRoot;
this.mappingLocalBindingContext = new LocalBindingContextImpl( metadata );
}
public XMLHibernateMapping getMappingRoot() {
return hbmJaxbRoot.getRoot();
}
public Origin getOrigin() {
return hbmJaxbRoot.getOrigin();
}
public JaxbRoot<XMLHibernateMapping> getJaxbRoot() {
return hbmJaxbRoot;
}
public HbmBindingContext getMappingLocalBindingContext() {
return mappingLocalBindingContext;
}
private class LocalBindingContextImpl implements HbmBindingContext {
private final MetadataImplementor metadata;
private final MetaAttributeContext metaAttributeContext;
private LocalBindingContextImpl(MetadataImplementor metadata) {
this.metadata = metadata;
if ( hbmJaxbRoot.getRoot().getMeta() == null || hbmJaxbRoot.getRoot().getMeta().isEmpty() ) {
this.metaAttributeContext = new MetaAttributeContext( metadata.getGlobalMetaAttributeContext() );
}
else {
this.metaAttributeContext = Helper.extractMetaAttributeContext(
hbmJaxbRoot.getRoot().getMeta(),
true,
metadata.getGlobalMetaAttributeContext()
);
}
}
@Override
public ServiceRegistry getServiceRegistry() {
return metadata.getServiceRegistry();
}
@Override
public NamingStrategy getNamingStrategy() {
return metadata.getNamingStrategy();
}
@Override
public MappingDefaults getMappingDefaults() {
return metadata.getMappingDefaults();
}
@Override
public MetadataImplementor getMetadataImplementor() {
return metadata;
}
@Override
public <T> Class<T> locateClassByName(String name) {
return metadata.locateClassByName( name );
}
@Override
public Type makeJavaType(String className) {
return metadata.makeJavaType( className );
}
@Override
public Value<Class<?>> makeClassReference(String className) {
return metadata.makeClassReference( className );
}
@Override
public boolean isAutoImport() {
return hbmJaxbRoot.getRoot().isAutoImport();
}
@Override
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
}
@Override
public Origin getOrigin() {
return hbmJaxbRoot.getOrigin();
}
@Override
public String qualifyClassName(String unqualifiedName) {
return Helper.qualifyIfNeeded( unqualifiedName, getMappingDefaults().getPackageName() );
}
@Override
public String determineEntityName(EntityElement entityElement) {
return Helper.determineEntityName( entityElement, getMappingDefaults().getPackageName() );
}
@Override
public void processFetchProfiles(List<XMLFetchProfileElement> fetchProfiles, String containingEntityName) {
// todo : this really needs to not be part of the context
}
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.binder.source.hbm;
/**
* Contract for elements within a {@link EntityHierarchy} which can contain sub elements. Essentially this
* abstracts that common aspect away from both root and sub entities.
*
* @author Steve Ebersole
*/
public interface SubEntityContainer {
public void addSubEntityDescriptor(EntityHierarchySubEntity subEntityDescriptor);
public Iterable<EntityHierarchySubEntity> subEntityDescriptors();
}

View File

@ -26,6 +26,7 @@ package org.hibernate.metamodel.binder.source.hbm.xml.mapping;
import java.util.List;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLLoaderElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLResultsetElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlDeleteElement;
@ -64,4 +65,6 @@ public interface EntityElement extends MetaAttributeContainer {
public List<XMLResultsetElement> getResultset();
public List<Object> getQueryOrSqlQuery();
public List<Object> getPropertyOrManyToOneOrOneToOne();
}

View File

@ -0,0 +1,35 @@
/*
* 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.binder.source.hbm.xml.mapping;
import java.util.List;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinElement;
/**
* @author Steve Ebersole
*/
public interface JoinElementSource {
public List<XMLJoinElement> getJoin();
}

View File

@ -26,6 +26,6 @@ package org.hibernate.metamodel.binder.source.hbm.xml.mapping;
/**
* @author Steve Ebersole
*/
public interface SubclassEntityElement extends EntityElement {
public interface SubEntityElement extends EntityElement {
public String getExtends();
}

View File

@ -52,6 +52,7 @@ import org.hibernate.metamodel.binder.source.MappingDefaults;
import org.hibernate.metamodel.binder.source.MetaAttributeContext;
import org.hibernate.metamodel.binder.source.MetadataImplementor;
import org.hibernate.metamodel.binder.source.SourceProcessor;
import org.hibernate.metamodel.binder.source.annotations.AnnotationsSourceProcessor;
import org.hibernate.metamodel.binder.source.hbm.HbmSourceProcessorImpl;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
@ -59,13 +60,12 @@ import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.domain.JavaType;
import org.hibernate.metamodel.domain.BasicType;
import org.hibernate.metamodel.domain.Type;
import org.hibernate.metamodel.relational.Database;
import org.hibernate.metamodel.binder.source.annotations.AnnotationsSourceProcessor;
import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.type.Type;
import org.hibernate.type.TypeResolver;
/**
@ -311,7 +311,8 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
return typeDefs.values();
}
public TypeDef getTypeDef(String name) {
@Override
public TypeDef getTypeDefinition(String name) {
return typeDefs.get( name );
}
@ -345,8 +346,9 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
}
@Override
public JavaType makeJavaType(String className) {
return new JavaType( className, classLoaderService() );
public Type makeJavaType(String className) {
// todo : have this perform some analysis of the incoming type name to determine appropriate return
return new BasicType( className, makeClassReference( className ) );
}
@Override
@ -493,7 +495,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
}
@Override
public Type getIdentifierType(String entityName) throws MappingException {
public org.hibernate.type.Type getIdentifierType(String entityName) throws MappingException {
EntityBinding entityBinding = getEntityBinding( entityName );
if ( entityBinding == null ) {
throw new MappingException( "Entity binding not known: " + entityName );
@ -516,7 +518,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
}
@Override
public Type getReferencedPropertyType(String entityName, String propertyName) throws MappingException {
public org.hibernate.type.Type getReferencedPropertyType(String entityName, String propertyName) throws MappingException {
EntityBinding entityBinding = getEntityBinding( entityName );
if ( entityBinding == null ) {
throw new MappingException( "Entity binding not known: " + entityName );

View File

@ -44,13 +44,14 @@ import org.hibernate.metamodel.relational.state.ValueCreator;
import org.hibernate.metamodel.relational.state.ValueRelationalState;
/**
* TODO : javadoc
* Basic support for {@link AttributeBinding} implementors
*
* @author Steve Ebersole
*/
public abstract class AbstractAttributeBinding implements AttributeBinding {
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private final EntityBinding entityBinding;
private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor();
private final Set<EntityReferencingAttributeBinding> entityReferencingAttributeBindings = new HashSet<EntityReferencingAttributeBinding>();
private Attribute attribute;
@ -62,9 +63,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
private Set<CascadeType> cascadeTypes;
private boolean optimisticLockable;
// DOM4J specific...
private String nodeName;
private MetaAttributeContext metaAttributeContext;
protected AbstractAttributeBinding(EntityBinding entityBinding) {
@ -79,7 +77,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
isAlternateUniqueKey = state.isAlternateUniqueKey();
cascadeTypes = state.getCascadeTypes();
optimisticLockable = state.isOptimisticLockable();
nodeName = state.getNodeName();
metaAttributeContext = state.getMetaAttributeContext();
}
@ -97,6 +94,10 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
this.attribute = attribute;
}
public void setValue(Value value) {
this.value = value;
}
protected boolean forceNonNullable() {
return false;
}
@ -156,10 +157,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
return optimisticLockable;
}
public String getNodeName() {
return nodeName;
}
@Override
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
@ -256,7 +253,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
return isLazy;
}
protected void setLazy(boolean isLazy) {
public void setLazy(boolean isLazy) {
this.isLazy = isLazy;
}

View File

@ -58,7 +58,10 @@ public interface AttributeBinding {
public Value getValue();
/**
* Obtain the descriptor for the Hibernate Type for this binding.
* Obtain the descriptor for the Hibernate {@link org.hibernate.type.Type} for this binding.
* <p/>
* For information about the Java type, query the {@link Attribute} obtained from {@link #getAttribute()}
* instead.
*
* @return The type descriptor
*/

View File

@ -41,7 +41,6 @@ public class HibernateTypeDescriptor {
return typeName;
}
/* package-protected */
public void setTypeName(String typeName) {
this.typeName = typeName;
}
@ -50,7 +49,6 @@ public class HibernateTypeDescriptor {
return explicitType;
}
/* package-protected */
public void setExplicitType(Type explicitType) {
this.explicitType = explicitType;
}
@ -59,7 +57,6 @@ public class HibernateTypeDescriptor {
return typeParameters;
}
/* package-protected */
void setTypeParameters(Map<String, String> typeParameters) {
this.typeParameters = typeParameters;
}

View File

@ -24,7 +24,10 @@
package org.hibernate.metamodel.binding;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.binder.source.MetaAttributeContext;
import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Value;
import org.hibernate.metamodel.relational.state.ColumnRelationalState;
import org.hibernate.metamodel.relational.state.ValueRelationalState;
@ -34,14 +37,20 @@ import org.hibernate.metamodel.relational.state.ValueRelationalState;
* @author Steve Ebersole
*/
public class SimpleAttributeBinding extends AbstractAttributeBinding implements KeyValueBinding {
private final boolean forceNonNullable;
private final boolean forceUnique;
private boolean insertable;
private boolean updatable;
private boolean keyCascadeDeleteEnabled;
private String unsavedValue;
private PropertyGeneration generation;
private String propertyAccessorName;
private String unsavedValue;
private boolean forceNonNullable;
private boolean forceUnique;
private boolean keyCascadeDeleteEnabled;
private boolean includedInOptimisticLocking;
private MetaAttributeContext metaAttributeContext;
SimpleAttributeBinding(EntityBinding entityBinding, boolean forceNonNullable, boolean forceUnique) {
super( entityBinding );
this.forceNonNullable = forceNonNullable;
@ -67,6 +76,11 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements
return isPrimaryKey() || state.isUnique();
}
@Override
public SingularAttribute getAttribute() {
return (SingularAttribute) super.getAttribute();
}
@Override
public boolean isSimpleValue() {
return true;
@ -76,7 +90,7 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements
return insertable;
}
protected void setInsertable(boolean insertable) {
public void setInsertable(boolean insertable) {
this.insertable = insertable;
}
@ -84,7 +98,7 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements
return updatable;
}
protected void setUpdatable(boolean updatable) {
public void setUpdatable(boolean updatable) {
this.updatable = updatable;
}
@ -117,4 +131,32 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements
public PropertyGeneration getGeneration() {
return generation;
}
public void setGeneration(PropertyGeneration generation) {
this.generation = generation;
}
public String getPropertyAccessorName() {
return propertyAccessorName;
}
public void setPropertyAccessorName(String propertyAccessorName) {
this.propertyAccessorName = propertyAccessorName;
}
public boolean isIncludedInOptimisticLocking() {
return includedInOptimisticLocking;
}
public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking) {
this.includedInOptimisticLocking = includedInOptimisticLocking;
}
public MetaAttributeContext getMetaAttributeContext() {
return metaAttributeContext;
}
public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) {
this.metaAttributeContext = metaAttributeContext;
}
}

View File

@ -88,7 +88,7 @@ public abstract class AbstractAttributeContainer implements AttributeContainer,
}
@Override
public SingularAttribute getOrCreateSingularAttribute(String name) {
public SingularAttribute locateOrCreateSingularAttribute(String name) {
SingularAttribute attribute = (SingularAttribute) getAttribute( name );
if ( attribute == null ) {
@ -99,7 +99,7 @@ public abstract class AbstractAttributeContainer implements AttributeContainer,
}
@Override
public SingularAttribute getOrCreateComponentAttribute(String name) {
public SingularAttribute locateOrCreateComponentAttribute(String name) {
SingularAttribute attribute = (SingularAttribute) getAttribute( name );
if ( attribute == null ) {
Component component = new Component( name, null );
@ -110,27 +110,27 @@ public abstract class AbstractAttributeContainer implements AttributeContainer,
}
@Override
public PluralAttribute getOrCreateBag(String name) {
return getOrCreatePluralAttribute( name, PluralAttributeNature.BAG );
public PluralAttribute locateOrCreateBag(String name) {
return locateOrCreatePluralAttribute( name, PluralAttributeNature.BAG );
}
@Override
public PluralAttribute getOrCreateSet(String name) {
return getOrCreatePluralAttribute( name, PluralAttributeNature.SET );
public PluralAttribute locateOrCreateSet(String name) {
return locateOrCreatePluralAttribute( name, PluralAttributeNature.SET );
}
@Override
public IndexedPluralAttribute getOrCreateList(String name) {
return (IndexedPluralAttribute) getOrCreatePluralAttribute( name, PluralAttributeNature.LIST );
public IndexedPluralAttribute locateOrCreateList(String name) {
return (IndexedPluralAttribute) locateOrCreatePluralAttribute( name, PluralAttributeNature.LIST );
}
@Override
public IndexedPluralAttribute getOrCreateMap(String name) {
return (IndexedPluralAttribute) getOrCreatePluralAttribute( name, PluralAttributeNature.MAP );
public IndexedPluralAttribute locateOrCreateMap(String name) {
return (IndexedPluralAttribute) locateOrCreatePluralAttribute( name, PluralAttributeNature.MAP );
}
@Override
public PluralAttribute getOrCreatePluralAttribute(String name, PluralAttributeNature nature) {
public PluralAttribute locateOrCreatePluralAttribute(String name, PluralAttributeNature nature) {
PluralAttribute attribute = (PluralAttribute) getAttribute( name );
if ( attribute == null ) {
attribute = nature.isIndexed()

View File

@ -32,13 +32,6 @@ import java.util.Set;
* @author Steve Ebersole
*/
public interface AttributeContainer extends Type {
/**
* Retrieve the attributes contained in this container.
*
* @return The contained attributes
*/
public Set<Attribute> getAttributes();
/**
* Retrieve an attribute by name.
*
@ -48,17 +41,18 @@ public interface AttributeContainer extends Type {
*/
public Attribute getAttribute(String name);
public SingularAttribute getOrCreateSingularAttribute(String name);
/**
* Retrieve the attributes contained in this container.
*
* @return The contained attributes
*/
public Set<Attribute> getAttributes();
public SingularAttribute getOrCreateComponentAttribute(String name);
public PluralAttribute getOrCreatePluralAttribute(String name, PluralAttributeNature nature);
public PluralAttribute getOrCreateBag(String name);
public PluralAttribute getOrCreateSet(String name);
public IndexedPluralAttribute getOrCreateList(String name);
public IndexedPluralAttribute getOrCreateMap(String name);
public SingularAttribute locateOrCreateSingularAttribute(String name);
public SingularAttribute locateOrCreateComponentAttribute(String name);
public PluralAttribute locateOrCreatePluralAttribute(String name, PluralAttributeNature nature);
public PluralAttribute locateOrCreateBag(String name);
public PluralAttribute locateOrCreateSet(String name);
public IndexedPluralAttribute locateOrCreateList(String name);
public IndexedPluralAttribute locateOrCreateMap(String name);
}

View File

@ -56,7 +56,7 @@ public abstract class AbstractTableSpecification implements TableSpecification {
}
@Override
public Column getOrCreateColumn(String name) {
public Column locateOrCreateColumn(String name) {
if(values.containsKey( name )){
return (Column) values.get( name );
}
@ -66,7 +66,7 @@ public abstract class AbstractTableSpecification implements TableSpecification {
}
@Override
public DerivedValue getOrCreateDerivedValue(String fragment) {
public DerivedValue locateOrCreateDerivedValue(String fragment) {
if(values.containsKey( fragment )){
return (DerivedValue) values.get( fragment );
}

View File

@ -59,7 +59,7 @@ public interface TableSpecification extends ValueContainer, Loggable {
*
* @return The generated column
*/
public Column getOrCreateColumn(String name);
public Column locateOrCreateColumn(String name);
/**
* Factory method for creating a {@link Column} associated with this container.
@ -77,7 +77,7 @@ public interface TableSpecification extends ValueContainer, Loggable {
*
* @return The generated value.
*/
public DerivedValue getOrCreateDerivedValue(String fragment);
public DerivedValue locateOrCreateDerivedValue(String fragment);
public Iterable<ForeignKey> getForeignKeys();

View File

@ -37,12 +37,12 @@ import org.hibernate.metamodel.relational.Value;
*/
public class ValueCreator {
public static Column createColumn(TableSpecification table,
public static Column createColumn(
TableSpecification table,
String attributeName,
ColumnRelationalState state,
boolean forceNonNullable,
boolean forceUnique
) {
boolean forceUnique) {
final String explicitName = state.getExplicitColumnName();
final String logicalColumnName = state.getNamingStrategy().logicalColumnName( explicitName, attributeName );
String columnName =
@ -58,22 +58,23 @@ public class ValueCreator {
if ( state.isGloballyQuotedIdentifiers() ) {
columnName = StringHelper.quote( columnName );
}
Column value = table.getOrCreateColumn( columnName );
Column value = table.locateOrCreateColumn( columnName );
value.initialize( state, forceNonNullable, forceUnique );
return value;
}
public static DerivedValue createDerivedValue(TableSpecification table,
public static DerivedValue createDerivedValue(
TableSpecification table,
DerivedValueRelationalState state) {
return table.getOrCreateDerivedValue( state.getFormula() );
return table.locateOrCreateDerivedValue( state.getFormula() );
}
public static SimpleValue createSimpleValue(TableSpecification table,
public static SimpleValue createSimpleValue(
TableSpecification table,
String attributeName,
SimpleValueRelationalState state,
boolean forceNonNullable,
boolean forceUnique
) {
boolean forceUnique) {
if ( state instanceof ColumnRelationalState ) {
ColumnRelationalState columnRelationalState = ColumnRelationalState.class.cast( state );
return createColumn( table, attributeName, columnRelationalState, forceNonNullable, forceUnique );
@ -86,12 +87,12 @@ public class ValueCreator {
}
}
public static Tuple createTuple(TableSpecification table,
public static Tuple createTuple(
TableSpecification table,
String attributeName,
TupleRelationalState state,
boolean forceNonNullable,
boolean forceUnique
) {
boolean forceUnique) {
Tuple tuple = table.createTuple( "[" + attributeName + "]" );
for ( SimpleValueRelationalState valueState : state.getRelationalStates() ) {
tuple.addValue( createSimpleValue( table, attributeName, valueState, forceNonNullable, forceUnique ) );
@ -99,7 +100,8 @@ public class ValueCreator {
return tuple;
}
public static Value createValue(TableSpecification table,
public static Value createValue(
TableSpecification table,
String attributeName,
ValueRelationalState state,
boolean forceNonNullable,

View File

@ -20,15 +20,17 @@
<!-- Inheritance -->
<jaxb:bindings node="//xsd:element[@name='class']/xsd:complexType">
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement</inheritance:implements>
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.JoinElementSource</inheritance:implements>
</jaxb:bindings>
<jaxb:bindings node="//xsd:complexType[@name='subclass-element']">
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement</inheritance:implements>
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement</inheritance:implements>
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.JoinElementSource</inheritance:implements>
</jaxb:bindings>
<jaxb:bindings node="//xsd:complexType[@name='joined-subclass-element']">
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement</inheritance:implements>
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement</inheritance:implements>
</jaxb:bindings>
<jaxb:bindings node="//xsd:complexType[@name='union-subclass-element']">
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement</inheritance:implements>
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement</inheritance:implements>
</jaxb:bindings>
<jaxb:bindings node="//xsd:complexType[@name='sql-insert-element']">
<inheritance:implements>org.hibernate.metamodel.binder.source.hbm.xml.mapping.CustomSqlElement</inheritance:implements>

View File

@ -29,7 +29,6 @@ import org.junit.Test;
import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.JavaType;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Datatype;
@ -61,14 +60,14 @@ public class SimpleValueBindingTests extends BaseUnitTestCase {
entityBinding.setEntity( entity );
entityBinding.setBaseTable( table );
SingularAttribute idAttribute = entity.getOrCreateSingularAttribute( "id" );
SingularAttribute idAttribute = entity.locateOrCreateSingularAttribute( "id" );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute );
attributeBinding.getHibernateTypeDescriptor().setTypeName( "long" );
assertSame( idAttribute, attributeBinding.getAttribute() );
entityBinding.getEntityIdentifier().setValueBinding( attributeBinding );
Column idColumn = table.getOrCreateColumn( "id" );
Column idColumn = table.locateOrCreateColumn( "id" );
idColumn.setDatatype( BIGINT );
idColumn.setSize( Size.precision( 18, 0 ) );
table.getPrimaryKey().addColumn( idColumn );

View File

@ -54,7 +54,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
assertNull( table.getPrimaryKey().getName() );
assertFalse( table.values().iterator().hasNext() );
Column idColumn = table.getOrCreateColumn( "id" );
Column idColumn = table.locateOrCreateColumn( "id" );
idColumn.setDatatype( INTEGER );
idColumn.setSize( Size.precision( 18, 0 ) );
table.getPrimaryKey().addColumn( idColumn );
@ -62,7 +62,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
assertEquals( "my_table_pk", table.getPrimaryKey().getName() );
assertEquals( "my_table.PK", table.getPrimaryKey().getExportIdentifier() );
Column col_1 = table.getOrCreateColumn( "col_1" );
Column col_1 = table.locateOrCreateColumn( "col_1" );
col_1.setDatatype( VARCHAR );
col_1.setSize( Size.length( 512 ) );
@ -107,7 +107,7 @@ public class TableManipulationTests extends BaseUnitTestCase {
Schema schema = new Schema( null, null );
Table book = schema.createTable( Identifier.toIdentifier( "BOOK" ) );
Column bookId = book.getOrCreateColumn( "id" );
Column bookId = book.locateOrCreateColumn( "id" );
bookId.setDatatype( INTEGER );
bookId.setSize( Size.precision( 18, 0 ) );
book.getPrimaryKey().addColumn( bookId );
@ -115,13 +115,13 @@ public class TableManipulationTests extends BaseUnitTestCase {
Table page = schema.createTable( Identifier.toIdentifier( "PAGE" ) );
Column pageId = page.getOrCreateColumn( "id" );
Column pageId = page.locateOrCreateColumn( "id" );
pageId.setDatatype( INTEGER );
pageId.setSize( Size.precision( 18, 0 ) );
page.getPrimaryKey().addColumn( pageId );
page.getPrimaryKey().setName( "PAGE_PK" );
Column pageBookId = page.getOrCreateColumn( "BOOK_ID" );
Column pageBookId = page.locateOrCreateColumn( "BOOK_ID" );
pageId.setDatatype( INTEGER );
pageId.setSize( Size.precision( 18, 0 ) );
ForeignKey pageBookFk = page.createForeignKey( book, "PAGE_BOOK_FK" );

View File

@ -41,7 +41,7 @@ import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.binder.source.MappingDefaults;
import org.hibernate.metamodel.binder.source.MetadataImplementor;
import org.hibernate.metamodel.binder.source.annotations.AnnotationsBindingContext;
import org.hibernate.metamodel.domain.JavaType;
import org.hibernate.metamodel.domain.Type;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
@ -93,7 +93,7 @@ public class TestAnnotationsBindingContextImpl implements AnnotationsBindingCont
}
@Override
public JavaType makeJavaType(String className) {
public Type makeJavaType(String className) {
throw new NotYetImplementedException();
}