From 24edf42c04a72bcc0d5f13203e43f227165b6f0d Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 12 Jul 2011 12:58:40 -0500 Subject: [PATCH] HHH-6371 - Develop metamodel binding creation using a push approach --- .../internal/CacheDataDescriptionImpl.java | 2 +- .../cfg/annotations/SimpleValueBinder.java | 2 +- .../binding/AbstractAttributeBinding.java | 2 +- .../metamodel/binding/CollectionElement.java | 2 +- .../metamodel/binding/EntityIdentifier.java | 3 +- .../binding/HibernateTypeDescriptor.java | 41 +++- .../metamodel/source/hbm/BindingCreator.java | 224 ++++++++++++------ .../jaxb/mapping/SingularAttributeSource.java | 37 +++ ...bmSimpleValueRelationalStateContainer.java | 18 +- .../internal/AttributeTypeResolver.java | 15 +- .../source/internal/MetadataImpl.java | 4 +- .../entity/AbstractEntityPersister.java | 3 +- .../entity/SingleTableEntityPersister.java | 4 +- .../org/hibernate/tuple/PropertyFactory.java | 9 +- .../tuple/entity/PojoEntityTuplizer.java | 2 +- .../src/main/xjb/hbm-mapping-bindings.xjb | 17 +- .../binding/AbstractBasicBindingTests.java | 5 +- .../binding/SimpleValueBindingTests.java | 2 +- 18 files changed, 268 insertions(+), 124 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/SingularAttributeSource.java diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java index 4e2bdd9f6a..f0a9d66014 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java @@ -99,7 +99,7 @@ public class CacheDataDescriptionImpl implements CacheDataDescription { ( VersionType ) model .getVersioningValueBinding() .getHibernateTypeDescriptor() - .getExplicitType() + .getResolvedTypeMapping() ).getComparator(); } return versionComparator; diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java index c13791cfca..88967b2b78 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java @@ -277,7 +277,7 @@ public class SimpleValueBinder { this.explicitType = explicitType; } - //FIXME raise an assertion failure if setExplicitType(String) and setExplicitType(Type) are use at the same time + //FIXME raise an assertion failure if setResolvedTypeMapping(String) and setResolvedTypeMapping(Type) are use at the same time public void setExplicitType(Type typeAnn) { if ( typeAnn != null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java index a42b3fd875..dce78cee7b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java @@ -70,7 +70,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { } protected void initialize(AttributeBindingState state) { - hibernateTypeDescriptor.setTypeName( state.getTypeName() ); + hibernateTypeDescriptor.setExplicitTypeName( state.getTypeName() ); hibernateTypeDescriptor.setTypeParameters( state.getTypeParameters() ); isLazy = state.isLazy(); propertyAccessorName = state.getPropertyAccessorName(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java index c1fa1c6150..1ff1902f07 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java @@ -50,7 +50,7 @@ public abstract class CollectionElement { /* package-protected */ void setTypeName(String typeName) { - hibernateTypeDescriptor.setTypeName( typeName ); + hibernateTypeDescriptor.setExplicitTypeName( typeName ); } /* package-protected */ diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityIdentifier.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityIdentifier.java index 7d75853f44..67898e6826 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityIdentifier.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityIdentifier.java @@ -24,7 +24,6 @@ package org.hibernate.metamodel.binding; import java.util.Properties; -import javax.persistence.GenerationType; import org.jboss.logging.Logger; @@ -93,7 +92,7 @@ public class EntityIdentifier { } identifierGenerator = factory.createIdentifierGenerator( idGenerator.getStrategy(), - getValueBinding().getHibernateTypeDescriptor().getExplicitType(), + getValueBinding().getHibernateTypeDescriptor().getResolvedTypeMapping(), props ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java index c4c1d5c13c..c4699bc2fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java @@ -33,31 +33,50 @@ import org.hibernate.type.Type; * @author Steve Ebersole */ public class HibernateTypeDescriptor { - private String typeName; - private Type explicitType; + private String explicitTypeName; + private String javaTypeName; + private boolean isToOne; private Map typeParameters; - public String getTypeName() { - return typeName; + private Type resolvedTypeMapping; + + public String getExplicitTypeName() { + return explicitTypeName; } - public void setTypeName(String typeName) { - this.typeName = typeName; + public void setExplicitTypeName(String explicitTypeName) { + this.explicitTypeName = explicitTypeName; } - public Type getExplicitType() { - return explicitType; + public String getJavaTypeName() { + return javaTypeName; } - public void setExplicitType(Type explicitType) { - this.explicitType = explicitType; + public void setJavaTypeName(String javaTypeName) { + this.javaTypeName = javaTypeName; + } + + public boolean isToOne() { + return isToOne; + } + + public void setToOne(boolean toOne) { + isToOne = toOne; } public Map getTypeParameters() { return typeParameters; } - void setTypeParameters(Map typeParameters) { + public void setTypeParameters(Map typeParameters) { this.typeParameters = typeParameters; } + + public Type getResolvedTypeMapping() { + return resolvedTypeMapping; + } + + public void setResolvedTypeMapping(Type resolvedTypeMapping) { + this.resolvedTypeMapping = resolvedTypeMapping; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/BindingCreator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/BindingCreator.java index 5bf17a2b6f..6907f7db3e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/BindingCreator.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/BindingCreator.java @@ -34,13 +34,13 @@ 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.StringHelper; import org.hibernate.internal.util.Value; import org.hibernate.internal.util.beans.BeanInfoHelper; import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.source.MappingException; import org.hibernate.metamodel.source.MetadataImplementor; -import org.hibernate.metamodel.source.annotations.attribute.SimpleAttribute; import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.JoinElementSource; import org.hibernate.metamodel.binding.BagBinding; @@ -59,6 +59,7 @@ 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.jaxb.mapping.SingularAttributeSource; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLAnyElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLBagElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLCacheElement; @@ -140,7 +141,6 @@ public class BindingCreator { private EntityBinding doCreateEntityBinding(EntitySourceInformation entitySourceInfo, EntityBinding superEntityBinding) { final EntityBinding entityBinding = createBasicEntityBinding( entitySourceInfo, superEntityBinding ); - bindPrimaryTable( entitySourceInfo, entityBinding ); bindAttributes( entitySourceInfo, entityBinding ); bindSecondaryTables( entitySourceInfo, entityBinding ); bindTableUniqueConstraints( entityBinding ); @@ -205,6 +205,7 @@ public class BindingCreator { entityBinding.setEntity( entity ); performBasicEntityBind( entityBinding, entitySourceInfo ); + bindIdentifier( entityBinding, entitySourceInfo ); entityBinding.setMutable( xmlClass.isMutable() ); entityBinding.setExplicitPolymorphism( "explicit".equals( xmlClass.getPolymorphism() ) ); @@ -354,6 +355,8 @@ public class BindingCreator { @SuppressWarnings( {"unchecked"}) private void performBasicEntityBind(EntityBinding entityBinding, EntitySourceInformation entitySourceInfo) { + bindPrimaryTable( entitySourceInfo, entityBinding ); + entityBinding.setJpaEntityName( null ); final EntityElement entityElement = entitySourceInfo.getEntityElement(); @@ -499,6 +502,77 @@ public class BindingCreator { private Stack attributeColumnTableStack = new Stack(); + private void bindIdentifier(EntityBinding entityBinding, EntitySourceInformation entitySourceInfo) { + final XMLHibernateMapping.XMLClass rootClassElement = (XMLHibernateMapping.XMLClass) entitySourceInfo.getEntityElement(); + if ( rootClassElement.getId() != null ) { + bindSimpleIdentifierAttribute( entityBinding, entitySourceInfo ); + } + else if ( rootClassElement.getCompositeId() != null ) { + bindCompositeIdentifierAttribute( entityBinding, entitySourceInfo ); + } + } + + private void bindSimpleIdentifierAttribute(EntityBinding entityBinding, EntitySourceInformation entitySourceInfo) { + final XMLHibernateMapping.XMLClass.XMLId idElement = ( (XMLHibernateMapping.XMLClass) entitySourceInfo.getEntityElement() ).getId(); + final String idAttributeName = idElement.getName() == null + ? "id" + : idElement.getName(); + + final SimpleAttributeBinding idAttributeBinding = doBasicSimpleAttributeBindingCreation( + idAttributeName, + idElement, + entityBinding + ); + + idAttributeBinding.setInsertable( false ); + idAttributeBinding.setUpdatable( false ); + idAttributeBinding.setGeneration( PropertyGeneration.INSERT ); + idAttributeBinding.setLazy( false ); + idAttributeBinding.setIncludedInOptimisticLocking( false ); + + final org.hibernate.metamodel.relational.Value relationalValue = makeValue( + new RelationValueMetadataSource() { + @Override + public String getColumnAttribute() { + return idElement.getColumnAttribute(); + } + + @Override + public String getFormulaAttribute() { + return null; + } + + @Override + public List getColumnOrFormulaElements() { + return idElement.getColumn(); + } + }, + idAttributeBinding + ); + + idAttributeBinding.setValue( relationalValue ); + if ( SimpleValue.class.isInstance( relationalValue ) ) { + if ( !Column.class.isInstance( relationalValue ) ) { + // this should never ever happen.. + throw new MappingException( "Simple ID is not a column.", currentBindingContext.getOrigin() ); + } + entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( relationalValue ) ); + } + else { + for ( SimpleValue subValue : ( (Tuple) relationalValue ).values() ) { + if ( Column.class.isInstance( subValue ) ) { + entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( subValue ) ); + } + } + } + } + + private void bindCompositeIdentifierAttribute( + EntityBinding entityBinding, + EntitySourceInformation entitySourceInfo) { + //To change body of created methods use File | Settings | File Templates. + } + 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 @@ -601,39 +675,69 @@ public class BindingCreator { } } - private void bindProperty(XMLPropertyElement property, EntityBinding entityBinding) { - SingularAttribute attr = entityBinding.getEntity().locateOrCreateSingularAttribute( property.getName() ); - SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( attr ); - resolveTypeInformation( property, attributeBinding ); + private void bindProperty(final XMLPropertyElement property, EntityBinding entityBinding) { + SimpleAttributeBinding attributeBinding = doBasicSimpleAttributeBindingCreation( property.getName(), property, entityBinding ); attributeBinding.setInsertable( Helper.getBooleanValue( property.isInsert(), true ) ); - attributeBinding.setInsertable( Helper.getBooleanValue( property.isUpdate(), true ) ); + attributeBinding.setUpdatable( Helper.getBooleanValue( property.isUpdate(), true ) ); attributeBinding.setGeneration( PropertyGeneration.parse( property.getGenerated() ) ); attributeBinding.setLazy( property.isLazy() ); attributeBinding.setIncludedInOptimisticLocking( property.isOptimisticLock() ); +// todo : implement. Is this meant to indicate the natural-id? +// attributeBinding.setAlternateUniqueKey( ... ); + + attributeBinding.setValue( + makeValue( + new RelationValueMetadataSource() { + @Override + public String getColumnAttribute() { + return property.getColumn(); + } + + @Override + public String getFormulaAttribute() { + return property.getFormula(); + } + + @Override + public List getColumnOrFormulaElements() { + return property.getColumnOrFormula(); + } + }, + attributeBinding + ) + ); + } + + private SimpleAttributeBinding doBasicSimpleAttributeBindingCreation( + String attributeName, + SingularAttributeSource attributeSource, + EntityBinding entityBinding) { + // todo : the need to pass in the attribute name here could be alleviated by making name required on etc + SingularAttribute attribute = entityBinding.getEntity().locateOrCreateSingularAttribute( attributeName ); + SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( attribute ); + resolveTypeInformation( attributeSource, attributeBinding ); + attributeBinding.setPropertyAccessorName( Helper.getPropertyAccessorName( - property.getAccess(), + attributeSource.getAccess(), false, currentBindingContext.getMappingDefaults().getPropertyAccessorName() ) ); attributeBinding.setMetaAttributeContext( - Helper.extractMetaAttributeContext( property.getMeta(), entityBinding.getMetaAttributeContext() ) + Helper.extractMetaAttributeContext( attributeSource.getMeta(), entityBinding.getMetaAttributeContext() ) ); -// todo : implement. Is this meant to indicate the natural-id? -// attributeBinding.setAlternateUniqueKey( ... ); - - attributeBinding.setValue( makeValue( property, attributeBinding ) ); - + return attributeBinding; } - private void resolveTypeInformation(XMLPropertyElement property, final SimpleAttributeBinding attributeBinding) { + private void resolveTypeInformation(SingularAttributeSource property, final SimpleAttributeBinding attributeBinding) { final Class attributeJavaType = determineJavaType( attributeBinding.getAttribute() ); if ( attributeJavaType != null ) { + attributeBinding.getHibernateTypeDescriptor().setJavaTypeName( attributeJavaType.getName() ); ( (AbstractAttributeContainer.SingularAttributeImpl) attributeBinding.getAttribute() ).resolveType( currentBindingContext.makeJavaType( attributeJavaType.getName() ) ); @@ -644,16 +748,16 @@ public class BindingCreator { final String explicitTypeName = property.getTypeAttribute(); final TypeDef typeDef = currentBindingContext.getMetadataImplementor().getTypeDefinition( explicitTypeName ); if ( typeDef != null ) { - attributeBinding.getHibernateTypeDescriptor().setTypeName( typeDef.getTypeClass() ); + attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( typeDef.getTypeClass() ); attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( typeDef.getParameters() ); } else { - attributeBinding.getHibernateTypeDescriptor().setTypeName( explicitTypeName ); + attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( 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() ); + attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( property.getType().getName() ); for ( XMLParamElement xmlParamElement : property.getType().getParam() ) { attributeBinding.getHibernateTypeDescriptor().getTypeParameters().put( xmlParamElement.getName(), @@ -662,29 +766,9 @@ public class BindingCreator { } } 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? + if ( attributeJavaType == null ) { + // we will have problems later determining the Hibernate Type to use. Should we throw an + // exception now? Might be better to get better contextual info } } } @@ -696,7 +780,7 @@ public class BindingCreator { BeanInfoHelper.visitBeanInfo( ownerClass, delegate ); return delegate.javaType; } - catch ( Exception e ) { + catch ( Exception ignore ) { // todo : log it? } return null; @@ -721,42 +805,51 @@ public class BindingCreator { } } - private org.hibernate.metamodel.relational.Value makeValue( - XMLPropertyElement property, - SimpleAttributeBinding attributeBinding) { + private static interface RelationValueMetadataSource { + public String getColumnAttribute(); + public String getFormulaAttribute(); + public List getColumnOrFormulaElements(); + } + private org.hibernate.metamodel.relational.Value makeValue( + RelationValueMetadataSource relationValueMetadataSource, + 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() ) { + if ( StringHelper.isNotEmpty( relationValueMetadataSource.getColumnAttribute() ) ) { + if ( relationValueMetadataSource.getColumnOrFormulaElements() != null + && ! relationValueMetadataSource.getColumnOrFormulaElements().isEmpty() ) { throw new MappingException( "column/formula attribute may not be used together with / subelement", currentBindingContext.getOrigin() ); } - if ( property.getFormula() != null ) { + if ( StringHelper.isNotEmpty( relationValueMetadataSource.getFormulaAttribute() ) ) { throw new MappingException( "column and formula attributes may not be used together", currentBindingContext.getOrigin() ); } - return valueSource.locateOrCreateColumn( property.getColumn() ); + return valueSource.locateOrCreateColumn( relationValueMetadataSource.getColumnAttribute() ); } - else if ( property.getFormula() != null && ! property.getFormula().isEmpty() ) { - if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) { + else if ( StringHelper.isNotEmpty( relationValueMetadataSource.getFormulaAttribute() ) ) { + if ( relationValueMetadataSource.getColumnOrFormulaElements() != null + && ! relationValueMetadataSource.getColumnOrFormulaElements().isEmpty() ) { throw new MappingException( "column/formula attribute may not be used together with / subelement", currentBindingContext.getOrigin() ); } - return valueSource.locateOrCreateDerivedValue( property.getFormula() ); + // column/formula attribute combo checked already + return valueSource.locateOrCreateDerivedValue( relationValueMetadataSource.getFormulaAttribute() ); } - else if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) { + else if ( relationValueMetadataSource.getColumnOrFormulaElements() != null + && ! relationValueMetadataSource.getColumnOrFormulaElements().isEmpty() ) { List values = new ArrayList(); - for ( Object columnOrFormula : property.getColumnOrFormula() ) { + for ( Object columnOrFormula : relationValueMetadataSource.getColumnOrFormulaElements() ) { final SimpleValue value; if ( XMLColumnElement.class.isInstance( columnOrFormula ) ) { final XMLColumnElement columnElement = (XMLColumnElement) columnOrFormula; @@ -781,9 +874,7 @@ public class BindingCreator { value = column; } else { - // todo : ??? Seems jaxb is not generating this class ?!?!?! -// final XMLFormulaElement formulaElement = (XMLFormulaElement) columnOrFormula; - value = null; + value = valueSource.locateOrCreateDerivedValue( (String) columnOrFormula ); } if ( value != null ) { values.add( value ); @@ -810,25 +901,6 @@ public class BindingCreator { .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) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/SingularAttributeSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/SingularAttributeSource.java new file mode 100644 index 0000000000..6163bbf281 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/jaxb/mapping/SingularAttributeSource.java @@ -0,0 +1,37 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.source.hbm.jaxb.mapping; + +/** + * @author Steve Ebersole + */ +public interface SingularAttributeSource extends MetaAttributeContainer { + public String getName(); + + public String getTypeAttribute(); + + public XMLTypeElement getType(); + + public String getAccess(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/relational/HbmSimpleValueRelationalStateContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/relational/HbmSimpleValueRelationalStateContainer.java index 9092a6e70b..9954e5e114 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/relational/HbmSimpleValueRelationalStateContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/relational/HbmSimpleValueRelationalStateContainer.java @@ -78,7 +78,7 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt else if ( id.getColumn() != null ) { throw new MappingException( "column attribute may not be used together with subelement" ); } - this.hibernateTypeDescriptor.setTypeName( id.getTypeAttribute() ); + this.hibernateTypeDescriptor.setExplicitTypeName( id.getTypeAttribute() ); } public HbmSimpleValueRelationalStateContainer( @@ -95,7 +95,11 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt else if ( discriminator.getColumn() != null || discriminator.getFormula() != null) { throw new MappingException( "column/formula attribute may not be used together with / subelement" ); } - this.hibernateTypeDescriptor.setTypeName( discriminator.getType() == null ? "string" : discriminator.getType() ); + this.hibernateTypeDescriptor.setExplicitTypeName( + discriminator.getType() == null ? + "string" : + discriminator.getType() + ); } public HbmSimpleValueRelationalStateContainer( @@ -112,7 +116,7 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt else if ( version.getColumn() != null ) { throw new MappingException( "column attribute may not be used together with subelement" ); } - this.hibernateTypeDescriptor.setTypeName( version.getType() == null ? "integer" : version.getType() ); + this.hibernateTypeDescriptor.setExplicitTypeName( version.getType() == null ? "integer" : version.getType() ); } public HbmSimpleValueRelationalStateContainer( @@ -129,7 +133,11 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt else if ( timestamp.getColumn() != null ) { throw new MappingException( "column attribute may not be used together with subelement" ); } - this.hibernateTypeDescriptor.setTypeName( "db".equals( timestamp.getSource() ) ? "dbtimestamp" : "timestamp" ); + this.hibernateTypeDescriptor.setExplicitTypeName( + "db".equals( timestamp.getSource() ) ? + "dbtimestamp" : + "timestamp" + ); } public HbmSimpleValueRelationalStateContainer( @@ -146,7 +154,7 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt else if ( property.getColumn() != null || property.getFormula() != null) { throw new MappingException( "column/formula attribute may not be used together with / subelement" ); } - this.hibernateTypeDescriptor.setTypeName( property.getTypeAttribute() ); + this.hibernateTypeDescriptor.setExplicitTypeName( property.getTypeAttribute() ); } public HbmSimpleValueRelationalStateContainer( diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AttributeTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AttributeTypeResolver.java index b27526c6ca..3d51927d3a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AttributeTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/AttributeTypeResolver.java @@ -29,10 +29,7 @@ import org.hibernate.MappingException; import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.HibernateTypeDescriptor; -import org.hibernate.metamodel.domain.AbstractAttributeContainer; import org.hibernate.metamodel.domain.Attribute; -import org.hibernate.metamodel.domain.BasicType; -import org.hibernate.metamodel.domain.JavaType; import org.hibernate.metamodel.relational.Datatype; import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.relational.Value; @@ -69,29 +66,29 @@ class AttributeTypeResolver { } private Type resolveHibernateType(AttributeBinding attributeBinding) { - if ( attributeBinding.getHibernateTypeDescriptor().getExplicitType() != null ) { - return attributeBinding.getHibernateTypeDescriptor().getExplicitType(); // already resolved + if ( attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() != null ) { + return attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(); // already resolved } // this only works for "basic" attribute types HibernateTypeDescriptor typeDescriptor = attributeBinding.getHibernateTypeDescriptor(); - if ( typeDescriptor == null || typeDescriptor.getTypeName() == null) { + if ( typeDescriptor == null || typeDescriptor.getExplicitTypeName() == null) { throw new MappingException( "Hibernate type name has not been defined for attribute: " + getQualifiedAttributeName( attributeBinding ) ); } Type type = null; - if ( typeDescriptor.getTypeName() != null ) { + if ( typeDescriptor.getExplicitTypeName() != null ) { Properties typeParameters = null; if ( typeDescriptor.getTypeParameters() != null ) { typeParameters = new Properties(); typeParameters.putAll( typeDescriptor.getTypeParameters() ); } type = metadata.getTypeResolver().heuristicType( - typeDescriptor.getTypeName(), + typeDescriptor.getExplicitTypeName(), typeParameters ); - typeDescriptor.setExplicitType( type ); + typeDescriptor.setResolvedTypeMapping( type ); } return type; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java index 6811d33a44..593e8d3525 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java @@ -503,7 +503,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { .getEntityIdentifier() .getValueBinding() .getHibernateTypeDescriptor() - .getExplicitType(); + .getResolvedTypeMapping(); } @Override @@ -527,7 +527,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { if ( attributeBinding == null ) { throw new MappingException( "unknown property: " + entityName + '.' + propertyName ); } - return attributeBinding.getHibernateTypeDescriptor().getExplicitType(); + return attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(); } private class MappingDefaultsImpl implements MappingDefaults { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 3076c610fa..0f071a3e27 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -97,7 +97,6 @@ import org.hibernate.metadata.ClassMetadata; import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.relational.DerivedValue; -import org.hibernate.metamodel.relational.Identifier; import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.pretty.MessageHelper; import org.hibernate.property.BackrefPropertyAccessor; @@ -904,7 +903,7 @@ public abstract class AbstractEntityPersister lazyProperties.add( prop.getAttribute().getName() ); lazyNames.add( prop.getAttribute().getName() ); lazyNumbers.add( i ); - lazyTypes.add( prop.getHibernateTypeDescriptor().getExplicitType()); + lazyTypes.add( prop.getHibernateTypeDescriptor().getResolvedTypeMapping()); lazyColAliases.add( colAliases ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java index cc293e6c83..4f30c3d2f9 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java @@ -29,7 +29,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; -import org.hibernate.EntityMode; + import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; @@ -586,7 +586,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { .getEntityDiscriminator() .getValueBinding() .getHibernateTypeDescriptor() - .getExplicitType(); + .getResolvedTypeMapping(); if ( entityBinding.getDiscriminatorValue() == null ) { discriminatorValue = NULL_DISCRIMINATOR; discriminatorSQLValue = InFragment.NULL; diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java index 6ff5e12423..00db55906e 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java @@ -37,7 +37,6 @@ import org.hibernate.mapping.Property; import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.EntityBinding; -import org.hibernate.metamodel.binding.EntityIdentifier; import org.hibernate.metamodel.binding.PluralAttributeBinding; import org.hibernate.metamodel.binding.SimpleAttributeBinding; import org.hibernate.property.Getter; @@ -111,7 +110,7 @@ public class PropertyFactory { // TODO: the following will cause an NPE with "virtual" IDs; how should they be set? final String mappedUnsavedValue = property.getUnsavedValue(); - final Type type = property.getHibernateTypeDescriptor().getExplicitType(); + final Type type = property.getHibernateTypeDescriptor().getResolvedTypeMapping(); IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue( mappedUnsavedValue, @@ -193,7 +192,7 @@ public class PropertyFactory { VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue( mappedUnsavedValue, getGetter( property ), - ( VersionType ) property.getHibernateTypeDescriptor().getExplicitType(), + ( VersionType ) property.getHibernateTypeDescriptor().getResolvedTypeMapping(), getConstructor( property.getEntityBinding() ) ); @@ -202,7 +201,7 @@ public class PropertyFactory { return new VersionProperty( property.getAttribute().getName(), null, - property.getHibernateTypeDescriptor().getExplicitType(), + property.getHibernateTypeDescriptor().getResolvedTypeMapping(), lazy, property.isInsertable(), property.isUpdatable(), @@ -267,7 +266,7 @@ public class PropertyFactory { */ public static StandardProperty buildStandardProperty(AttributeBinding property, boolean lazyAvailable) { - final Type type = property.getHibernateTypeDescriptor().getExplicitType(); + final Type type = property.getHibernateTypeDescriptor().getResolvedTypeMapping(); // we need to dirty check collections, since they can cause an owner // version number increment diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java index 73ccd8c088..04879fa3ca 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java @@ -328,7 +328,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer { .getEntityIdentifier() .getValueBinding() .getHibernateTypeDescriptor() - .getExplicitType() : + .getResolvedTypeMapping() : null ); } diff --git a/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb b/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb index 74dcd601f6..a306b2269a 100644 --- a/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb +++ b/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb @@ -17,7 +17,7 @@ - + org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement org.hibernate.metamodel.source.hbm.jaxb.mapping.JoinElementSource @@ -45,6 +45,21 @@ org.hibernate.metamodel.source.hbm.jaxb.mapping.CustomSqlElement + + org.hibernate.metamodel.source.hbm.jaxb.mapping.SingularAttributeSource + + + org.hibernate.metamodel.source.hbm.jaxb.mapping.SingularAttributeSource + + + diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java index ca7f01602f..8ea115db92 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java @@ -36,7 +36,6 @@ import org.hibernate.metamodel.source.MetadataImplementor; import org.hibernate.metamodel.source.internal.MetadataImpl; import org.hibernate.metamodel.domain.BasicType; import org.hibernate.metamodel.domain.SingularAttribute; -import org.hibernate.metamodel.domain.TypeNature; import org.hibernate.metamodel.relational.Column; import org.hibernate.metamodel.relational.Datatype; import org.hibernate.metamodel.relational.SimpleValue; @@ -137,7 +136,7 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" ); assertNotNull( idAttributeBinding ); assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() ); - assertSame( LongType.INSTANCE, idAttributeBinding.getHibernateTypeDescriptor().getExplicitType() ); + assertSame( LongType.INSTANCE, idAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() ); assertTrue( idAttributeBinding.getAttribute().isSingular() ); assertNotNull( idAttributeBinding.getAttribute() ); @@ -154,7 +153,7 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" ); assertNotNull( nameBinding ); - assertSame( StringType.INSTANCE, nameBinding.getHibernateTypeDescriptor().getExplicitType() ); + assertSame( StringType.INSTANCE, nameBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() ); assertNotNull( nameBinding.getAttribute() ); assertNotNull( nameBinding.getValue() ); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java index 633a990aea..250420892d 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java @@ -62,7 +62,7 @@ public class SimpleValueBindingTests extends BaseUnitTestCase { SingularAttribute idAttribute = entity.locateOrCreateSingularAttribute( "id" ); SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute ); - attributeBinding.getHibernateTypeDescriptor().setTypeName( "long" ); + attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( "long" ); assertSame( idAttribute, attributeBinding.getAttribute() ); entityBinding.getEntityIdentifier().setValueBinding( attributeBinding );