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

This commit is contained in:
Steve Ebersole 2011-07-12 12:58:40 -05:00
parent e339dac91e
commit 24edf42c04
18 changed files with 268 additions and 124 deletions

View File

@ -99,7 +99,7 @@ public class CacheDataDescriptionImpl implements CacheDataDescription {
( VersionType ) model ( VersionType ) model
.getVersioningValueBinding() .getVersioningValueBinding()
.getHibernateTypeDescriptor() .getHibernateTypeDescriptor()
.getExplicitType() .getResolvedTypeMapping()
).getComparator(); ).getComparator();
} }
return versionComparator; return versionComparator;

View File

@ -277,7 +277,7 @@ public class SimpleValueBinder {
this.explicitType = explicitType; 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) { public void setExplicitType(Type typeAnn) {
if ( typeAnn != null ) { if ( typeAnn != null ) {

View File

@ -70,7 +70,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding {
} }
protected void initialize(AttributeBindingState state) { protected void initialize(AttributeBindingState state) {
hibernateTypeDescriptor.setTypeName( state.getTypeName() ); hibernateTypeDescriptor.setExplicitTypeName( state.getTypeName() );
hibernateTypeDescriptor.setTypeParameters( state.getTypeParameters() ); hibernateTypeDescriptor.setTypeParameters( state.getTypeParameters() );
isLazy = state.isLazy(); isLazy = state.isLazy();
propertyAccessorName = state.getPropertyAccessorName(); propertyAccessorName = state.getPropertyAccessorName();

View File

@ -50,7 +50,7 @@ public abstract class CollectionElement {
/* package-protected */ /* package-protected */
void setTypeName(String typeName) { void setTypeName(String typeName) {
hibernateTypeDescriptor.setTypeName( typeName ); hibernateTypeDescriptor.setExplicitTypeName( typeName );
} }
/* package-protected */ /* package-protected */

View File

@ -24,7 +24,6 @@
package org.hibernate.metamodel.binding; package org.hibernate.metamodel.binding;
import java.util.Properties; import java.util.Properties;
import javax.persistence.GenerationType;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -93,7 +92,7 @@ public class EntityIdentifier {
} }
identifierGenerator = factory.createIdentifierGenerator( identifierGenerator = factory.createIdentifierGenerator(
idGenerator.getStrategy(), idGenerator.getStrategy(),
getValueBinding().getHibernateTypeDescriptor().getExplicitType(), getValueBinding().getHibernateTypeDescriptor().getResolvedTypeMapping(),
props props
); );
} }

View File

@ -33,31 +33,50 @@ import org.hibernate.type.Type;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class HibernateTypeDescriptor { public class HibernateTypeDescriptor {
private String typeName; private String explicitTypeName;
private Type explicitType; private String javaTypeName;
private boolean isToOne;
private Map<String, String> typeParameters; private Map<String, String> typeParameters;
public String getTypeName() { private Type resolvedTypeMapping;
return typeName;
public String getExplicitTypeName() {
return explicitTypeName;
} }
public void setTypeName(String typeName) { public void setExplicitTypeName(String explicitTypeName) {
this.typeName = typeName; this.explicitTypeName = explicitTypeName;
} }
public Type getExplicitType() { public String getJavaTypeName() {
return explicitType; return javaTypeName;
} }
public void setExplicitType(Type explicitType) { public void setJavaTypeName(String javaTypeName) {
this.explicitType = explicitType; this.javaTypeName = javaTypeName;
}
public boolean isToOne() {
return isToOne;
}
public void setToOne(boolean toOne) {
isToOne = toOne;
} }
public Map<String, String> getTypeParameters() { public Map<String, String> getTypeParameters() {
return typeParameters; return typeParameters;
} }
void setTypeParameters(Map<String, String> typeParameters) { public void setTypeParameters(Map<String, String> typeParameters) {
this.typeParameters = typeParameters; this.typeParameters = typeParameters;
} }
public Type getResolvedTypeMapping() {
return resolvedTypeMapping;
}
public void setResolvedTypeMapping(Type resolvedTypeMapping) {
this.resolvedTypeMapping = resolvedTypeMapping;
}
} }

View File

@ -34,13 +34,13 @@ import org.hibernate.EntityMode;
import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.NamingStrategy; import org.hibernate.cfg.NamingStrategy;
import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.Value; import org.hibernate.internal.util.Value;
import org.hibernate.internal.util.beans.BeanInfoHelper; import org.hibernate.internal.util.beans.BeanInfoHelper;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.source.MappingException; import org.hibernate.metamodel.source.MappingException;
import org.hibernate.metamodel.source.MetadataImplementor; 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.EntityElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.JoinElementSource; import org.hibernate.metamodel.source.hbm.jaxb.mapping.JoinElementSource;
import org.hibernate.metamodel.binding.BagBinding; 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.Size;
import org.hibernate.metamodel.relational.TableSpecification; import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.Tuple; 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.XMLAnyElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLBagElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLBagElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLCacheElement; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLCacheElement;
@ -140,7 +141,6 @@ public class BindingCreator {
private EntityBinding doCreateEntityBinding(EntitySourceInformation entitySourceInfo, EntityBinding superEntityBinding) { private EntityBinding doCreateEntityBinding(EntitySourceInformation entitySourceInfo, EntityBinding superEntityBinding) {
final EntityBinding entityBinding = createBasicEntityBinding( entitySourceInfo, superEntityBinding ); final EntityBinding entityBinding = createBasicEntityBinding( entitySourceInfo, superEntityBinding );
bindPrimaryTable( entitySourceInfo, entityBinding );
bindAttributes( entitySourceInfo, entityBinding ); bindAttributes( entitySourceInfo, entityBinding );
bindSecondaryTables( entitySourceInfo, entityBinding ); bindSecondaryTables( entitySourceInfo, entityBinding );
bindTableUniqueConstraints( entityBinding ); bindTableUniqueConstraints( entityBinding );
@ -205,6 +205,7 @@ public class BindingCreator {
entityBinding.setEntity( entity ); entityBinding.setEntity( entity );
performBasicEntityBind( entityBinding, entitySourceInfo ); performBasicEntityBind( entityBinding, entitySourceInfo );
bindIdentifier( entityBinding, entitySourceInfo );
entityBinding.setMutable( xmlClass.isMutable() ); entityBinding.setMutable( xmlClass.isMutable() );
entityBinding.setExplicitPolymorphism( "explicit".equals( xmlClass.getPolymorphism() ) ); entityBinding.setExplicitPolymorphism( "explicit".equals( xmlClass.getPolymorphism() ) );
@ -354,6 +355,8 @@ public class BindingCreator {
@SuppressWarnings( {"unchecked"}) @SuppressWarnings( {"unchecked"})
private void performBasicEntityBind(EntityBinding entityBinding, EntitySourceInformation entitySourceInfo) { private void performBasicEntityBind(EntityBinding entityBinding, EntitySourceInformation entitySourceInfo) {
bindPrimaryTable( entitySourceInfo, entityBinding );
entityBinding.setJpaEntityName( null ); entityBinding.setJpaEntityName( null );
final EntityElement entityElement = entitySourceInfo.getEntityElement(); final EntityElement entityElement = entitySourceInfo.getEntityElement();
@ -499,6 +502,77 @@ public class BindingCreator {
private Stack<TableSpecification> attributeColumnTableStack = new Stack<TableSpecification>(); private Stack<TableSpecification> attributeColumnTableStack = new Stack<TableSpecification>();
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) { 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 : we really need the notion of a Stack here for the table from which the columns come for binding these attributes.
// todo : adding the concept (interface) of a source of attribute metadata would allow reuse of this method for entity, component, unique-key, etc // todo : adding the concept (interface) of a source of attribute metadata would allow reuse of this method for entity, component, unique-key, etc
@ -601,39 +675,69 @@ public class BindingCreator {
} }
} }
private void bindProperty(XMLPropertyElement property, EntityBinding entityBinding) { private void bindProperty(final XMLPropertyElement property, EntityBinding entityBinding) {
SingularAttribute attr = entityBinding.getEntity().locateOrCreateSingularAttribute( property.getName() ); SimpleAttributeBinding attributeBinding = doBasicSimpleAttributeBindingCreation( property.getName(), property, entityBinding );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( attr );
resolveTypeInformation( property, attributeBinding );
attributeBinding.setInsertable( Helper.getBooleanValue( property.isInsert(), true ) ); 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.setGeneration( PropertyGeneration.parse( property.getGenerated() ) );
attributeBinding.setLazy( property.isLazy() ); attributeBinding.setLazy( property.isLazy() );
attributeBinding.setIncludedInOptimisticLocking( property.isOptimisticLock() ); 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 <id/> etc
SingularAttribute attribute = entityBinding.getEntity().locateOrCreateSingularAttribute( attributeName );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( attribute );
resolveTypeInformation( attributeSource, attributeBinding );
attributeBinding.setPropertyAccessorName( attributeBinding.setPropertyAccessorName(
Helper.getPropertyAccessorName( Helper.getPropertyAccessorName(
property.getAccess(), attributeSource.getAccess(),
false, false,
currentBindingContext.getMappingDefaults().getPropertyAccessorName() currentBindingContext.getMappingDefaults().getPropertyAccessorName()
) )
); );
attributeBinding.setMetaAttributeContext( attributeBinding.setMetaAttributeContext(
Helper.extractMetaAttributeContext( property.getMeta(), entityBinding.getMetaAttributeContext() ) Helper.extractMetaAttributeContext( attributeSource.getMeta(), entityBinding.getMetaAttributeContext() )
); );
// todo : implement. Is this meant to indicate the natural-id? return attributeBinding;
// attributeBinding.setAlternateUniqueKey( ... );
attributeBinding.setValue( makeValue( property, attributeBinding ) );
} }
private void resolveTypeInformation(XMLPropertyElement property, final SimpleAttributeBinding attributeBinding) { private void resolveTypeInformation(SingularAttributeSource property, final SimpleAttributeBinding attributeBinding) {
final Class<?> attributeJavaType = determineJavaType( attributeBinding.getAttribute() ); final Class<?> attributeJavaType = determineJavaType( attributeBinding.getAttribute() );
if ( attributeJavaType != null ) { if ( attributeJavaType != null ) {
attributeBinding.getHibernateTypeDescriptor().setJavaTypeName( attributeJavaType.getName() );
( (AbstractAttributeContainer.SingularAttributeImpl) attributeBinding.getAttribute() ).resolveType( ( (AbstractAttributeContainer.SingularAttributeImpl) attributeBinding.getAttribute() ).resolveType(
currentBindingContext.makeJavaType( attributeJavaType.getName() ) currentBindingContext.makeJavaType( attributeJavaType.getName() )
); );
@ -644,16 +748,16 @@ public class BindingCreator {
final String explicitTypeName = property.getTypeAttribute(); final String explicitTypeName = property.getTypeAttribute();
final TypeDef typeDef = currentBindingContext.getMetadataImplementor().getTypeDefinition( explicitTypeName ); final TypeDef typeDef = currentBindingContext.getMetadataImplementor().getTypeDefinition( explicitTypeName );
if ( typeDef != null ) { if ( typeDef != null ) {
attributeBinding.getHibernateTypeDescriptor().setTypeName( typeDef.getTypeClass() ); attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( typeDef.getTypeClass() );
attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( typeDef.getParameters() ); attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( typeDef.getParameters() );
} }
else { else {
attributeBinding.getHibernateTypeDescriptor().setTypeName( explicitTypeName ); attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( explicitTypeName );
} }
} }
else if ( property.getType() != null ) { else if ( property.getType() != null ) {
// todo : consider changing in-line type definitions to implicitly generate uniquely-named type-defs // 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() ) { for ( XMLParamElement xmlParamElement : property.getType().getParam() ) {
attributeBinding.getHibernateTypeDescriptor().getTypeParameters().put( attributeBinding.getHibernateTypeDescriptor().getTypeParameters().put(
xmlParamElement.getName(), xmlParamElement.getName(),
@ -662,29 +766,9 @@ public class BindingCreator {
} }
} }
else { else {
// see if we can reflect to determine the appropriate type if ( attributeJavaType == null ) {
try { // we will have problems later determining the Hibernate Type to use. Should we throw an
final String attributeName = attributeBinding.getAttribute().getName(); // exception now? Might be better to get better contextual info
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?
} }
} }
} }
@ -696,7 +780,7 @@ public class BindingCreator {
BeanInfoHelper.visitBeanInfo( ownerClass, delegate ); BeanInfoHelper.visitBeanInfo( ownerClass, delegate );
return delegate.javaType; return delegate.javaType;
} }
catch ( Exception e ) { catch ( Exception ignore ) {
// todo : log it? // todo : log it?
} }
return null; return null;
@ -721,42 +805,51 @@ public class BindingCreator {
} }
} }
private org.hibernate.metamodel.relational.Value makeValue( private static interface RelationValueMetadataSource {
XMLPropertyElement property, public String getColumnAttribute();
SimpleAttributeBinding attributeBinding) { 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. // 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. // There is a note about this somewhere else with ideas on the subject.
// For now, just use the entity's base table. // For now, just use the entity's base table.
final TableSpecification valueSource = attributeBinding.getEntityBinding().getBaseTable(); final TableSpecification valueSource = attributeBinding.getEntityBinding().getBaseTable();
if ( property.getColumn() != null && ! property.getColumn().isEmpty() ) { if ( StringHelper.isNotEmpty( relationValueMetadataSource.getColumnAttribute() ) ) {
if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) { if ( relationValueMetadataSource.getColumnOrFormulaElements() != null
&& ! relationValueMetadataSource.getColumnOrFormulaElements().isEmpty() ) {
throw new MappingException( throw new MappingException(
"column/formula attribute may not be used together with <column>/<formula> subelement", "column/formula attribute may not be used together with <column>/<formula> subelement",
currentBindingContext.getOrigin() currentBindingContext.getOrigin()
); );
} }
if ( property.getFormula() != null ) { if ( StringHelper.isNotEmpty( relationValueMetadataSource.getFormulaAttribute() ) ) {
throw new MappingException( throw new MappingException(
"column and formula attributes may not be used together", "column and formula attributes may not be used together",
currentBindingContext.getOrigin() currentBindingContext.getOrigin()
); );
} }
return valueSource.locateOrCreateColumn( property.getColumn() ); return valueSource.locateOrCreateColumn( relationValueMetadataSource.getColumnAttribute() );
} }
else if ( property.getFormula() != null && ! property.getFormula().isEmpty() ) { else if ( StringHelper.isNotEmpty( relationValueMetadataSource.getFormulaAttribute() ) ) {
if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) { if ( relationValueMetadataSource.getColumnOrFormulaElements() != null
&& ! relationValueMetadataSource.getColumnOrFormulaElements().isEmpty() ) {
throw new MappingException( throw new MappingException(
"column/formula attribute may not be used together with <column>/<formula> subelement", "column/formula attribute may not be used together with <column>/<formula> subelement",
currentBindingContext.getOrigin() 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<SimpleValue> values = new ArrayList<SimpleValue>(); List<SimpleValue> values = new ArrayList<SimpleValue>();
for ( Object columnOrFormula : property.getColumnOrFormula() ) { for ( Object columnOrFormula : relationValueMetadataSource.getColumnOrFormulaElements() ) {
final SimpleValue value; final SimpleValue value;
if ( XMLColumnElement.class.isInstance( columnOrFormula ) ) { if ( XMLColumnElement.class.isInstance( columnOrFormula ) ) {
final XMLColumnElement columnElement = (XMLColumnElement) columnOrFormula; final XMLColumnElement columnElement = (XMLColumnElement) columnOrFormula;
@ -781,9 +874,7 @@ public class BindingCreator {
value = column; value = column;
} }
else { else {
// todo : ??? Seems jaxb is not generating this class ?!?!?! value = valueSource.locateOrCreateDerivedValue( (String) columnOrFormula );
// final XMLFormulaElement formulaElement = (XMLFormulaElement) columnOrFormula;
value = null;
} }
if ( value != null ) { if ( value != null ) {
values.add( value ); values.add( value );
@ -810,25 +901,6 @@ public class BindingCreator {
.propertyToColumnName( attributeBinding.getAttribute().getName() ); .propertyToColumnName( attributeBinding.getAttribute().getName() );
return valueSource.locateOrCreateColumn( name ); 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) { private void makeManyToOneAttributeBinding(XMLManyToOneElement manyToOne, EntityBinding entityBinding) {

View File

@ -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();
}

View File

@ -78,7 +78,7 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt
else if ( id.getColumn() != null ) { else if ( id.getColumn() != null ) {
throw new MappingException( "column attribute may not be used together with <column> subelement" ); throw new MappingException( "column attribute may not be used together with <column> subelement" );
} }
this.hibernateTypeDescriptor.setTypeName( id.getTypeAttribute() ); this.hibernateTypeDescriptor.setExplicitTypeName( id.getTypeAttribute() );
} }
public HbmSimpleValueRelationalStateContainer( public HbmSimpleValueRelationalStateContainer(
@ -95,7 +95,11 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt
else if ( discriminator.getColumn() != null || discriminator.getFormula() != null) { else if ( discriminator.getColumn() != null || discriminator.getFormula() != null) {
throw new MappingException( "column/formula attribute may not be used together with <column>/<formula> subelement" ); throw new MappingException( "column/formula attribute may not be used together with <column>/<formula> subelement" );
} }
this.hibernateTypeDescriptor.setTypeName( discriminator.getType() == null ? "string" : discriminator.getType() ); this.hibernateTypeDescriptor.setExplicitTypeName(
discriminator.getType() == null ?
"string" :
discriminator.getType()
);
} }
public HbmSimpleValueRelationalStateContainer( public HbmSimpleValueRelationalStateContainer(
@ -112,7 +116,7 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt
else if ( version.getColumn() != null ) { else if ( version.getColumn() != null ) {
throw new MappingException( "column attribute may not be used together with <column> subelement" ); throw new MappingException( "column attribute may not be used together with <column> subelement" );
} }
this.hibernateTypeDescriptor.setTypeName( version.getType() == null ? "integer" : version.getType() ); this.hibernateTypeDescriptor.setExplicitTypeName( version.getType() == null ? "integer" : version.getType() );
} }
public HbmSimpleValueRelationalStateContainer( public HbmSimpleValueRelationalStateContainer(
@ -129,7 +133,11 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt
else if ( timestamp.getColumn() != null ) { else if ( timestamp.getColumn() != null ) {
throw new MappingException( "column attribute may not be used together with <column> subelement" ); throw new MappingException( "column attribute may not be used together with <column> subelement" );
} }
this.hibernateTypeDescriptor.setTypeName( "db".equals( timestamp.getSource() ) ? "dbtimestamp" : "timestamp" ); this.hibernateTypeDescriptor.setExplicitTypeName(
"db".equals( timestamp.getSource() ) ?
"dbtimestamp" :
"timestamp"
);
} }
public HbmSimpleValueRelationalStateContainer( public HbmSimpleValueRelationalStateContainer(
@ -146,7 +154,7 @@ public class HbmSimpleValueRelationalStateContainer implements TupleRelationalSt
else if ( property.getColumn() != null || property.getFormula() != null) { else if ( property.getColumn() != null || property.getFormula() != null) {
throw new MappingException( "column/formula attribute may not be used together with <column>/<formula> subelement" ); throw new MappingException( "column/formula attribute may not be used together with <column>/<formula> subelement" );
} }
this.hibernateTypeDescriptor.setTypeName( property.getTypeAttribute() ); this.hibernateTypeDescriptor.setExplicitTypeName( property.getTypeAttribute() );
} }
public HbmSimpleValueRelationalStateContainer( public HbmSimpleValueRelationalStateContainer(

View File

@ -29,10 +29,7 @@ import org.hibernate.MappingException;
import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.HibernateTypeDescriptor; import org.hibernate.metamodel.binding.HibernateTypeDescriptor;
import org.hibernate.metamodel.domain.AbstractAttributeContainer;
import org.hibernate.metamodel.domain.Attribute; 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.Datatype;
import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Value; import org.hibernate.metamodel.relational.Value;
@ -69,29 +66,29 @@ class AttributeTypeResolver {
} }
private Type resolveHibernateType(AttributeBinding attributeBinding) { private Type resolveHibernateType(AttributeBinding attributeBinding) {
if ( attributeBinding.getHibernateTypeDescriptor().getExplicitType() != null ) { if ( attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() != null ) {
return attributeBinding.getHibernateTypeDescriptor().getExplicitType(); // already resolved return attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(); // already resolved
} }
// this only works for "basic" attribute types // this only works for "basic" attribute types
HibernateTypeDescriptor typeDescriptor = attributeBinding.getHibernateTypeDescriptor(); 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: " + throw new MappingException( "Hibernate type name has not been defined for attribute: " +
getQualifiedAttributeName( attributeBinding ) getQualifiedAttributeName( attributeBinding )
); );
} }
Type type = null; Type type = null;
if ( typeDescriptor.getTypeName() != null ) { if ( typeDescriptor.getExplicitTypeName() != null ) {
Properties typeParameters = null; Properties typeParameters = null;
if ( typeDescriptor.getTypeParameters() != null ) { if ( typeDescriptor.getTypeParameters() != null ) {
typeParameters = new Properties(); typeParameters = new Properties();
typeParameters.putAll( typeDescriptor.getTypeParameters() ); typeParameters.putAll( typeDescriptor.getTypeParameters() );
} }
type = metadata.getTypeResolver().heuristicType( type = metadata.getTypeResolver().heuristicType(
typeDescriptor.getTypeName(), typeDescriptor.getExplicitTypeName(),
typeParameters typeParameters
); );
typeDescriptor.setExplicitType( type ); typeDescriptor.setResolvedTypeMapping( type );
} }
return type; return type;
} }

View File

@ -503,7 +503,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
.getEntityIdentifier() .getEntityIdentifier()
.getValueBinding() .getValueBinding()
.getHibernateTypeDescriptor() .getHibernateTypeDescriptor()
.getExplicitType(); .getResolvedTypeMapping();
} }
@Override @Override
@ -527,7 +527,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
if ( attributeBinding == null ) { if ( attributeBinding == null ) {
throw new MappingException( "unknown property: " + entityName + '.' + propertyName ); throw new MappingException( "unknown property: " + entityName + '.' + propertyName );
} }
return attributeBinding.getHibernateTypeDescriptor().getExplicitType(); return attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping();
} }
private class MappingDefaultsImpl implements MappingDefaults { private class MappingDefaultsImpl implements MappingDefaults {

View File

@ -97,7 +97,6 @@ import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.relational.DerivedValue; import org.hibernate.metamodel.relational.DerivedValue;
import org.hibernate.metamodel.relational.Identifier;
import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.pretty.MessageHelper; import org.hibernate.pretty.MessageHelper;
import org.hibernate.property.BackrefPropertyAccessor; import org.hibernate.property.BackrefPropertyAccessor;
@ -904,7 +903,7 @@ public abstract class AbstractEntityPersister
lazyProperties.add( prop.getAttribute().getName() ); lazyProperties.add( prop.getAttribute().getName() );
lazyNames.add( prop.getAttribute().getName() ); lazyNames.add( prop.getAttribute().getName() );
lazyNumbers.add( i ); lazyNumbers.add( i );
lazyTypes.add( prop.getHibernateTypeDescriptor().getExplicitType()); lazyTypes.add( prop.getHibernateTypeDescriptor().getResolvedTypeMapping());
lazyColAliases.add( colAliases ); lazyColAliases.add( colAliases );
} }

View File

@ -29,7 +29,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
@ -586,7 +586,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
.getEntityDiscriminator() .getEntityDiscriminator()
.getValueBinding() .getValueBinding()
.getHibernateTypeDescriptor() .getHibernateTypeDescriptor()
.getExplicitType(); .getResolvedTypeMapping();
if ( entityBinding.getDiscriminatorValue() == null ) { if ( entityBinding.getDiscriminatorValue() == null ) {
discriminatorValue = NULL_DISCRIMINATOR; discriminatorValue = NULL_DISCRIMINATOR;
discriminatorSQLValue = InFragment.NULL; discriminatorSQLValue = InFragment.NULL;

View File

@ -37,7 +37,6 @@ import org.hibernate.mapping.Property;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.EntityIdentifier;
import org.hibernate.metamodel.binding.PluralAttributeBinding; import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.SimpleAttributeBinding; import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.property.Getter; 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? // TODO: the following will cause an NPE with "virtual" IDs; how should they be set?
final String mappedUnsavedValue = property.getUnsavedValue(); final String mappedUnsavedValue = property.getUnsavedValue();
final Type type = property.getHibernateTypeDescriptor().getExplicitType(); final Type type = property.getHibernateTypeDescriptor().getResolvedTypeMapping();
IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue( IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue(
mappedUnsavedValue, mappedUnsavedValue,
@ -193,7 +192,7 @@ public class PropertyFactory {
VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue( VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
mappedUnsavedValue, mappedUnsavedValue,
getGetter( property ), getGetter( property ),
( VersionType ) property.getHibernateTypeDescriptor().getExplicitType(), ( VersionType ) property.getHibernateTypeDescriptor().getResolvedTypeMapping(),
getConstructor( property.getEntityBinding() ) getConstructor( property.getEntityBinding() )
); );
@ -202,7 +201,7 @@ public class PropertyFactory {
return new VersionProperty( return new VersionProperty(
property.getAttribute().getName(), property.getAttribute().getName(),
null, null,
property.getHibernateTypeDescriptor().getExplicitType(), property.getHibernateTypeDescriptor().getResolvedTypeMapping(),
lazy, lazy,
property.isInsertable(), property.isInsertable(),
property.isUpdatable(), property.isUpdatable(),
@ -267,7 +266,7 @@ public class PropertyFactory {
*/ */
public static StandardProperty buildStandardProperty(AttributeBinding property, boolean lazyAvailable) { 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 // we need to dirty check collections, since they can cause an owner
// version number increment // version number increment

View File

@ -328,7 +328,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
.getEntityIdentifier() .getEntityIdentifier()
.getValueBinding() .getValueBinding()
.getHibernateTypeDescriptor() .getHibernateTypeDescriptor()
.getExplicitType() : .getResolvedTypeMapping() :
null null
); );
} }

View File

@ -17,7 +17,7 @@
</jaxb:nameXmlTransform> </jaxb:nameXmlTransform>
</jaxb:schemaBindings> </jaxb:schemaBindings>
<!-- Inheritance --> <!-- Mix-ins -->
<jaxb:bindings node="//xsd:element[@name='class']/xsd:complexType"> <jaxb:bindings node="//xsd:element[@name='class']/xsd:complexType">
<inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement</inheritance:implements> <inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement</inheritance:implements>
<inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.JoinElementSource</inheritance:implements> <inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.JoinElementSource</inheritance:implements>
@ -45,6 +45,21 @@
<inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.CustomSqlElement</inheritance:implements> <inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.CustomSqlElement</inheritance:implements>
</jaxb:bindings> </jaxb:bindings>
<jaxb:bindings node="//xsd:complexType[@name='property-element']">
<inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.SingularAttributeSource</inheritance:implements>
</jaxb:bindings>
<jaxb:bindings node="//xsd:element[@name='id']/xsd:complexType">
<inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.SingularAttributeSource</inheritance:implements>
</jaxb:bindings>
<!--
<jaxb:bindings node="//xsd:element[@name='version']/xsd:complexType">
<inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.SingularAttributeSource</inheritance:implements>
</jaxb:bindings>
<jaxb:bindings node="//xsd:element[@name='timestamp']/xsd:complexType">
<inheritance:implements>org.hibernate.metamodel.source.hbm.jaxb.mapping.SingularAttributeSource</inheritance:implements>
</jaxb:bindings>
-->
<jaxb:bindings node="//xsd:element[@name='class']//xsd:attribute[@name='subselect']"> <jaxb:bindings node="//xsd:element[@name='class']//xsd:attribute[@name='subselect']">
<jaxb:property name="subselectAttribute"/> <jaxb:property name="subselectAttribute"/>
</jaxb:bindings> </jaxb:bindings>

View File

@ -36,7 +36,6 @@ import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.source.internal.MetadataImpl; import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.hibernate.metamodel.domain.BasicType; import org.hibernate.metamodel.domain.BasicType;
import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.domain.TypeNature;
import org.hibernate.metamodel.relational.Column; import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Datatype; import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.relational.SimpleValue;
@ -137,7 +136,7 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" ); AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" );
assertNotNull( idAttributeBinding ); assertNotNull( idAttributeBinding );
assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() ); assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() );
assertSame( LongType.INSTANCE, idAttributeBinding.getHibernateTypeDescriptor().getExplicitType() ); assertSame( LongType.INSTANCE, idAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() );
assertTrue( idAttributeBinding.getAttribute().isSingular() ); assertTrue( idAttributeBinding.getAttribute().isSingular() );
assertNotNull( idAttributeBinding.getAttribute() ); assertNotNull( idAttributeBinding.getAttribute() );
@ -154,7 +153,7 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" ); AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" );
assertNotNull( nameBinding ); assertNotNull( nameBinding );
assertSame( StringType.INSTANCE, nameBinding.getHibernateTypeDescriptor().getExplicitType() ); assertSame( StringType.INSTANCE, nameBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() );
assertNotNull( nameBinding.getAttribute() ); assertNotNull( nameBinding.getAttribute() );
assertNotNull( nameBinding.getValue() ); assertNotNull( nameBinding.getValue() );

View File

@ -62,7 +62,7 @@ public class SimpleValueBindingTests extends BaseUnitTestCase {
SingularAttribute idAttribute = entity.locateOrCreateSingularAttribute( "id" ); SingularAttribute idAttribute = entity.locateOrCreateSingularAttribute( "id" );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute ); SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute );
attributeBinding.getHibernateTypeDescriptor().setTypeName( "long" ); attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( "long" );
assertSame( idAttribute, attributeBinding.getAttribute() ); assertSame( idAttribute, attributeBinding.getAttribute() );
entityBinding.getEntityIdentifier().setValueBinding( attributeBinding ); entityBinding.getEntityIdentifier().setValueBinding( attributeBinding );