diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java
index 6a84daea5897..980b25b91172 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java
@@ -238,9 +238,9 @@ private void processIdentifierGenerators(MetadataSourceProcessor[] metadataSourc
}
private void processMappings(MetadataSourceProcessor[] metadataSourceProcessors) {
- final Binder binder = new Binder( this );
+ final Binder binder = new Binder( this, identifierGeneratorFactory );
for ( MetadataSourceProcessor processor : metadataSourceProcessors )
- binder.processEntityHierarchies( processor.extractEntityHierarchies() );
+ binder.bindEntities( processor.extractEntityHierarchies() );
}
private void bindMappingDependentMetadata(MetadataSourceProcessor[] metadataSourceProcessors) {
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/Binder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/Binder.java
index f993463506e7..741c00866e9b 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/Binder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/Binder.java
@@ -23,17 +23,13 @@
*/
package org.hibernate.metamodel.internal.source;
-import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-
-import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.TruthValue;
import org.hibernate.cfg.AvailableSettings;
@@ -42,8 +38,9 @@
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.id.factory.IdentifierGeneratorFactory;
+import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
-import org.hibernate.metamodel.internal.source.hbm.Helper;
import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.AttributeBindingContainer;
@@ -52,6 +49,8 @@
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.EntityDiscriminator;
+import org.hibernate.metamodel.spi.binding.EntityVersion;
+import org.hibernate.metamodel.spi.binding.HibernateTypeDescriptor;
import org.hibernate.metamodel.spi.binding.IdGenerator;
import org.hibernate.metamodel.spi.binding.InheritanceType;
import org.hibernate.metamodel.spi.binding.ManyToOneAttributeBinding;
@@ -60,18 +59,19 @@
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.binding.SecondaryTable;
import org.hibernate.metamodel.spi.binding.SetBinding;
-import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
+import org.hibernate.metamodel.spi.binding.TypeDefinition;
import org.hibernate.metamodel.spi.domain.Attribute;
import org.hibernate.metamodel.spi.domain.Composite;
import org.hibernate.metamodel.spi.domain.Entity;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.domain.SingularAttribute;
+import org.hibernate.metamodel.spi.relational.AbstractValue;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.DerivedValue;
import org.hibernate.metamodel.spi.relational.ForeignKey;
import org.hibernate.metamodel.spi.relational.Identifier;
-import org.hibernate.metamodel.spi.relational.InLineView;
+import org.hibernate.metamodel.spi.relational.JdbcDataType;
import org.hibernate.metamodel.spi.relational.PrimaryKey;
import org.hibernate.metamodel.spi.relational.Schema;
import org.hibernate.metamodel.spi.relational.Table;
@@ -81,7 +81,6 @@
import org.hibernate.metamodel.spi.source.AttributeSource;
import org.hibernate.metamodel.spi.source.AttributeSourceContainer;
import org.hibernate.metamodel.spi.source.BasicPluralAttributeElementSource;
-import org.hibernate.metamodel.spi.source.ColumnBindingDefaults;
import org.hibernate.metamodel.spi.source.ColumnSource;
import org.hibernate.metamodel.spi.source.ComponentAttributeSource;
import org.hibernate.metamodel.spi.source.ConstraintSource;
@@ -89,8 +88,12 @@
import org.hibernate.metamodel.spi.source.DiscriminatorSource;
import org.hibernate.metamodel.spi.source.EntityHierarchy;
import org.hibernate.metamodel.spi.source.EntitySource;
+import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
+import org.hibernate.metamodel.spi.source.IdentifierSource;
+import org.hibernate.metamodel.spi.source.IdentifierSource.Nature;
import org.hibernate.metamodel.spi.source.InLineViewSource;
import org.hibernate.metamodel.spi.source.LocalBindingContext;
+import org.hibernate.metamodel.spi.source.MappingDefaults;
import org.hibernate.metamodel.spi.source.MappingException;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
import org.hibernate.metamodel.spi.source.MetaAttributeSource;
@@ -109,7 +112,6 @@
import org.hibernate.metamodel.spi.source.SingularAttributeNature;
import org.hibernate.metamodel.spi.source.SingularAttributeSource;
import org.hibernate.metamodel.spi.source.Sortable;
-import org.hibernate.metamodel.spi.source.SubclassEntityContainer;
import org.hibernate.metamodel.spi.source.SubclassEntitySource;
import org.hibernate.metamodel.spi.source.TableSource;
import org.hibernate.metamodel.spi.source.TableSpecificationSource;
@@ -125,1590 +127,1106 @@
/**
* The common binder shared between annotations and {@code hbm.xml} processing.
*
- * The API consists of {@link #Binder( MetadataImplementor )} and {@link #processEntityHierarchies(Iterable)}
- *
- * @todo Really need to chop this up. The class is doing so many different things right now.
- * @todo And really need to come up with consistent method naming.
- * @todo This class really should live in the o.h.metamodel.internal package
+ * The API consists of {@link #Binder(MetadataImplementor, IdentifierGeneratorFactory)} and {@link #bindEntities(Iterable)}
*
* @author Steve Ebersole
* @author Hardy Ferentschik
* @author Gail Badner
*/
+// todo: move to parent package
+// todo: chase unresolved attribute references
public class Binder {
+
private final MetadataImplementor metadata;
- private final ArrayList processedEntityNames = new ArrayList();
+ private final IdentifierGeneratorFactory identifierGeneratorFactory;
+ private final ObjectNameNormalizer nameNormalizer;
+ private final HashMap< String, EntitySource > entitySourcesByName = new HashMap< String, EntitySource >();
+ private final HashMap< RootEntitySource, EntityHierarchy > entityHierarchiesByRootEntitySource =
+ new HashMap< RootEntitySource, EntityHierarchy >();
+ private final HashMap< String, AttributeSource > attributeSourcesByName = new HashMap< String, AttributeSource >();
+ private final LinkedList< LocalBindingContext > bindingContexts = new LinkedList< LocalBindingContext >();
+ private final LinkedList< InheritanceType > inheritanceTypes = new LinkedList< InheritanceType >();
+ private final LinkedList< EntityMode > entityModes = new LinkedList< EntityMode >();
+
+ private final HibernateTypeHelper typeHelper; // todo: refactor helper and remove redundant methods in this class
+
+ public Binder( final MetadataImplementor metadata,
+ final IdentifierGeneratorFactory identifierGeneratorFactory ) {
+ this.metadata = metadata;
+ this.identifierGeneratorFactory = identifierGeneratorFactory;
+ nameNormalizer = new ObjectNameNormalizer() {
- private HibernateTypeHelper typeHelper = new HibernateTypeHelper( this );
+ @Override
+ protected NamingStrategy getNamingStrategy() {
+ return metadata.getNamingStrategy();
+ }
- private final ObjectNameNormalizer NAME_NORMALIZER = new ObjectNameNormalizer() {
- @Override
- protected boolean isUseQuotedIdentifiersGlobally() {
- return metadata.isGloballyQuotedIdentifiers();
- }
+ @Override
+ protected boolean isUseQuotedIdentifiersGlobally() {
+ return metadata.isGloballyQuotedIdentifiers();
+ }
+ };
+ typeHelper = new HibernateTypeHelper( this, metadata );
+ }
- @Override
- protected NamingStrategy getNamingStrategy() {
- return metadata.getNamingStrategy();
+ private AttributeBinding bindAttribute( final AttributeBindingContainer attributeBindingContainer,
+ final AttributeSource attributeSource ) {
+ // Return existing binding if available
+ final String attributeName = attributeSource.getName();
+ System.out.println( "bindAttribute( " + attributeBindingContainer.getAttributeContainer().getName() + ", "
+ + attributeSource.getName() + " )" );
+ final AttributeBinding attributeBinding = attributeBindingContainer.locateAttributeBinding( attributeName );
+ if ( attributeBinding != null ) {
+ return attributeBinding;
}
- };
-
- private InheritanceType currentInheritanceType;
- private EntityMode currentHierarchyEntityMode;
- private LocalBindingContext currentBindingContext;
- private HashMap sourcesByName = new HashMap();
-
- public Binder( MetadataImplementor metadata ) {
- this.metadata = metadata;
+ if ( attributeSource.isSingular() ) {
+ return bindSingularAttribute( attributeBindingContainer, ( SingularAttributeSource ) attributeSource );
+ }
+ return bindPluralAttribute( attributeBindingContainer, ( PluralAttributeSource ) attributeSource );
}
- MetadataImplementor getMetadata() {
- return metadata;
+ private void bindAttributes( final AttributeBindingContainer attributeBindingContainer,
+ final AttributeSourceContainer attributeSourceContainer ) {
+ System.out.println( "bindAttributes( " + attributeBindingContainer.getAttributeContainer().getName() + " )" );
+ for ( final AttributeSource attributeSource : attributeSourceContainer.attributeSources() ) {
+ bindAttribute( attributeBindingContainer, attributeSource );
+ }
}
- LocalBindingContext getCurrentBindingContext() {
- return currentBindingContext;
+ private AbstractPluralAttributeBinding bindBagAttribute( final AttributeBindingContainer attributeBindingContainer,
+ final PluralAttributeSource attributeSource,
+ PluralAttribute attribute ) {
+ if ( attribute == null ) {
+ attribute = attributeBindingContainer.getAttributeContainer().createBag( attributeSource.getName() );
+ }
+ return attributeBindingContainer.makeBagAttributeBinding( attribute,
+ pluralAttributeElementNature( attributeSource ),
+ pluralAttributeKeyBinding( attributeBindingContainer,
+ attributeSource ),
+ propertyAccessorName( attributeSource ),
+ attributeSource.isIncludedInOptimisticLocking(),
+ false,
+ createMetaAttributeContext( attributeBindingContainer,
+ attributeSource ) );
}
- /**
- * Process an entity hierarchy.
- *
- * @param entityHierarchies THe hierarchies to process.
- */
- public void processEntityHierarchies( Iterable extends EntityHierarchy> entityHierarchies ) {
- // Index sources by name so we can find and resolve entities on the fly as references to them
- // are encountered (e.g., within associations)
- for ( EntityHierarchy hierarchy : entityHierarchies ) {
- mapSourcesByName( hierarchy.getRootEntitySource() );
- }
-
- for ( EntityHierarchy hierarchy : entityHierarchies ) {
- processEntityHierarchy( hierarchy );
- }
- }
+ private BasicAttributeBinding bindBasicAttribute( final AttributeBindingContainer attributeBindingContainer,
+ final SingularAttributeSource attributeSource,
+ SingularAttribute attribute ) {
- private void mapSourcesByName(EntitySource source) {
- sourcesByName.put( source.getEntityName(), source );
- for ( SubclassEntitySource subclassEntitySource : source.subclassEntitySources() ) {
- mapSourcesByName( subclassEntitySource );
- }
+ System.out.println( "bindBasicAttribute( " + attributeBindingContainer.getAttributeContainer().getName() + ", "
+ + attributeSource.getName() + " )" );
+ if ( attribute == null ) {
+ attribute = createSingularAttribute( attributeBindingContainer, attributeSource );
+ }
+ final List< RelationalValueBinding > relationalValueBindings =
+ bindValues( attributeBindingContainer,
+ attributeSource,
+ attribute,
+ attributeBindingContainer.seekEntityBinding().getPrimaryTable() );
+ final BasicAttributeBinding attributeBinding =
+ attributeBindingContainer.makeBasicAttributeBinding( attribute,
+ relationalValueBindings,
+ propertyAccessorName( attributeSource ),
+ attributeSource.isIncludedInOptimisticLocking(),
+ attributeSource.isLazy(),
+ createMetaAttributeContext( attributeBindingContainer,
+ attributeSource ),
+ attributeSource.getGeneration() );
+ bindHibernateTypeDescriptor( attributeBinding.getHibernateTypeDescriptor(),
+ attributeSource.getTypeInformation(),
+ attributeBinding.getAttribute(),
+ ( AbstractValue ) relationalValueBindings.get( 0 ).getValue() );
+ final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor();
+ attributeBinding.getAttribute().resolveType( bindingContexts.peek().
+ makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) );
+ return attributeBinding;
}
- @SuppressWarnings( {"unchecked"})
- private void processEntityHierarchy(EntityHierarchy hierarchy) {
- final RootEntitySource rootEntitySource = hierarchy.getRootEntitySource();
- currentInheritanceType = hierarchy.getHierarchyInheritanceType();
- currentHierarchyEntityMode = rootEntitySource.getEntityMode();
- try {
- // create the binding
- final EntityBinding rootEntityBinding = createEntityBinding( rootEntitySource, null );
-
- // Create identifier generator for root entity
- Properties properties = new Properties();
- properties.putAll( metadata.getServiceRegistry().getService( ConfigurationService.class ).getSettings() );
- if ( !properties.contains( AvailableSettings.PREFER_POOLED_VALUES_LO ) ) {
- properties.put( AvailableSettings.PREFER_POOLED_VALUES_LO, "false" );
- }
- if ( !properties.contains( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER ) ) {
- properties.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, NAME_NORMALIZER );
- }
- rootEntityBinding.getHierarchyDetails()
- .getEntityIdentifier()
- .createIdentifierGenerator( metadata.getIdentifierGeneratorFactory(), properties );
+ private void bindBasicElementSetTablePrimaryKey( final SetBinding attributeBinding ) {
- if ( currentInheritanceType != InheritanceType.NO_INHERITANCE ) {
- processHierarchySubEntities( rootEntitySource, rootEntityBinding );
+ final PrimaryKey primaryKey = attributeBinding.getCollectionTable().getPrimaryKey();
+ final ForeignKey foreignKey = attributeBinding.getPluralAttributeKeyBinding().getForeignKey();
+ final BasicPluralAttributeElementBinding elementBinding =
+ ( BasicPluralAttributeElementBinding ) attributeBinding.getPluralAttributeElementBinding();
+ if ( elementBinding.getPluralAttributeElementNature() != PluralAttributeElementNature.BASIC ) {
+ throw new MappingException(
+ String.format( "Expected a SetBinding with an element of nature PluralAttributeElementNature.BASIC; instead was %s",
+ elementBinding.getPluralAttributeElementNature() ),
+ bindingContexts.peek().getOrigin() );
+ }
+ for ( final Column foreignKeyColumn : foreignKey.getSourceColumns() ) {
+ primaryKey.addColumn( foreignKeyColumn );
+ }
+ for ( final RelationalValueBinding elementValueBinding : elementBinding.getRelationalValueBindings() ) {
+ if ( elementValueBinding.getValue() instanceof Column && !elementValueBinding.isNullable() ) {
+ primaryKey.addColumn( ( Column ) elementValueBinding.getValue() );
}
}
- finally {
- currentHierarchyEntityMode = null;
- currentInheritanceType = null;
+ if ( primaryKey.getColumnSpan() == foreignKey.getColumnSpan() ) {
+ // for backward compatibility, allow a set with no not-null
+ // element columns, using all columns in the row locater SQL
+ // todo: create an implicit not null constraint on all cols?
}
}
- private void processHierarchySubEntities(
- SubclassEntityContainer subclassEntitySource,
- EntityBinding superEntityBinding) {
- for ( SubclassEntitySource subEntity : subclassEntitySource.subclassEntitySources() ) {
- // create the current entity's binding....
- final EntityBinding entityBinding = createEntityBinding( subEntity, superEntityBinding );
- // then drill down into its sub-class entities
- processHierarchySubEntities( subEntity, entityBinding );
- }
+ private void bindBasicPluralElementRelationalValues( final RelationalValueSourceContainer relationalValueSourceContainer,
+ final BasicPluralAttributeElementBinding elementBinding ) {
+ elementBinding.setRelationalValueBindings( bindValues( elementBinding.getPluralAttributeBinding().getContainer(),
+ relationalValueSourceContainer,
+ elementBinding.getPluralAttributeBinding().getAttribute(),
+ elementBinding.getPluralAttributeBinding().getCollectionTable() ) );
}
-
- // Entities ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- private EntityBinding createEntityBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
- if ( processedEntityNames.contains( entitySource.getEntityName() ) ) {
- return metadata.getEntityBinding( entitySource.getEntityName() );
+ private void bindCollectionElement( final AbstractPluralAttributeBinding attributeBinding,
+ final PluralAttributeSource attributeSource ) {
+ final PluralAttributeElementSource elementSource = attributeSource.getElementSource();
+ if ( elementSource.getNature() == org.hibernate.metamodel.spi.source.PluralAttributeElementNature.BASIC ) {
+ final BasicPluralAttributeElementSource basicElementSource = ( BasicPluralAttributeElementSource ) elementSource;
+ final BasicPluralAttributeElementBinding basicCollectionElement =
+ ( BasicPluralAttributeElementBinding ) attributeBinding.getPluralAttributeElementBinding();
+ bindBasicPluralElementRelationalValues( basicElementSource, basicCollectionElement );
+ return;
}
+ // todo : handle cascades
+ // final Cascadeable cascadeable = (Cascadeable) binding.getPluralAttributeElementBinding();
+ // cascadeable.setCascadeStyles( source.getCascadeStyles() );
+ // todo : implement
+ throw new NotYetImplementedException( String.format( "Support for collection elements of type %s not yet implemented",
+ elementSource.getNature() ) );
+ }
- currentBindingContext = entitySource.getLocalBindingContext();
- try {
- final EntityBinding entityBinding = doCreateEntityBinding( entitySource, superEntityBinding );
-
- metadata.addEntity( entityBinding );
- processedEntityNames.add( entityBinding.getEntity().getName() );
-
- processFetchProfiles( entitySource, entityBinding );
-
- return entityBinding;
- }
- finally {
- currentBindingContext = null;
+ private void bindCollectionIndex( final AbstractPluralAttributeBinding attributeBinding,
+ final PluralAttributeSource attributeSource ) {
+ if ( attributeSource.getPluralAttributeNature() != PluralAttributeNature.LIST
+ && attributeSource.getPluralAttributeNature() != PluralAttributeNature.MAP ) {
+ return;
}
+ // todo : implement
+ throw new NotYetImplementedException();
}
- private EntityBinding doCreateEntityBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
- final EntityBinding entityBinding = createBasicEntityBinding( entitySource, superEntityBinding );
-
- bindSecondaryTables( entitySource, entityBinding );
-
- Deque tableStack = new ArrayDeque( );
- tableStack.add( entityBinding.getPrimaryTable() );
- bindAttributes( entitySource, entityBinding, tableStack );
-
- bindTableUniqueConstraints( entitySource, entityBinding );
-
- return entityBinding;
+ private void bindCollectionKey( final AbstractPluralAttributeBinding attributeBinding,
+ final PluralAttributeSource attributeSource ) {
+ final PluralAttributeKeySource keySource = attributeSource.getKeySource();
+ final String foreignKeyName =
+ StringHelper.isEmpty( keySource.getExplicitForeignKeyName() )
+ ? null // todo: is null FK name allowed (is there a default?)
+ : quotedIdentifier( keySource.getExplicitForeignKeyName() );
+ final TableSpecification table = attributeBinding.getContainer().seekEntityBinding().getPrimaryTable();
+ attributeBinding.getPluralAttributeKeyBinding().prepareForeignKey( foreignKeyName, table );
+ attributeBinding.getPluralAttributeKeyBinding().getForeignKey().setDeleteRule( keySource.getOnDeleteAction() );
+ if ( keySource.getReferencedEntityAttributeName() == null ) {
+ bindCollectionKeyTargetingPrimaryKey( attributeBinding, attributeSource.getKeySource() );
+ } else {
+ bindCollectionKeyTargetingPropertyRef( attributeBinding, attributeSource.getKeySource() );
+ }
}
- private EntityBinding createBasicEntityBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
- if ( superEntityBinding == null ) {
- return makeRootEntityBinding( (RootEntitySource) entitySource );
- }
- else {
- switch ( currentInheritanceType ) {
- case SINGLE_TABLE:
- return makeDiscriminatedSubclassBinding( (SubclassEntitySource) entitySource, superEntityBinding );
- case JOINED:
- return makeJoinedSubclassBinding( (SubclassEntitySource) entitySource, superEntityBinding );
- case TABLE_PER_CLASS:
- return makeUnionedSubclassBinding( (SubclassEntitySource) entitySource, superEntityBinding );
- default:
- // extreme internal error!
- throw new AssertionFailure( "Internal condition failure" );
+ private void bindCollectionKeyTargetingPrimaryKey( final AbstractPluralAttributeBinding attributeBinding,
+ final PluralAttributeKeySource keySource ) {
+ for ( final RelationalValueSource valueSource : keySource.getValueSources() ) {
+ if ( valueSource instanceof ColumnSource ) {
+ final Column column = createColumn( attributeBinding.getCollectionTable(),
+ ( ColumnSource ) valueSource,
+ attributeBinding.getAttribute().getName(),
+ false,
+ true );
+ attributeBinding.getPluralAttributeKeyBinding().getForeignKey().addColumn( column );
+ } else {
+ // todo: deal with formulas???
}
}
}
- private EntityBinding makeRootEntityBinding(RootEntitySource entitySource) {
- final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, null );
-
- bindPrimaryTable( entitySource, entityBinding );
-
- bindIdentifier( entitySource, entityBinding );
- bindVersion( entityBinding, entitySource );
- bindDiscriminator( entitySource, entityBinding );
-
- entityBinding.getHierarchyDetails().setCaching( entitySource.getCaching() );
- entityBinding.getHierarchyDetails().setExplicitPolymorphism( entitySource.isExplicitPolymorphism() );
- entityBinding.getHierarchyDetails().setOptimisticLockStyle( entitySource.getOptimisticLockStyle() );
-
- entityBinding.setMutable( entitySource.isMutable() );
- entityBinding.setWhereFilter( entitySource.getWhere() );
- entityBinding.setRowId( entitySource.getRowId() );
-
- return entityBinding;
- }
-
- private EntityBinding buildBasicEntityBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
- final EntityBinding entityBinding = superEntityBinding == null
- ? new EntityBinding( currentInheritanceType, currentHierarchyEntityMode )
- : new EntityBinding( superEntityBinding );
-
- final String entityName = entitySource.getEntityName();
- final String className = currentHierarchyEntityMode == EntityMode.POJO ? entitySource.getClassName() : null;
-
- final Entity entity = new Entity(
- entityName,
- className,
- currentBindingContext.makeClassReference( className ),
- superEntityBinding == null ? null : superEntityBinding.getEntity()
- );
- entityBinding.setEntity( entity );
-
- entityBinding.setJpaEntityName( entitySource.getJpaEntityName() );
-
- if ( currentHierarchyEntityMode == EntityMode.POJO ) {
- final String proxy = entitySource.getProxy();
- if ( proxy != null ) {
- entityBinding.setProxyInterfaceType(
- currentBindingContext.makeClassReference(
- currentBindingContext.qualifyClassName( proxy )
- )
- );
- entityBinding.setLazy( true );
+ private void bindCollectionKeyTargetingPropertyRef( final AbstractPluralAttributeBinding attributeBinding,
+ final PluralAttributeKeySource keySource ) {
+ final EntityBinding ownerEntityBinding = attributeBinding.getContainer().seekEntityBinding();
+ final AttributeBinding referencedAttributeBinding = ownerEntityBinding.locateAttributeBinding(
+ keySource.getReferencedEntityAttributeName()
+ );
+ final ForeignKey foreignKey = attributeBinding.getPluralAttributeKeyBinding().getForeignKey();
+ if ( !referencedAttributeBinding.getAttribute().isSingular() ) {
+ throw new MappingException(
+ String.format( "Collection (%s) property-ref is a plural attribute (%s); must be singular.",
+ attributeBinding.getAttribute().getRole(),
+ referencedAttributeBinding ),
+ bindingContexts.peek().getOrigin() );
+ }
+ final Iterator< RelationalValueBinding > targetValueBindings =
+ ( ( SingularAttributeBinding ) referencedAttributeBinding ).getRelationalValueBindings().iterator();
+ for ( final RelationalValueSource valueSource : keySource.getValueSources() ) {
+ if ( !targetValueBindings.hasNext() ) {
+ throw new MappingException(
+ String.format( "More collection key source columns than target columns for collection: %s",
+ attributeBinding.getAttribute().getRole() ),
+ bindingContexts.peek().getOrigin() );
}
- else if ( entitySource.isLazy() ) {
- entityBinding.setProxyInterfaceType( entityBinding.getEntity().getClassReferenceUnresolved() );
- entityBinding.setLazy( true );
+ final Value targetValue = targetValueBindings.next().getValue();
+ if ( ColumnSource.class.isInstance( valueSource ) ) {
+ final ColumnSource columnSource = ( ColumnSource ) valueSource;
+ final Column column = createColumn( attributeBinding.getCollectionTable(),
+ columnSource,
+ attributeBinding.getAttribute().getName(),
+ false,
+ true );
+ if ( targetValue != null && !( targetValue instanceof Column ) ) {
+ throw new MappingException(
+ String.format( "Type mismatch between collection key source and target; collection: %s; source column (%s) corresponds with target derived value (%s).",
+ attributeBinding.getAttribute().getRole(),
+ columnSource.getName(),
+ ( ( DerivedValue ) targetValue ).getExpression() ),
+ bindingContexts.peek().getOrigin() );
+ }
+ foreignKey.addColumnMapping( column, ( Column ) targetValue );
+ } else {
+ // todo: deal with formulas???
}
}
- else {
- entityBinding.setProxyInterfaceType( null );
- entityBinding.setLazy( entitySource.isLazy() );
- }
-
- final String customTuplizerClassName = entitySource.getCustomTuplizerClassName();
- if ( customTuplizerClassName != null ) {
- entityBinding.setCustomEntityTuplizerClass(
- currentBindingContext.locateClassByName(
- customTuplizerClassName
- )
- );
- }
-
- final String customPersisterClassName = entitySource.getCustomPersisterClassName();
- if ( customPersisterClassName != null ) {
- entityBinding.setCustomEntityPersisterClass(
- currentBindingContext.locateClassByName(
- customPersisterClassName
- )
- );
- }
-
- entityBinding.setMetaAttributeContext( buildMetaAttributeContext( entitySource ) );
-
- entityBinding.setDynamicUpdate( entitySource.isDynamicUpdate() );
- entityBinding.setDynamicInsert( entitySource.isDynamicInsert() );
- entityBinding.setBatchSize( entitySource.getBatchSize() );
- entityBinding.setSelectBeforeUpdate( entitySource.isSelectBeforeUpdate() );
- entityBinding.setAbstract( entitySource.isAbstract() );
-
- entityBinding.setCustomLoaderName( entitySource.getCustomLoaderName() );
- entityBinding.setCustomInsert( entitySource.getCustomSqlInsert() );
- entityBinding.setCustomUpdate( entitySource.getCustomSqlUpdate() );
- entityBinding.setCustomDelete( entitySource.getCustomSqlDelete() );
-
- if ( entitySource.getSynchronizedTableNames() != null ) {
- entityBinding.addSynchronizedTableNames( entitySource.getSynchronizedTableNames() );
+ if ( targetValueBindings != null && targetValueBindings.hasNext() ) {
+ throw new MappingException( String.format( "More collection key target columns than source columns for collection: %s",
+ attributeBinding.getAttribute().getRole() ),
+ bindingContexts.peek().getOrigin() );
}
-
- entityBinding.setJpaCallbackClasses(entitySource.getJpaCallbackClasses());
-
- return entityBinding;
}
- private EntityBinding makeDiscriminatedSubclassBinding(SubclassEntitySource entitySource, EntityBinding superEntityBinding) {
- final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, superEntityBinding );
-
- entityBinding.setPrimaryTable( superEntityBinding.getPrimaryTable() );
- entityBinding.setPrimaryTableName( superEntityBinding.getPrimaryTableName() );
- bindDiscriminatorValue( entitySource, entityBinding );
-
- return entityBinding;
- }
-
- private EntityBinding makeJoinedSubclassBinding(SubclassEntitySource entitySource, EntityBinding superEntityBinding) {
- final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, superEntityBinding );
-
- bindPrimaryTable( entitySource, entityBinding );
-
- // todo : join
-
- return entityBinding;
- }
-
- private EntityBinding makeUnionedSubclassBinding(SubclassEntitySource entitySource, EntityBinding superEntityBinding) {
- final EntityBinding entityBinding = buildBasicEntityBinding( entitySource, superEntityBinding );
-
- bindPrimaryTable( entitySource, entityBinding );
-
- // todo : ??
-
- return entityBinding;
- }
-
- // Attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- private void bindIdentifier(RootEntitySource entitySource, EntityBinding entityBinding) {
- if ( entitySource.getIdentifierSource() == null ) {
- throw new AssertionFailure( "Expecting identifier information on root entity descriptor" );
+ private void bindCollectionTable( final AbstractPluralAttributeBinding pluralAttributeBinding,
+ final PluralAttributeSource attributeSource ) {
+ if ( attributeSource.getElementSource().getNature() == org.hibernate.metamodel.spi.source.PluralAttributeElementNature.ONE_TO_MANY ) {
+ return;
}
- switch ( entitySource.getIdentifierSource().getNature() ) {
- case SIMPLE: {
- bindSimpleIdentifier( (SimpleIdentifierSource) entitySource.getIdentifierSource(), entityBinding );
- break;
- }
- case AGGREGATED_COMPOSITE: {
- // composite id with an actual component class
- break;
- }
- case COMPOSITE: {
- // what we used to term an "embedded composite identifier", which is not tobe confused with the JPA
- // term embedded. Specifically a composite id where there is no component class, though there may
- // be a @IdClass :/
- break;
+ final DefaultNamingStrategy defaultNamingStategy = new DefaultNamingStrategy() {
+
+ @Override
+ public String defaultName() {
+ final AttributeBindingContainer attributeBindingContainer = pluralAttributeBinding.getContainer();
+ final EntityBinding owner = attributeBindingContainer.seekEntityBinding();
+ final String ownerTableLogicalName = Table.class.isInstance( owner.getPrimaryTable() )
+ ? ( ( Table ) owner.getPrimaryTable() ).getTableName().getName()
+ : null;
+ return bindingContexts.peek().getNamingStrategy().collectionTableName( owner.getEntity().getName(),
+ ownerTableLogicalName,
+ null, // todo: here
+ null, // todo: and here
+ attributeBindingContainer.getPathBase()
+ + '.' + attributeSource.getName() );
}
+ };
+ pluralAttributeBinding.setCollectionTable( createTable( attributeSource.getCollectionTableSpecificationSource(),
+ defaultNamingStategy ) );
+ if ( StringHelper.isNotEmpty( attributeSource.getCollectionTableComment() ) ) {
+ pluralAttributeBinding.getCollectionTable().addComment( attributeSource.getCollectionTableComment() );
}
- }
-
- private void bindSimpleIdentifier(
- SimpleIdentifierSource identifierSource,
- EntityBinding entityBinding) {
- final BasicAttributeBinding idAttributeBinding = bindBasicAttribute(
- identifierSource.getIdentifierAttributeSource(),
- entityBinding
- );
-
- entityBinding.getHierarchyDetails().getEntityIdentifier().setValueBinding( idAttributeBinding );
- IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor();
- if ( generator == null ) {
- Map params = new HashMap();
- params.put( IdentifierGenerator.ENTITY_NAME, entityBinding.getEntity().getName() );
- generator = new IdGenerator( "default_assign_identity_generator", "assigned", params );
+ if ( StringHelper.isNotEmpty( attributeSource.getCollectionTableCheck() ) ) {
+ pluralAttributeBinding.getCollectionTable().addCheckConstraint( attributeSource.getCollectionTableCheck() );
}
- entityBinding.getHierarchyDetails()
- .getEntityIdentifier()
- .setIdGenerator( generator );
-
- final List relationalValueBindings = idAttributeBinding.getRelationalValueBindings();
+ }
- if ( relationalValueBindings.size() == 1 ) {
- final Value value = relationalValueBindings.get( 0 ).getValue();
- if ( !Column.class.isInstance( value ) ) {
- // this should never ever happen..
- throw new AssertionFailure( "Simple-id was not a column." );
- }
- entityBinding.getPrimaryTable().getPrimaryKey().addColumn( Column.class.cast( value ) );
+ private void bindCollectionTablePrimaryKey( final AbstractPluralAttributeBinding attributeBinding,
+ final PluralAttributeSource attributeSource ) {
+ if ( attributeSource.getElementSource().getNature() == org.hibernate.metamodel.spi.source.PluralAttributeElementNature.ONE_TO_MANY
+ || attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) {
+ return;
}
- else {
- for ( RelationalValueBinding valueBinding : relationalValueBindings ) {
- final Value value = valueBinding.getValue();
- if ( Column.class.isInstance( value ) ) {
- entityBinding.getPrimaryTable().getPrimaryKey().addColumn( Column.class.cast( value ) );
- }
+ if ( attributeBinding.getPluralAttributeElementBinding().getPluralAttributeElementNature() == PluralAttributeElementNature.BASIC ) {
+ if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.SET ) {
+ bindBasicElementSetTablePrimaryKey( ( SetBinding ) attributeBinding );
+ } else {
+ throw new NotYetImplementedException( "Only Sets with basic elements are supported so far." );
}
}
}
- private void bindVersion(EntityBinding entityBinding, RootEntitySource entitySource) {
- final VersionAttributeSource versioningAttributeSource = entitySource.getVersioningAttributeSource();
- if ( versioningAttributeSource == null ) {
- return;
- }
-
- BasicAttributeBinding attributeBinding = bindBasicAttribute( versioningAttributeSource, entityBinding );
- entityBinding.getHierarchyDetails().getEntityVersion().setVersioningAttributeBinding( attributeBinding );
- entityBinding.getHierarchyDetails().getEntityVersion().setUnsavedValue( versioningAttributeSource.getUnsavedValue() );
+ private CompositeAttributeBinding bindComponentAttribute( final AttributeBindingContainer attributeBindingContainer,
+ final ComponentAttributeSource attributeSource,
+ SingularAttribute attribute ) {
+ System.out.println( "bindComponentAttribute( " + attributeBindingContainer.getAttributeContainer().getName() + ", "
+ + attributeSource.getName() + " )" );
+ Composite composite;
+ if ( attribute == null ) {
+ composite = new Composite( attributeSource.getPath(), attributeSource.getClassName(),
+ attributeSource.getClassReference(), null );
+ attribute = attributeBindingContainer.getAttributeContainer().createCompositeAttribute( attributeSource.getName(),
+ composite );
+ } else {
+ composite = ( Composite ) attribute.getSingularAttributeType();
+ }
+ final SingularAttribute referencingAttribute;
+ if ( StringHelper.isEmpty( attributeSource.getParentReferenceAttributeName() ) ) {
+ referencingAttribute = null;
+ } else {
+ referencingAttribute = composite.createSingularAttribute( attributeSource.getParentReferenceAttributeName() );
+ }
+ final CompositeAttributeBinding attributeBinding =
+ attributeBindingContainer.makeComponentAttributeBinding( attribute,
+ referencingAttribute,
+ propertyAccessorName( attributeSource ),
+ attributeSource.isIncludedInOptimisticLocking(),
+ attributeSource.isLazy(),
+ createMetaAttributeContext( attributeBindingContainer,
+ attributeSource ) );
+ bindAttributes( attributeBinding, attributeSource );
+ return attributeBinding;
}
- public static final ColumnBindingDefaults DISCRIMINATOR_COLUMN_BINDING_DEFAULTS = new ColumnBindingDefaults() {
- @Override
- public boolean areValuesIncludedInInsertByDefault() {
- return true;
- }
-
- @Override
- public boolean areValuesIncludedInUpdateByDefault() {
- return false;
- }
-
- @Override
- public boolean areValuesNullableByDefault() {
- return false;
- }
- };
-
- private void bindDiscriminator(RootEntitySource entitySource, EntityBinding entityBinding) {
- final DiscriminatorSource discriminatorSource = entitySource.getDiscriminatorSource();
+ private void bindDiscriminator( final EntityBinding rootEntityBinding,
+ final RootEntitySource rootEntitySource ) {
+ final DiscriminatorSource discriminatorSource = rootEntitySource.getDiscriminatorSource();
if ( discriminatorSource == null ) {
return;
}
+ final RelationalValueSource valueSource = discriminatorSource.getDiscriminatorRelationalValueSource();
+ final TableSpecification table = rootEntityBinding.locateTable( valueSource.getContainingTableName() );
+ AbstractValue value;
+ if ( valueSource instanceof ColumnSource ) {
+ value = createColumn( table,
+ ( ColumnSource ) valueSource,
+ bindingContexts.peek().getMappingDefaults().getDiscriminatorColumnName(),
+ false,
+ false );
+ } else {
+ value = table.locateOrCreateDerivedValue( ( ( DerivedValueSource ) valueSource ).getExpression() );
+ }
+ final EntityDiscriminator discriminator = new EntityDiscriminator( value, discriminatorSource.isInserted(),
+ discriminatorSource.isForced() );
+ rootEntityBinding.getHierarchyDetails().setEntityDiscriminator( discriminator );
+ rootEntityBinding.setDiscriminatorMatchValue( rootEntitySource.getDiscriminatorMatchValue() );
+ // Configure discriminator hibernate type
+ final String typeName = discriminatorSource.getExplicitHibernateTypeName() != null
+ ? discriminatorSource.getExplicitHibernateTypeName()
+ : "string";
+ final HibernateTypeDescriptor hibernateTypeDescriptor = discriminator.getExplicitHibernateTypeDescriptor();
+ hibernateTypeDescriptor.setExplicitTypeName( typeName );
+ resolveHibernateResolvedType( hibernateTypeDescriptor, typeName, value );
+ }
- TableSpecification table = entityBinding.locateTable( discriminatorSource.getDiscriminatorRelationalValueSource().getContainingTableName() );
- Value relationalValue;
- if ( ColumnSource.class.isInstance( discriminatorSource.getDiscriminatorRelationalValueSource() ) ) {
- relationalValue = makeColumn(
- ( ColumnSource) discriminatorSource.getDiscriminatorRelationalValueSource(),
- DISCRIMINATOR_COLUMN_BINDING_DEFAULTS,
- table,
- currentBindingContext.getMappingDefaults().getDiscriminatorColumnName(),
- false
- );
- }
- else {
- relationalValue = makeDerivedValue( (DerivedValueSource) discriminatorSource.getDiscriminatorRelationalValueSource(), table );
+ private EntityBinding bindEntities( final EntityHierarchy entityHierarchy ) {
+ final RootEntitySource rootEntitySource = entityHierarchy.getRootEntitySource();
+ System.out.println( "bindEntities(): rootEntitySource = " + rootEntitySource.getEntityName() );
+ // Return existing binding if available
+ EntityBinding rootEntityBinding = metadata.getEntityBinding( rootEntitySource.getEntityName() );
+ if ( rootEntityBinding != null ) {
+ return rootEntityBinding;
+ }
+ // Save inheritance type and entity mode that will apply to entire hierarchy
+ inheritanceTypes.push( entityHierarchy.getHierarchyInheritanceType() );
+ entityModes.push( rootEntitySource.getEntityMode() );
+ try {
+ // Create root entity binding
+ rootEntityBinding = createEntityBinding( rootEntitySource, null );
+ // Create/Bind root-specific information
+ bindIdentifier( rootEntityBinding, rootEntitySource.getIdentifierSource() );
+ bindVersion( rootEntityBinding, rootEntitySource.getVersioningAttributeSource() );
+ bindDiscriminator( rootEntityBinding, rootEntitySource );
+ createIdentifierGenerator( rootEntityBinding );
+ rootEntityBinding.getHierarchyDetails().setCaching( rootEntitySource.getCaching() );
+ rootEntityBinding.getHierarchyDetails().setExplicitPolymorphism( rootEntitySource.isExplicitPolymorphism() );
+ rootEntityBinding.getHierarchyDetails().setOptimisticLockStyle( rootEntitySource.getOptimisticLockStyle() );
+ rootEntityBinding.setMutable( rootEntitySource.isMutable() );
+ rootEntityBinding.setWhereFilter( rootEntitySource.getWhere() );
+ rootEntityBinding.setRowId( rootEntitySource.getRowId() );
+ bindAttributes( rootEntityBinding, rootEntitySource );
+ if ( inheritanceTypes.peek() != InheritanceType.NO_INHERITANCE ) {
+ bindSubEntities( rootEntityBinding, rootEntitySource );
+ }
+ } finally {
+ inheritanceTypes.pop();
+ entityModes.pop();
}
- EntityDiscriminator discriminator = new EntityDiscriminator(
- relationalValue,
- discriminatorSource.isInserted(),
- discriminatorSource.isForced()
- );
-
- discriminator.getExplicitHibernateTypeDescriptor().setExplicitTypeName(
- discriminatorSource.getExplicitHibernateTypeName() != null
- ? discriminatorSource.getExplicitHibernateTypeName()
- : "string"
- );
-
- entityBinding.getHierarchyDetails().setEntityDiscriminator( discriminator );
- entityBinding.setDiscriminatorMatchValue( entitySource.getDiscriminatorMatchValue() );
+ return rootEntityBinding;
+ }
- Type resolvedType = typeHelper.determineHibernateTypeFromDescriptor( discriminator.getExplicitHibernateTypeDescriptor() );
- if ( resolvedType != null ) {
- typeHelper.pushHibernateTypeInformationDown( resolvedType, relationalValue );
+ public void bindEntities( final Iterable< EntityHierarchy > entityHierarchies ) {
+ entitySourcesByName.clear();
+ attributeSourcesByName.clear();
+ inheritanceTypes.clear();
+ entityModes.clear();
+ bindingContexts.clear();
+ // Index sources by name so we can find and resolve entities on the fly as references to them
+ // are encountered (e.g., within associations)
+ for ( final EntityHierarchy entityHierarchy : entityHierarchies ) {
+ entityHierarchiesByRootEntitySource.put( entityHierarchy.getRootEntitySource(), entityHierarchy );
+ mapSourcesByName( entityHierarchy.getRootEntitySource() );
+ }
+ // Bind each entity hierarchy
+ for ( final EntityHierarchy entityHierarchy : entityHierarchies ) {
+ bindEntities( entityHierarchy );
}
}
- private void bindDiscriminatorValue(SubclassEntitySource entitySource, EntityBinding entityBinding) {
- final String discriminatorValue = entitySource.getDiscriminatorMatchValue();
- if ( discriminatorValue == null ) {
- return;
+ private EntityBinding bindEntity( final EntitySource entitySource,
+ final EntityBinding superEntityBinding ) {
+ System.out.println( "bindEntity( entitySource = " + entitySource.getEntityName() + ", superEntityBinding = "
+ + ( superEntityBinding == null ? "null" : superEntityBinding.getEntity().getName() ) + " )" );
+ // Return existing binding if available
+ EntityBinding entityBinding = metadata.getEntityBinding( entitySource.getEntityName() );
+ if ( entityBinding != null ) {
+ return entityBinding;
}
- entityBinding.setDiscriminatorMatchValue( discriminatorValue );
+ // Create new entity binding
+ entityBinding = createEntityBinding( entitySource, superEntityBinding );
+ bindAttributes( entityBinding, entitySource );
+ bindSubEntities( entityBinding, entitySource );
+ return entityBinding;
}
- private void bindAttributes(
- AttributeSourceContainer attributeSourceContainer,
- AttributeBindingContainer attributeBindingContainer,
- Deque tableStack) {
- // 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....
-
- for ( AttributeSource attributeSource : attributeSourceContainer.attributeSources() ) {
- if ( attributeSource.isSingular() ) {
- bindSingularAttribute( (SingularAttributeSource) attributeSource, attributeBindingContainer, tableStack );
+ private void bindHibernateTypeDescriptor( final HibernateTypeDescriptor hibernateTypeDescriptor,
+ final ExplicitHibernateTypeSource typeSource,
+ final Attribute attribute,
+ final AbstractValue value ) {
+ String typeName = typeSource.getName();
+ System.out.println( "bindHibernateTypeDescriptor( typeSource = " + typeSource.getName() + ", attribute = "
+ + attribute.getName() + " )" );
+ // Check if user specified a type
+ if ( typeName == null ) {
+ // Obtain Java type name from attribute
+ final Class< ? > attributeJavaType =
+ ReflectHelper.reflectedPropertyClass( attribute.getAttributeContainer().getClassReference(), attribute.getName() );
+ typeName = attributeJavaType.getName();
+ hibernateTypeDescriptor.setJavaTypeName( typeName );
+ } else {
+ // Check if user-specified name is of a User-Defined Type (UDT)
+ final TypeDefinition typeDef = metadata.getTypeDefinition( typeName );
+ if ( typeDef == null ) {
+ hibernateTypeDescriptor.setExplicitTypeName( typeName );
+ } else {
+ hibernateTypeDescriptor.setExplicitTypeName( typeDef.getTypeImplementorClass().getName() );
+ hibernateTypeDescriptor.setTypeParameters( typeDef.getParameters() );
}
- else {
- bindPersistentCollection( (PluralAttributeSource) attributeSource, attributeBindingContainer, tableStack );
+ final Map< String, String > typeParameters = typeSource.getParameters();
+ if ( typeParameters != null ) {
+ hibernateTypeDescriptor.getTypeParameters().putAll( typeParameters );
}
}
+ resolveHibernateResolvedType( hibernateTypeDescriptor, typeName, value );
}
- private void bindSingularAttribute(
- SingularAttributeSource attributeSource,
- AttributeBindingContainer attributeBindingContainer,
- Deque tableStack) {
- if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) {
- bindBasicAttribute( attributeSource, attributeBindingContainer );
- }
- else if ( attributeSource.getNature() == SingularAttributeNature.COMPONENT ) {
- bindComponentAttribute( (ComponentAttributeSource) attributeSource, attributeBindingContainer, tableStack );
- }
- else if ( attributeSource.getNature() == SingularAttributeNature.ANY ) {
- throw new NotYetImplementedException( "Handling of ANY mappings not yet implemented" );
- }
- else {
- bindToOneAttribute( (ToOneAttributeSource) attributeSource, attributeBindingContainer );
+ private void bindIdentifier( final EntityBinding rootEntityBinding,
+ final IdentifierSource identifierSource ) {
+ final Nature nature = identifierSource.getNature();
+ System.out.println( "bindIdentifier( " + rootEntityBinding.getEntity().getName() + " ): nature = " + nature );
+ if ( nature == Nature.SIMPLE ) {
+ bindSimpleIdentifier( rootEntityBinding, ( SimpleIdentifierSource ) identifierSource );
+ } else {
+ throw new NotYetImplementedException( nature.toString() );
+ // } else if ( nature == Nature.AGGREGATED_COMPOSITE ) {
+ // // composite id with an actual component class
+ // } else if ( nature == Nature.COMPOSITE ) {
+ // // what we used to term an "embedded composite identifier", which is not to be confused with the JPA
+ // // term embedded. Specifically a composite id where there is no component class, though there may
+ // // be a @IdClass :/
}
}
- private SingularAttributeBinding bindToOneAttribute(
- ToOneAttributeSource attributeSource,
- AttributeBindingContainer attributeBindingContainer) {
- final SingularAttribute existingAttribute = attributeBindingContainer.getAttributeContainer()
- .locateSingularAttribute( attributeSource.getName() );
- final SingularAttribute attribute;
- if ( existingAttribute != null ) {
- attribute = existingAttribute;
- }
- else if ( attributeSource.isVirtualAttribute() ) {
- attribute = attributeBindingContainer.getAttributeContainer().createVirtualSingularAttribute(
- attributeSource.getName()
- );
- }
- else {
- attribute = attributeBindingContainer.getAttributeContainer()
- .createSingularAttribute( attributeSource.getName() );
- }
-
- final List relationalValueBindings = createSimpleRelationalValues(
- attributeSource,
- attributeBindingContainer,
- attribute,
- attributeBindingContainer
- .seekEntityBinding()
- .getPrimaryTable()
- );
- final String propertyAccessorName = Helper.getPropertyAccessorName(
- attributeSource.getPropertyAccessorName(),
- false,
- currentBindingContext.getMappingDefaults().getPropertyAccessorName()
- );
- final MetaAttributeContext metaAttributeContext = buildMetaAttributeContext(
- attributeSource.metaAttributes(),
- attributeBindingContainer.getMetaAttributeContext()
- );
-
- final SingularAssociationAttributeBinding attributeBinding;
- if ( attributeSource.getNature() == SingularAttributeNature.ONE_TO_ONE ) {
- throw new NotYetImplementedException( "Handling of one-to-one mappings not yet implemented" );
- }
- else if ( attributeSource.getNature() == SingularAttributeNature.MANY_TO_ONE ) {
- attributeBinding = attributeBindingContainer.makeManyToOneAttributeBinding(
- attribute,
- propertyAccessorName,
- attributeSource.isIncludedInOptimisticLocking(),
- attributeSource.isLazy(),
- metaAttributeContext,
- attributeSource.getReferencedEntityName(),
- attributeSource.getReferencedEntityAttributeName(),
- relationalValueBindings
- );
- typeHelper.bindSingularAttributeTypeInformation( attributeSource, attributeBinding );
- resolveToOneInformation(
- attributeSource,
- (ManyToOneAttributeBinding) attributeBinding
- );
- final String referencedEntityName = attributeBinding.getReferencedEntityName();
- EntityBinding referencedEntityBinding = getEntityBinding( referencedEntityName );
- if ( referencedEntityBinding == null ) {
- EntitySource source = sourcesByName.get( referencedEntityName );
- createEntityBinding( source, referencedEntityBinding );
- }
- AttributeBinding referencedAttrBinding = attributeSource.getReferencedEntityAttributeName() != null
- ? referencedEntityBinding.locateAttributeBinding( attributeSource.getReferencedEntityAttributeName() )
- : referencedEntityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding();
- attributeBinding.resolveReference( referencedAttrBinding );
- referencedAttrBinding.addEntityReferencingAttributeBinding( attributeBinding );
- }
- else {
- throw new NotYetImplementedException();
- }
-
- return attributeBinding;
+ LocalBindingContext bindingContext() {
+ return bindingContexts.peek();
}
- private ForeignKey resolveForeignKey(
- ToOneAttributeSource attributeSource,
- AttributeBindingContainer attributeBindingContainer,
- Attribute attribute) {
- final String explicitForeignKeyName = attributeSource.getForeignKeyName();
-
- // foreign key columns should all come from the same table...
- final TableSpecification sourceTable = attributeBindingContainer.seekEntityBinding().locateTable(
- attributeSource.relationalValueSources().get( 0 ).getContainingTableName()
- );
-
- ForeignKey foreignKey = sourceTable.locateForeignKey( explicitForeignKeyName );
- if ( foreignKey != null ) {
- // todo : maybe validate columns?
- return foreignKey;
- }
-
- final List sourceColumns = new ArrayList();
- for ( RelationalValueSource relationalValueSource : attributeSource.relationalValueSources() ) {
- sourceColumns.add(
- makeRelationalValue(
- sourceTable,
- relationalValueSource,
- attributeSource,
- attribute
- )
- );
- }
-
- // todo : pretty sure this is one of the places where the "chasing" approach implemented by john breaks down
- // even assuming the best case that the target entity and its attributes are fully resolved,
- // what about the self-referential (Employee<->Manager) case?
- final EntityBinding referencedEntityBinding = metadata.getEntityBinding( attributeSource.getReferencedEntityName() );
- if ( referencedEntityBinding == null ) {
- throw new MappingException(
- "Unable to locate reference entity binding for association : " + attributeSource,
- currentBindingContext.getOrigin()
- );
- }
+ private ManyToOneAttributeBinding bindManyToOneAttribute( final AttributeBindingContainer attributeBindingContainer,
+ final ToOneAttributeSource attributeSource,
+ SingularAttribute attribute ) {
+ System.out.println( "bindManyToOneAttribute( " + attributeBindingContainer.getAttributeContainer().getName() + ", "
+ + attributeSource.getName() + " )" );
+ if ( attribute == null ) {
+ attribute = createSingularAttribute( attributeBindingContainer, attributeSource );
+ }
+ final List< RelationalValueBinding > relationalValueBindings =
+ bindValues( attributeBindingContainer,
+ attributeSource,
+ attribute,
+ attributeBindingContainer.seekEntityBinding().getPrimaryTable() );
+ final ManyToOneAttributeBinding attributeBinding =
+ attributeBindingContainer.makeManyToOneAttributeBinding( attribute,
+ propertyAccessorName( attributeSource ),
+ attributeSource.isIncludedInOptimisticLocking(),
+ attributeSource.isLazy(),
+ createMetaAttributeContext( attributeBindingContainer,
+ attributeSource ),
+ null, // this isn't passed to the binding constructor
+ null, // this isn't passed to the binding constructor
+ relationalValueBindings );
+ bindHibernateTypeDescriptor( attributeBinding.getHibernateTypeDescriptor(),
+ attributeSource.getTypeInformation(),
+ attributeBinding.getAttribute(),
+ ( AbstractValue ) relationalValueBindings.get( 0 ).getValue() );
+ final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor();
+ attribute.resolveType( bindingContexts.peek().makeJavaType( hibernateTypeDescriptor.getJavaTypeName() ) );
- // todo : try to look up the reverse FK based on the tables/columns...
+ attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() );
+ attributeBinding.setFetchTiming( attributeSource.getFetchTiming() );
+ attributeBinding.setFetchStyle( attributeSource.getFetchStyle() );
- final TableSpecification targetTable;
- final List targetColumns = new ArrayList();
- if ( StringHelper.isEmpty( attributeSource.getReferencedEntityAttributeName() ) ) {
- List valueBindings = referencedEntityBinding.getHierarchyDetails()
- .getEntityIdentifier()
- .getValueBinding()
- .getRelationalValueBindings();
- targetTable = valueBindings.get( 0 ).getValue().getTable();
- for ( RelationalValueBinding binding : valueBindings ) {
- targetColumns.add( binding.getValue() );
- }
- }
- else {
- // todo : this is very different for JPA which uses @JoinColumn and hbm which uses property-ref
- // we need a scheme that works for both.
- // the processing here uses hbm/property-ref approach
- //
- // the referenced property could conceivably be either a component or a basic
- final SingularAttributeBinding referencedAttributeBinding = (SingularAttributeBinding) referencedEntityBinding.locateAttributeBinding(
- attributeSource.getReferencedEntityAttributeName()
- );
- if ( CompositeAttributeBinding.class.isInstance( referencedAttributeBinding ) ) {
- collectValues( (CompositeAttributeBinding) referencedAttributeBinding, targetColumns );
- }
- else {
- for ( RelationalValueBinding valueBinding :( (BasicAttributeBinding) referencedAttributeBinding ).getRelationalValueBindings() ) {
- targetColumns.add( valueBinding.getValue() );
- }
- }
- targetTable = targetColumns.get( 0 ).getTable();
+ String referencedEntityName = attributeSource.getReferencedEntityName();
+ if ( referencedEntityName == null ) {
+ referencedEntityName = attribute.getSingularAttributeType().getClassName();
}
+ attributeBinding.setReferencedEntityName( referencedEntityName );
+ final EntityBinding referencedEntityBinding = entityBinding( referencedEntityName );
+ System.out.println( "bindManyToOneAttribute: referencedEntityBinding = " + referencedEntityBinding.getEntity().getName() );
+ final String referencedAttributeName = attributeSource.getReferencedEntityAttributeName();
+ System.out.println( "bindManyToOneAttribute: referencedAttributeName = " + referencedAttributeName );
+ attributeBinding.setReferencedAttributeName( referencedAttributeName );
+ final AttributeBinding referencedAttributeBinding = referencedAttributeName == null
+ ? referencedEntityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding()
+ : referencedEntityBinding.locateAttributeBinding( referencedAttributeName );
+ System.out.println( "bindManyToOneAttribute: referencedAttributeBinding = " + referencedAttributeBinding );
+ attributeBinding.resolveReference( referencedAttributeBinding );
+ referencedAttributeBinding.addEntityReferencingAttributeBinding( attributeBinding );
+ return attributeBinding;
+ }
- if ( sourceColumns.size() != targetColumns.size() ) {
- throw new MappingException(
- "Encountered mismatch in number of columns in foreign key",
- currentBindingContext.getOrigin()
- );
- }
- foreignKey = sourceTable.createForeignKey( targetTable, explicitForeignKeyName );
- for ( int i = 0; i < sourceColumns.size(); i++ ) {
- // todo : handle special case of formulas in key mappings...
- foreignKey.addColumnMapping( (Column) sourceColumns.get(i), (Column) targetColumns.get(i) );
+ private AbstractPluralAttributeBinding bindPluralAttribute( final AttributeBindingContainer attributeBindingContainer,
+ final PluralAttributeSource attributeSource ) {
+ final PluralAttributeNature nature = attributeSource.getPluralAttributeNature();
+ System.out.println( "bindPluralAttribute( " + attributeBindingContainer.getAttributeContainer().getName() + ", "
+ + attributeSource.getName() + " ): nature = " + nature );
+ final PluralAttribute attribute =
+ attributeBindingContainer.getAttributeContainer().locatePluralAttribute( attributeSource.getName() );
+ AbstractPluralAttributeBinding attributeBinding;
+ if ( nature == PluralAttributeNature.BAG ) {
+ attributeBinding = bindBagAttribute( attributeBindingContainer, attributeSource, attribute );
+ } else if ( nature == PluralAttributeNature.SET ) {
+ attributeBinding = bindSetAttribute( attributeBindingContainer, attributeSource, attribute );
+ } else {
+ throw new NotYetImplementedException( nature.toString() );
}
+ attributeBinding.setFetchTiming( attributeSource.getFetchTiming() );
+ attributeBinding.setFetchStyle( attributeSource.getFetchStyle() );
+ attributeBinding.setCaching( attributeSource.getCaching() );
+ attributeBinding.getHibernateTypeDescriptor().setJavaTypeName( nature.reportedJavaType().getName() );
+ attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( attributeSource.getTypeInformation().getName() );
+ attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( attributeSource.getTypeInformation().
+ getParameters() );
+ if ( StringHelper.isNotEmpty( attributeSource.getCustomPersisterClassName() ) ) {
+ attributeBinding.setExplicitPersisterClass( bindingContexts.peek().
+ < CollectionPersister >locateClassByName( attributeSource.
+ getCustomPersisterClassName() ) );
+ }
+ attributeBinding.setCustomLoaderName( attributeSource.getCustomLoaderName() );
+ attributeBinding.setCustomSqlInsert( attributeSource.getCustomSqlInsert() );
+ attributeBinding.setCustomSqlUpdate( attributeSource.getCustomSqlUpdate() );
+ attributeBinding.setCustomSqlDelete( attributeSource.getCustomSqlDelete() );
+ attributeBinding.setCustomSqlDeleteAll( attributeSource.getCustomSqlDeleteAll() );
+ attributeBinding.setWhere( attributeSource.getWhere() );
+ bindCollectionTable( attributeBinding, attributeSource );
+ bindSortingAndOrdering( attributeBinding, attributeSource );
+ bindCollectionKey( attributeBinding, attributeSource );
+ bindCollectionElement( attributeBinding, attributeSource );
+ bindCollectionIndex( attributeBinding, attributeSource );
+ bindCollectionTablePrimaryKey( attributeBinding, attributeSource );
+ typeHelper.bindPluralAttributeTypeInformation( attributeSource, attributeBinding );
+ metadata.addCollection( attributeBinding );
+ return attributeBinding;
+ }
+
+ private void bindPrimaryTable( final EntityBinding entityBinding,
+ final EntitySource entitySource ) {
+ entityBinding.setPrimaryTable( createTable( entitySource.getPrimaryTable(), new DefaultNamingStrategy() {
- return foreignKey;
+ @Override
+ public String defaultName() {
+ return bindingContexts.peek().getNamingStrategy().classToTableName( entityBinding.getEntity().getClassName() );
+ }
+ } ) );
}
- private void collectValues(CompositeAttributeBinding compositeAttributeBinding, List targetColumns) {
- for ( AttributeBinding attributeBinding : compositeAttributeBinding.attributeBindings() ) {
- if ( BasicAttributeBinding.class.isInstance( attributeBinding ) ) {
- for ( RelationalValueBinding valueBinding :( (BasicAttributeBinding) attributeBinding ).getRelationalValueBindings() ) {
- targetColumns.add( valueBinding.getValue() );
+ private void bindSecondaryTables( final EntityBinding entityBinding,
+ final EntitySource entitySource ) {
+ System.out.println( "bindSecondaryTables( entityBinding = " + entitySource.getEntityName() + " )" );
+ final TableSpecification primaryTable = entityBinding.getPrimaryTable();
+ for ( final SecondaryTableSource secondaryTableSource : entitySource.getSecondaryTables() ) {
+ final TableSpecification table = createTable( secondaryTableSource.getTableSource(), null );
+ // todo: really need a concept like SecondaryTableSource in the binding model as well
+ // so that EntityBinding can know the proper foreign key to use to build SQL statements.
+ ForeignKey foreignKey = null;
+ if ( secondaryTableSource.getForeignKeyName() == null ) {
+ // todo: for now lets assume we have to create it, but eventually we should look through the
+ // candidate foreign keys referencing primary table also...
+ foreignKey = table.createForeignKey( primaryTable, null );
+ } else {
+ foreignKey = table.locateForeignKey( secondaryTableSource.getForeignKeyName() );
+ if ( foreignKey == null ) {
+ foreignKey = table.createForeignKey( primaryTable, secondaryTableSource.getForeignKeyName() );
}
}
- else if ( ManyToOneAttributeBinding.class.isInstance( attributeBinding ) ) {
- for ( RelationalValueBinding valueBinding :( (BasicAttributeBinding) attributeBinding ).getRelationalValueBindings() ) {
- targetColumns.add( valueBinding.getValue() );
+ for ( final PrimaryKeyJoinColumnSource joinColumnSource : secondaryTableSource.getJoinColumns() ) {
+ // todo : currently we only support columns here, not formulas
+ // todo : apply naming strategy to infer missing column name
+ Column column = table.locateColumn( joinColumnSource.getColumnName() );
+ if ( column == null ) {
+ column = table.createColumn( joinColumnSource.getColumnName() );
+ if ( joinColumnSource.getColumnDefinition() != null ) {
+ column.setSqlType( joinColumnSource.getColumnDefinition() );
+ }
+ }
+ if ( joinColumnSource.getReferencedColumnName() == null ) {
+ foreignKey.addColumn( column );
+ } else {
+ foreignKey.addColumnMapping( column, primaryTable.locateColumn( joinColumnSource.getReferencedColumnName() ) );
}
}
- else if ( CompositeAttributeBinding.class.isInstance( attributeBinding ) ) {
- collectValues( (CompositeAttributeBinding) attributeBinding, targetColumns );
- }
+ entityBinding.addSecondaryTable( new SecondaryTable( table, foreignKey ) );
}
}
- private BasicAttributeBinding bindBasicAttribute(
- SingularAttributeSource attributeSource,
- AttributeBindingContainer attributeBindingContainer) {
- final SingularAttribute existingAttribute = attributeBindingContainer.getAttributeContainer()
- .locateSingularAttribute( attributeSource.getName() );
- final SingularAttribute attribute;
- if ( existingAttribute != null ) {
- attribute = existingAttribute;
- }
- else if ( attributeSource.isVirtualAttribute() ) {
- attribute = attributeBindingContainer.getAttributeContainer().createVirtualSingularAttribute(
- attributeSource.getName()
- );
- }
- else {
- attribute = attributeBindingContainer.getAttributeContainer()
- .createSingularAttribute( attributeSource.getName() );
- }
-
- final List relationalValueBindings = createSimpleRelationalValues(
- attributeSource,
- attributeBindingContainer,
- attribute,
- attributeBindingContainer
- .seekEntityBinding()
- .getPrimaryTable()
- );
- final String propertyAccessorName = Helper.getPropertyAccessorName(
- attributeSource.getPropertyAccessorName(),
- false,
- currentBindingContext.getMappingDefaults().getPropertyAccessorName()
- );
- final MetaAttributeContext metaAttributeContext = buildMetaAttributeContext(
- attributeSource.metaAttributes(),
- attributeBindingContainer.getMetaAttributeContext()
- );
-
- final BasicAttributeBinding attributeBinding = attributeBindingContainer.makeBasicAttributeBinding(
- attribute,
- relationalValueBindings,
- propertyAccessorName,
- attributeSource.isIncludedInOptimisticLocking(),
- attributeSource.isLazy(),
- metaAttributeContext,
- attributeSource.getGeneration()
- );
- typeHelper.bindSingularAttributeTypeInformation( attributeSource, attributeBinding );
- return attributeBinding;
- }
-
- private void bindComponentAttribute(
- ComponentAttributeSource attributeSource,
- AttributeBindingContainer container,
- Deque tableStack) {
- final String attributeName = attributeSource.getName();
- SingularAttribute attribute = container.getAttributeContainer().locateCompositeAttribute( attributeName );
- final Composite composite;
+ private AbstractPluralAttributeBinding bindSetAttribute( final AttributeBindingContainer attributeBindingContainer,
+ final PluralAttributeSource attributeSource,
+ PluralAttribute attribute ) {
if ( attribute == null ) {
- composite = new Composite(
- attributeSource.getPath(),
- attributeSource.getClassName(),
- attributeSource.getClassReference(),
- null // composition inheritance not YET supported
- );
- attribute = container.getAttributeContainer().createCompositeAttribute( attributeName, composite );
- }
- else {
- composite = (Composite) attribute.getSingularAttributeType();
- }
-
- final String propertyAccessorName = Helper.getPropertyAccessorName(
- attributeSource.getPropertyAccessorName(),
- false,
- currentBindingContext.getMappingDefaults().getPropertyAccessorName()
- );
- final MetaAttributeContext metaAttributeContext = buildMetaAttributeContext(
- attributeSource.metaAttributes(),
- container.getMetaAttributeContext()
- );
-
- final SingularAttribute parentReferenceAttribute;
- if ( StringHelper.isNotEmpty( attributeSource.getParentReferenceAttributeName() ) ) {
- parentReferenceAttribute = composite.createSingularAttribute( attributeSource.getParentReferenceAttributeName() );
- }
- else {
- parentReferenceAttribute = null;
- }
-
- CompositeAttributeBinding compositeAttributeBinding = container.makeComponentAttributeBinding(
- attribute,
- parentReferenceAttribute,
- propertyAccessorName,
- attributeSource.isIncludedInOptimisticLocking(),
- attributeSource.isLazy(),
- metaAttributeContext
- );
-
- bindAttributes( attributeSource, compositeAttributeBinding, tableStack );
- }
-
- private void bindPersistentCollection(
- PluralAttributeSource attributeSource,
- AttributeBindingContainer attributeBindingContainer,
- Deque tableStack) {
- final PluralAttribute existingAttribute = attributeBindingContainer.getAttributeContainer()
- .locatePluralAttribute( attributeSource.getName() );
- final AbstractPluralAttributeBinding pluralAttributeBinding;
-
- final String propertyAccessorName = Helper.getPropertyAccessorName(
- attributeSource.getPropertyAccessorName(),
- false,
- currentBindingContext.getMappingDefaults().getPropertyAccessorName()
- );
- final MetaAttributeContext metaAttributeContext = buildMetaAttributeContext(
- attributeSource.metaAttributes(),
- attributeBindingContainer.getMetaAttributeContext()
- );
-
- // TODO: referenced attribute binding may not be defined yet; if it doesn't, need to chase it
- // before resolving types.
- SingularAttributeBinding referencedAttributeBinding = locatePluralAttributeKeyReferencedBinding(
- attributeSource, attributeBindingContainer
- );
- if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) {
- final PluralAttribute attribute = existingAttribute != null
- ? existingAttribute
- : attributeBindingContainer.getAttributeContainer().createBag( attributeSource.getName() );
- pluralAttributeBinding = attributeBindingContainer.makeBagAttributeBinding(
- attribute,
- convert( attributeSource.getElementSource().getNature() ),
- referencedAttributeBinding,
- propertyAccessorName,
- attributeSource.isIncludedInOptimisticLocking(),
- false,
- metaAttributeContext
- );
- }
- else if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.SET ) {
- final PluralAttribute attribute = existingAttribute != null
- ? existingAttribute
- : attributeBindingContainer.getAttributeContainer().createSet( attributeSource.getName() );
- final Comparator comparator = null;
- pluralAttributeBinding = attributeBindingContainer.makeSetAttributeBinding(
- attribute,
- convert( attributeSource.getElementSource().getNature() ),
- referencedAttributeBinding,
- propertyAccessorName,
- attributeSource.isIncludedInOptimisticLocking(),
- false,
- metaAttributeContext,
- comparator
- );
- }
- else {
- // todo : implement other collection types
- throw new NotYetImplementedException( "Collections other than bag and set not yet implemented :(" );
- }
-
- doBasicPluralAttributeBinding( attributeSource, pluralAttributeBinding );
-
- bindCollectionTable( attributeSource, pluralAttributeBinding );
- bindSortingAndOrdering( attributeSource, pluralAttributeBinding );
-
- bindCollectionKey( attributeSource, pluralAttributeBinding, tableStack );
- bindCollectionElement( attributeSource, pluralAttributeBinding );
- bindCollectionIndex( attributeSource, pluralAttributeBinding );
- bindCollectionTablePrimaryKey( attributeSource, pluralAttributeBinding );
-
- typeHelper.bindPluralAttributeTypeInformation( attributeSource, pluralAttributeBinding );
-
- metadata.addCollection( pluralAttributeBinding );
+ attribute = attributeBindingContainer.getAttributeContainer().createSet( attributeSource.getName() );
+ }
+ return attributeBindingContainer.makeSetAttributeBinding( attribute,
+ pluralAttributeElementNature( attributeSource ),
+ pluralAttributeKeyBinding( attributeBindingContainer,
+ attributeSource ),
+ propertyAccessorName( attributeSource ),
+ attributeSource.isIncludedInOptimisticLocking(),
+ false,
+ createMetaAttributeContext( attributeBindingContainer,
+ attributeSource ),
+ null );
}
- private SingularAttributeBinding locatePluralAttributeKeyReferencedBinding(
- PluralAttributeSource attributeSource,
- AttributeBindingContainer attributeBindingContainer) {
- final EntityBinding entityBinding = attributeBindingContainer.seekEntityBinding();
- final String referencedAttributeName = attributeSource.getKeySource().getReferencedEntityAttributeName();
- AttributeBinding referencedAttributeBinding =
- attributeSource.getKeySource().getReferencedEntityAttributeName() == null ?
- entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() :
- entityBinding.locateAttributeBinding( referencedAttributeName );
- if ( referencedAttributeBinding == null ) {
- throw new MappingException(
- String.format(
- "Plural atttribute key references an attribute binding that does not exist: %s",
- referencedAttributeBinding
- ),
- currentBindingContext.getOrigin()
- );
+ private void bindSimpleIdentifier( final EntityBinding rootEntityBinding,
+ final SimpleIdentifierSource identifierSource ) {
+ final BasicAttributeBinding idAttributeBinding =
+ ( BasicAttributeBinding ) bindAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() );
+ System.out.println( "bindSimpleIdentifier( " + rootEntityBinding.getEntity().getName() + ", "
+ + identifierSource.getIdentifierAttributeSource().getName() + " )" );
+ rootEntityBinding.getHierarchyDetails().getEntityIdentifier().setValueBinding( idAttributeBinding );
+ // Configure ID generator
+ IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor();
+ if ( generator == null ) {
+ final Map< String, String > params = new HashMap< String, String >();
+ params.put( IdentifierGenerator.ENTITY_NAME, rootEntityBinding.getEntity().getName() );
+ generator = new IdGenerator( "default_assign_identity_generator", "assigned", params );
}
- if ( ! referencedAttributeBinding.getAttribute().isSingular() ) {
- throw new MappingException(
- String.format(
- "Plural atttribute key references a plural attribute; it must be plural: %s",
- referencedAttributeName
- ),
- currentBindingContext.getOrigin()
- );
+ rootEntityBinding.getHierarchyDetails().getEntityIdentifier().setIdGenerator( generator );
+ // Configure primary key in relational model
+ for ( final RelationalValueBinding valueBinding : idAttributeBinding.getRelationalValueBindings() ) {
+ rootEntityBinding.getPrimaryTable().getPrimaryKey().addColumn( ( Column ) valueBinding.getValue() );
}
- return ( SingularAttributeBinding ) referencedAttributeBinding;
}
- private void doBasicPluralAttributeBinding(PluralAttributeSource source, AbstractPluralAttributeBinding binding) {
- binding.setFetchTiming( source.getFetchTiming() );
- binding.setFetchStyle( source.getFetchStyle() );
-
- binding.setCaching( source.getCaching() );
-
- binding.getHibernateTypeDescriptor().setJavaTypeName(
- source.getPluralAttributeNature().reportedJavaType().getName()
- );
- binding.getHibernateTypeDescriptor().setExplicitTypeName( source.getTypeInformation().getName() );
- binding.getHibernateTypeDescriptor().getTypeParameters().putAll( source.getTypeInformation().getParameters() );
-
- if ( StringHelper.isNotEmpty( source.getCustomPersisterClassName() ) ) {
- binding.setExplicitPersisterClass(
- currentBindingContext.locateClassByName( source.getCustomPersisterClassName() )
- );
- }
-
- binding.setCustomLoaderName( source.getCustomLoaderName() );
- binding.setCustomSqlInsert( source.getCustomSqlInsert() );
- binding.setCustomSqlUpdate( source.getCustomSqlUpdate() );
- binding.setCustomSqlDelete( source.getCustomSqlDelete() );
- binding.setCustomSqlDeleteAll( source.getCustomSqlDeleteAll() );
-
- binding.setWhere( source.getWhere() );
-
-// doBasicAttributeBinding( source, binding );
+ private SingularAttributeBinding bindSingularAttribute( final AttributeBindingContainer attributeBindingContainer,
+ final SingularAttributeSource attributeSource ) {
+ final SingularAttributeNature nature = attributeSource.getNature();
+ System.out.println( "bindSingularAttribute( " + attributeBindingContainer.getAttributeContainer().getName() + ", "
+ + attributeSource.getName() + " ): nature = " + nature );
+ final SingularAttribute attribute =
+ attributeBindingContainer.getAttributeContainer().locateSingularAttribute( attributeSource.getName() );
+ if ( nature == SingularAttributeNature.BASIC ) {
+ return bindBasicAttribute( attributeBindingContainer, attributeSource, attribute );
+ }
+ if ( nature == SingularAttributeNature.MANY_TO_ONE ) {
+ return bindManyToOneAttribute( attributeBindingContainer, ( ToOneAttributeSource ) attributeSource, attribute );
+ }
+ if ( nature == SingularAttributeNature.COMPONENT ) {
+ return bindComponentAttribute( attributeBindingContainer,
+ ( ComponentAttributeSource ) attributeSource,
+ attribute );
+ }
+ throw new NotYetImplementedException( nature.toString() );
}
-// private CollectionLaziness interpretLaziness(String laziness) {
-// if ( laziness == null ) {
-// laziness = Boolean.toString( metadata.getMappingDefaults().areAssociationsLazy() );
-// }
-//
-// if ( "extra".equals( laziness ) ) {
-// return CollectionLaziness.EXTRA;
-// }
-// else if ( "false".equals( laziness ) ) {
-// return CollectionLaziness.NOT;
-// }
-// else if ( "true".equals( laziness ) ) {
-// return CollectionLaziness.LAZY;
-// }
-//
-// throw new MappingException(
-// String.format( "Unexpected collection laziness value %s", laziness ),
-// currentBindingContext.getOrigin()
-// );
-// }
-
- private void bindCollectionTable(
- final PluralAttributeSource attributeSource,
- final AbstractPluralAttributeBinding pluralAttributeBinding) {
- if ( attributeSource.getElementSource().getNature() == org.hibernate.metamodel.spi.source.PluralAttributeElementNature.ONE_TO_MANY ) {
+ private void bindSortingAndOrdering( final AbstractPluralAttributeBinding attributeBinding,
+ final PluralAttributeSource attributeSource ) {
+ if ( Sortable.class.isInstance( attributeSource ) ) {
+ final Sortable sortable = ( Sortable ) attributeSource;
+ if ( sortable.isSorted() ) {
+ // todo : handle setting comparator
+ }
+ // Return because sorting and ordering are mutually exclusive
return;
}
-
- TableSpecificationSource tableSpecificationSource = attributeSource.getCollectionTableSpecificationSource();
- if ( TableSource.class.isInstance( tableSpecificationSource ) ) {
- Table collectionTable = createTable(
- (TableSource) tableSpecificationSource,
- new InferredNamingStrategy() {
- @Override
- public String inferredTableName() {
- final EntityBinding owner = pluralAttributeBinding.getContainer().seekEntityBinding();
- final String ownerTableLogicalName = Table.class.isInstance( owner.getPrimaryTable() )
- ? Table.class.cast( owner.getPrimaryTable() ).getTableName().getName()
- : null;
- return currentBindingContext.getNamingStrategy().collectionTableName(
- owner.getEntity().getName(),
- ownerTableLogicalName,
- null, // todo : here
- null, // todo : and here
- pluralAttributeBinding.getContainer().getPathBase() + '.' + attributeSource.getName()
- );
- }
- }
- );
- pluralAttributeBinding.setCollectionTable( collectionTable );
- }
- else {
- pluralAttributeBinding.setCollectionTable( createInLineView( (InLineViewSource) tableSpecificationSource ) );
- }
-
- if ( StringHelper.isNotEmpty( attributeSource.getCollectionTableComment() ) ) {
- pluralAttributeBinding.getCollectionTable().addComment( attributeSource.getCollectionTableComment() );
+ if ( Orderable.class.isInstance( attributeSource ) ) {
+ final Orderable orderable = ( Orderable ) attributeSource;
+ if ( orderable.isOrdered() ) {
+ // todo : handle setting ordering
+ }
}
-
- if ( StringHelper.isNotEmpty( attributeSource.getCollectionTableCheck() ) ) {
- pluralAttributeBinding.getCollectionTable().addCheckConstraint( attributeSource.getCollectionTableCheck() );
- }
}
-
- private void bindCollectionKey(
- PluralAttributeSource attributeSource,
- AbstractPluralAttributeBinding pluralAttributeBinding,
- Deque tableStack) {
-
- final PluralAttributeKeySource keySource = attributeSource.getKeySource();
-
- String foreignKeyName = (
- StringHelper.isNotEmpty( keySource.getExplicitForeignKeyName() ) ?
- quoteIdentifier( keySource.getExplicitForeignKeyName() ) :
- null // TODO: is null FK name allowd (is there a default?)
- );
- pluralAttributeBinding.getPluralAttributeKeyBinding().prepareForeignKey(
- foreignKeyName,
- tableStack.peekLast()
- );
- final ForeignKey foreignKey = pluralAttributeBinding.getPluralAttributeKeyBinding().getForeignKey();
-
- foreignKey.setDeleteRule( keySource.getOnDeleteAction() );
- if ( keySource.getReferencedEntityAttributeName() == null ) {
- bindCollectionKeyTargetingPrimaryKey( attributeSource.getKeySource(), pluralAttributeBinding );
- }
- else {
- bindCollectionKeyTargetingPropertyRef( attributeSource.getKeySource(), pluralAttributeBinding );
+ private void bindSubEntities( final EntityBinding entityBinding,
+ final EntitySource entitySource ) {
+ for ( final SubclassEntitySource subEntitySource : entitySource.subclassEntitySources() ) {
+ bindEntity( subEntitySource, entityBinding );
}
}
- private void bindCollectionKeyTargetingPrimaryKey(
- PluralAttributeKeySource keySource,
- AbstractPluralAttributeBinding pluralAttributeBinding) {
-
- for ( RelationalValueSource valueSource : keySource.getValueSources() ) {
- if ( ColumnSource.class.isInstance( valueSource ) ) {
- final Column column = makeColumn(
- ColumnSource.class.cast( valueSource ),
- COLL_KEY_COLUMN_BINDING_DEFAULTS,
- pluralAttributeBinding.getCollectionTable(),
- pluralAttributeBinding.getAttribute().getName(),
- true
- );
- pluralAttributeBinding.getPluralAttributeKeyBinding().getForeignKey().addColumn( column );
- }
- else {
- // TODO: deal with formulas???
+ private void bindUniqueConstraints( final EntityBinding entityBinding,
+ final EntitySource entitySource ) {
+ for ( final ConstraintSource constraintSource : entitySource.getConstraints() ) {
+ if ( constraintSource instanceof UniqueConstraintSource ) {
+ final TableSpecification table = entityBinding.locateTable( constraintSource.getTableName() );
+ final String constraintName = constraintSource.name();
+ if ( constraintName == null ) {
+ throw new NotYetImplementedException( "create default constraint name" );
+ }
+ final UniqueKey uniqueKey = table.getOrCreateUniqueKey( constraintName );
+ for ( final String columnName : constraintSource.columnNames() ) {
+ uniqueKey.addColumn( table.locateOrCreateColumn( quotedIdentifier( columnName ) ) );
+ }
}
}
}
- private void bindCollectionKeyTargetingPropertyRef(
- PluralAttributeKeySource keySource,
- AbstractPluralAttributeBinding pluralAttributeBinding) {
- final EntityBinding ownerEntityBinding = pluralAttributeBinding.getContainer().seekEntityBinding();
- final AttributeBinding referencedAttributeBinding = ownerEntityBinding.locateAttributeBinding(
- keySource.getReferencedEntityAttributeName()
- );
- final ForeignKey foreignKey = pluralAttributeBinding.getPluralAttributeKeyBinding().getForeignKey();
- if ( ! referencedAttributeBinding.getAttribute().isSingular() ) {
- throw new MappingException(
- String.format(
- "Collection (%s) property-ref is a plural attribute (%s); must be singular.",
- pluralAttributeBinding.getAttribute().getRole(),
- referencedAttributeBinding
- ),
- currentBindingContext.getOrigin()
- );
- }
- Iterator targetValueBindings =
- ( (SingularAttributeBinding) referencedAttributeBinding ).getRelationalValueBindings().iterator();
- for ( RelationalValueSource valueSource : keySource.getValueSources() ) {
- if ( ! targetValueBindings.hasNext() ) {
- throw new MappingException(
- String.format(
- "More collection key source columns than target columns for collection: %s",
- pluralAttributeBinding.getAttribute().getRole()
- ),
- currentBindingContext.getOrigin()
- );
- }
- Value targetValue = targetValueBindings.next().getValue();
- if ( ColumnSource.class.isInstance( valueSource ) ) {
- final ColumnSource columnSource = ColumnSource.class.cast( valueSource );
- final Column column = makeColumn(
- columnSource,
- COLL_KEY_COLUMN_BINDING_DEFAULTS,
- pluralAttributeBinding.getCollectionTable(),
- pluralAttributeBinding.getAttribute().getName(),
- true
- );
- if ( targetValue != null && ! Column.class.isInstance( targetValue ) ) {
- throw new MappingException(
- String.format(
- "Type mismatch between collection key source and target; collection: %s; source column (%s) corresponds with target derived value (%s).",
- pluralAttributeBinding.getAttribute().getRole(),
- columnSource.getName(),
- DerivedValue.class.cast( targetValue ).getExpression()
- ),
- currentBindingContext.getOrigin()
- );
+ private List< RelationalValueBinding > bindValues( final AttributeBindingContainer attributeBindingContainer,
+ final RelationalValueSourceContainer valueSourceContainer,
+ final Attribute attribute,
+ final TableSpecification defaultTable ) {
+ System.out.println( "bindValues( " + attributeBindingContainer.getAttributeContainer().getName() + ", "
+ + attribute.getName() + " )" );
+ final List< RelationalValueBinding > valueBindings = new ArrayList< RelationalValueBinding >();
+ if ( valueSourceContainer.relationalValueSources().isEmpty() ) {
+ final String columnName =
+ quotedIdentifier( bindingContexts.peek().getNamingStrategy().propertyToColumnName( attribute.getName() ) );
+ final Column column = defaultTable.locateOrCreateColumn( columnName );
+ System.out.println( "bindValues: \"" + column.getColumnName().getName() + "\" column on primary table "
+ + defaultTable.getLogicalName() );
+ column.setNullable( valueSourceContainer.areValuesNullableByDefault() );
+ valueBindings.add( new RelationalValueBinding( column ) );
+ } else {
+ final String name = attribute.getName();
+ for ( final RelationalValueSource valueSource : valueSourceContainer.relationalValueSources() ) {
+ final TableSpecification table =
+ valueSource.getContainingTableName() == null
+ ? defaultTable
+ : attributeBindingContainer.seekEntityBinding().locateTable( valueSource.getContainingTableName() );
+ if ( valueSource instanceof ColumnSource ) {
+ final ColumnSource columnSource = ( ColumnSource ) valueSource;
+ final boolean isIncludedInInsert = toBoolean( columnSource.isIncludedInInsert(),
+ valueSourceContainer.areValuesIncludedInInsertByDefault() );
+ final boolean isIncludedInUpdate = toBoolean( columnSource.isIncludedInUpdate(),
+ valueSourceContainer.areValuesIncludedInUpdateByDefault() );
+
+ valueBindings.add( new RelationalValueBinding( createColumn( table,
+ columnSource,
+ name,
+ valueSourceContainer.areValuesNullableByDefault(),
+ true ),
+ isIncludedInInsert, isIncludedInUpdate ) );
+ } else {
+ final DerivedValue derivedValue =
+ table.locateOrCreateDerivedValue( ( ( DerivedValueSource ) valueSource ).getExpression() );
+ valueBindings.add( new RelationalValueBinding( derivedValue ) );
}
- foreignKey.addColumnMapping( column, Column.class.cast( targetValue ) );
- }
- else {
- // TODO: deal with formulas???
}
}
- if ( targetValueBindings != null && targetValueBindings.hasNext() ) {
- throw new MappingException(
- String.format(
- "More collection key target columns than source columns for collection: %s",
- pluralAttributeBinding.getAttribute().getRole()
- ),
- currentBindingContext.getOrigin()
- );
- }
+ return valueBindings;
}
- private void bindCollectionTablePrimaryKey(
- final PluralAttributeSource attributeSource,
- final AbstractPluralAttributeBinding pluralAttributeBinding) {
- if ( attributeSource.getElementSource().getNature() == org.hibernate.metamodel.spi.source.PluralAttributeElementNature.ONE_TO_MANY ||
- attributeSource.getPluralAttributeNature() == PluralAttributeNature.BAG ) {
+ private void bindVersion( final EntityBinding rootEntityBinding,
+ final VersionAttributeSource versionAttributeSource ) {
+ if ( versionAttributeSource == null ) {
return;
}
- if ( pluralAttributeBinding.getPluralAttributeElementBinding().getPluralAttributeElementNature() == PluralAttributeElementNature.BASIC ) {
- if ( attributeSource.getPluralAttributeNature() == PluralAttributeNature.SET ) {
- bindBasicElementSetTablePrimaryKey( ( SetBinding ) pluralAttributeBinding );
- }
- else {
- throw new NotYetImplementedException( "Only Sets with basic elements are supported so far." );
- }
- }
+ System.out.println( "bindVersion( " + rootEntityBinding.getEntity().getName() + " ): " + versionAttributeSource.getName() );
+ final EntityVersion version = rootEntityBinding.getHierarchyDetails().getEntityVersion();
+ version.setVersioningAttributeBinding( ( BasicAttributeBinding ) bindAttribute( rootEntityBinding,
+ versionAttributeSource ) );
+ version.setUnsavedValue( versionAttributeSource.getUnsavedValue() );
}
- private void bindBasicElementSetTablePrimaryKey(SetBinding setBinding) {
-
- final PrimaryKey pk = setBinding.getCollectionTable().getPrimaryKey();
- final ForeignKey foreignKey = setBinding.getPluralAttributeKeyBinding().getForeignKey();
-
- final BasicPluralAttributeElementBinding elementBinding =
- ( BasicPluralAttributeElementBinding ) setBinding.getPluralAttributeElementBinding();
- if ( elementBinding.getPluralAttributeElementNature() != PluralAttributeElementNature.BASIC ) {
- throw new IllegalArgumentException(
- String.format(
- "Expected a SetBinding with an element of nature PluralAttributeElementNature.BASIC; instead was %s",
- elementBinding.getPluralAttributeElementNature()
- )
- );
- }
-
- for ( Column foreignKeyColumn : foreignKey.getSourceColumns() ) {
- pk.addColumn( foreignKeyColumn );
- }
-
- for ( RelationalValueBinding elementValueBinding : elementBinding.getRelationalValueBindings() ) {
- if ( Column.class.isInstance( elementValueBinding.getValue() ) && !elementValueBinding.isNullable() ) {
- pk.addColumn( ( Column ) elementValueBinding.getValue() );
- }
+ private Column createColumn( final TableSpecification table,
+ final ColumnSource columnSource,
+ final String defaultName,
+ final boolean isNullableByDefault,
+ final boolean isDefaultAttributeName ) {
+ if ( columnSource.getName() == null && defaultName == null ) {
+ throw new MappingException( "Cannot resolve name for column because no name was specified and default name is null.",
+ bindingContexts.peek().getOrigin() );
}
- if ( pk.getColumnSpan() == foreignKey.getColumnSpan() ) {
- //for backward compatibility, allow a set with no not-null
- //element columns, using all columns in the row locater SQL
- //TODO: create an implicit not null constraint on all cols?
+ String name;
+ if ( columnSource.getName() != null ) {
+ name = bindingContexts.peek().getNamingStrategy().columnName( columnSource.getName() );
+ } else if ( isDefaultAttributeName ) {
+ name = bindingContexts.peek().getNamingStrategy().propertyToColumnName( defaultName );
+ } else {
+ name = bindingContexts.peek().getNamingStrategy().columnName( defaultName );
}
+ final String resolvedColumnName = quotedIdentifier( name );
+ final Column column = table.locateOrCreateColumn( resolvedColumnName );
+ column.setNullable( toBoolean( columnSource.isNullable(), isNullableByDefault ) );
+ column.setDefaultValue( columnSource.getDefaultValue() );
+ column.setSqlType( columnSource.getSqlType() );
+ column.setSize( columnSource.getSize() );
+ column.setJdbcDataType( columnSource.getDatatype() );
+ column.setReadFragment( columnSource.getReadFragment() );
+ column.setWriteFragment( columnSource.getWriteFragment() );
+ column.setUnique( columnSource.isUnique() );
+ column.setCheckCondition( columnSource.getCheckCondition() );
+ column.setComment( columnSource.getComment() );
+ return column;
}
- private static final ColumnBindingDefaults COLL_KEY_COLUMN_BINDING_DEFAULTS = new ColumnBindingDefaults() {
- @Override
- public boolean areValuesIncludedInInsertByDefault() {
- return true;
- }
-
- @Override
- public boolean areValuesIncludedInUpdateByDefault() {
- return false;
- }
-
- @Override
- public boolean areValuesNullableByDefault() {
- return false;
- }
- };
+ private EntityBinding createEntityBinding( final EntitySource entitySource,
+ final EntityBinding superEntityBinding ) {
+ System.out.println( "createEntityBinding( entitySource = " + entitySource.getEntityName() + ", superEntityBinding = "
+ + ( superEntityBinding == null ? "null" : superEntityBinding.getEntity().getName() ) + " )" );
+ final LocalBindingContext bindingContext = entitySource.getLocalBindingContext();
+ bindingContexts.push( bindingContext );
+ try {
+ // Create binding
+ final InheritanceType inheritanceType = inheritanceTypes.peek();
+ final EntityMode entityMode = entityModes.peek();
+ final EntityBinding entityBinding = entitySource instanceof RootEntitySource
+ ? new EntityBinding( inheritanceType, entityMode )
+ : new EntityBinding( superEntityBinding );
+ // Create domain entity
+ final String entityClassName = entityMode == EntityMode.POJO ? entitySource.getClassName() : null;
+ entityBinding.setEntity( new Entity( entitySource.getEntityName(), entityClassName,
+ bindingContext.makeClassReference( entityClassName ),
+ superEntityBinding == null ? null : superEntityBinding.getEntity() ) );
+ // Create relational table
+ if ( superEntityBinding != null && inheritanceType == InheritanceType.SINGLE_TABLE ) {
+ entityBinding.setPrimaryTable( superEntityBinding.getPrimaryTable() );
+ entityBinding.setPrimaryTableName( superEntityBinding.getPrimaryTableName() );
+ // Configure discriminator if present
+ final String discriminatorValue = entitySource.getDiscriminatorMatchValue();
+ if ( discriminatorValue != null ) {
+ entityBinding.setDiscriminatorMatchValue( discriminatorValue );
+ }
+ } else {
+ bindPrimaryTable( entityBinding, entitySource );
+ }
+ // todo: deal with joined and unioned subclass bindings
+ // todo: bind fetch profiles
+ // Configure rest of binding
+ final String customTuplizerClassName = entitySource.getCustomTuplizerClassName();
+ if ( customTuplizerClassName != null ) {
+ entityBinding.setCustomEntityTuplizerClass( bindingContext.
+ < EntityTuplizer >locateClassByName( customTuplizerClassName ) );
+ }
+ final String customPersisterClassName = entitySource.getCustomPersisterClassName();
+ if ( customPersisterClassName != null ) {
+ entityBinding.setCustomEntityPersisterClass( bindingContext.
+ < EntityPersister >locateClassByName( customPersisterClassName ) );
+ }
+ entityBinding.setMetaAttributeContext( createMetaAttributeContext( entitySource.metaAttributes(),
+ true,
+ metadata.getGlobalMetaAttributeContext() ) );
+ entityBinding.setJpaEntityName( entitySource.getJpaEntityName() );
+ entityBinding.setDynamicUpdate( entitySource.isDynamicUpdate() );
+ entityBinding.setDynamicInsert( entitySource.isDynamicInsert() );
+ entityBinding.setBatchSize( entitySource.getBatchSize() );
+ entityBinding.setSelectBeforeUpdate( entitySource.isSelectBeforeUpdate() );
+ entityBinding.setAbstract( entitySource.isAbstract() );
+
+ entityBinding.setCustomLoaderName( entitySource.getCustomLoaderName() );
+ entityBinding.setCustomInsert( entitySource.getCustomSqlInsert() );
+ entityBinding.setCustomUpdate( entitySource.getCustomSqlUpdate() );
+ entityBinding.setCustomDelete( entitySource.getCustomSqlDelete() );
+ entityBinding.setJpaCallbackClasses( entitySource.getJpaCallbackClasses() );
+ if ( entitySource.getSynchronizedTableNames() != null ) {
+ entityBinding.addSynchronizedTableNames( entitySource.getSynchronizedTableNames() );
+ }
+ if ( entityMode == EntityMode.POJO ) {
+ final String proxy = entitySource.getProxy();
+ if ( proxy == null ) {
+ if ( entitySource.isLazy() ) {
+ entityBinding.setProxyInterfaceType( entityBinding.getEntity().getClassReferenceUnresolved() );
+ entityBinding.setLazy( true );
+ }
+ } else {
+ entityBinding.setProxyInterfaceType( bindingContext.makeClassReference( bindingContext.qualifyClassName( proxy ) ) );
+ entityBinding.setLazy( true );
+ }
+ } else {
+ entityBinding.setProxyInterfaceType( null );
+ entityBinding.setLazy( entitySource.isLazy() );
+ }
+ bindSecondaryTables( entityBinding, entitySource );
+ bindUniqueConstraints( entityBinding, entitySource );
+ // Register binding with metadata
+ metadata.addEntity( entityBinding );
+ return entityBinding;
+ } finally {
- private void bindCollectionElement(
- PluralAttributeSource attributeSource,
- AbstractPluralAttributeBinding pluralAttributeBinding) {
- final PluralAttributeElementSource elementSource = attributeSource.getElementSource();
- if ( elementSource.getNature() == org.hibernate.metamodel.spi.source.PluralAttributeElementNature.BASIC ) {
- final BasicPluralAttributeElementSource basicElementSource =
- (BasicPluralAttributeElementSource) elementSource;
- final BasicPluralAttributeElementBinding basicCollectionElement =
- (BasicPluralAttributeElementBinding) pluralAttributeBinding.getPluralAttributeElementBinding();
- bindBasicPluralElementRelationalValues(
- basicElementSource,
- basicCollectionElement
- );
- return;
}
-
-// todo : handle cascades
-// final Cascadeable cascadeable = (Cascadeable) binding.getPluralAttributeElementBinding();
-// cascadeable.setCascadeStyles( source.getCascadeStyles() );
-
- // todo : implement
- throw new NotYetImplementedException(
- String.format(
- "Support for collection elements of type %s not yet implemented",
- elementSource.getNature()
- )
- );
- }
-
- private void bindBasicPluralElementRelationalValues(
- RelationalValueSourceContainer relationalValueSourceContainer,
- BasicPluralAttributeElementBinding elementBinding) {
- elementBinding.setRelationalValueBindings(
- createSimpleRelationalValues(
- relationalValueSourceContainer,
- elementBinding.getPluralAttributeBinding().getContainer(),
- elementBinding.getPluralAttributeBinding().getAttribute(),
- elementBinding.getPluralAttributeBinding().getCollectionTable()
- )
- );
}
- private void bindCollectionIndex(
- PluralAttributeSource attributeSource,
- AbstractPluralAttributeBinding pluralAttributeBinding) {
- if ( attributeSource.getPluralAttributeNature() != PluralAttributeNature.LIST
- && attributeSource.getPluralAttributeNature() != PluralAttributeNature.MAP ) {
- return;
+ private Identifier createIdentifier( String name,
+ final String defaultName ) {
+ System.out.println( "createIdentifier( name = " + name + ", defaultName = " + defaultName + " )" );
+ if ( StringHelper.isEmpty( name ) ) {
+ name = defaultName;
}
-
- // todo : implement
- throw new NotYetImplementedException();
+ name = quotedIdentifier( name );
+ return Identifier.toIdentifier( name );
}
- private void bindSortingAndOrdering(
- PluralAttributeSource attributeSource,
- AbstractPluralAttributeBinding pluralAttributeBinding) {
- if ( Sortable.class.isInstance( attributeSource ) ) {
- final Sortable sortable = Sortable.class.cast( attributeSource );
- if ( sortable.isSorted() ) {
- // todo : handle setting comparator
-
- // and then return because sorting and ordering are mutually exclusive
- return;
- }
+ private void createIdentifierGenerator( final EntityBinding rootEntityBinding ) {
+ System.out.println( "createIdentifierGenerator( " + rootEntityBinding.getEntity().getName() + " )" );
+ final Properties properties = new Properties();
+ properties.putAll( metadata.getServiceRegistry().getService( ConfigurationService.class ).getSettings() );
+ if ( !properties.contains( AvailableSettings.PREFER_POOLED_VALUES_LO ) ) {
+ properties.put( AvailableSettings.PREFER_POOLED_VALUES_LO, "false" );
}
-
- if ( Orderable.class.isInstance( attributeSource ) ) {
- final Orderable orderable = Orderable.class.cast( attributeSource );
- if ( orderable.isOrdered() ) {
- // todo : handle setting ordering
- }
+ if ( !properties.contains( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER ) ) {
+ properties.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, nameNormalizer );
}
+ rootEntityBinding.getHierarchyDetails().getEntityIdentifier().createIdentifierGenerator( identifierGeneratorFactory,
+ properties );
}
- private PluralAttributeElementNature convert(org.hibernate.metamodel.spi.source.PluralAttributeElementNature pluralAttributeElementNature) {
- return PluralAttributeElementNature.valueOf( pluralAttributeElementNature.name() );
- }
-
- private EntityBinding getEntityBinding(String entityName) {
- // Check if binding has already been created
- EntityBinding binding = metadata.getEntityBinding( entityName );
- if ( binding == null ) {
- // Find appropriate source to create binding
- EntitySource source = sourcesByName.get( entityName );
- // Get super entity binding (creating it if necessary using recursive call to this method)
- EntityBinding superBinding = source instanceof SubclassEntitySource
- ? getEntityBinding( ( ( SubclassEntitySource ) source ).superclassEntitySource().getEntityName() )
- : null;
- // Create entity binding
- binding = createEntityBinding( source, superBinding );
- // Create entity binding's sub-entity bindings
- processHierarchySubEntities( source, binding );
- }
- return binding;
- }
-
- private void resolveToOneInformation(ToOneAttributeSource attributeSource, ManyToOneAttributeBinding attributeBinding) {
- final String referencedEntityName = attributeSource.getReferencedEntityName() != null
- ? attributeSource.getReferencedEntityName()
- : attributeBinding.getAttribute().getSingularAttributeType().getClassName();
- attributeBinding.setReferencedEntityName( referencedEntityName );
- // todo : we should consider basing references on columns instead of property-ref, which would require a resolution (later) of property-ref to column names
- attributeBinding.setReferencedAttributeName( attributeSource.getReferencedEntityAttributeName() );
-
- attributeBinding.setCascadeStyles( attributeSource.getCascadeStyles() );
- attributeBinding.setFetchTiming( attributeSource.getFetchTiming() );
- attributeBinding.setFetchStyle( attributeSource.getFetchStyle() );
- }
-
- private MetaAttributeContext buildMetaAttributeContext(EntitySource entitySource) {
- return buildMetaAttributeContext(
- entitySource.metaAttributes(),
- true,
- currentBindingContext.getMetadataImplementor().getGlobalMetaAttributeContext()
- );
- }
-
- private static MetaAttributeContext buildMetaAttributeContext(
- Iterable metaAttributeSources,
- MetaAttributeContext parentContext) {
- return buildMetaAttributeContext( metaAttributeSources, false, parentContext );
+ private MetaAttributeContext createMetaAttributeContext( final AttributeBindingContainer attributeBindingContainer,
+ final AttributeSource attributeSource ) {
+ return createMetaAttributeContext( attributeSource.metaAttributes(),
+ false,
+ attributeBindingContainer.getMetaAttributeContext() );
}
- private static MetaAttributeContext buildMetaAttributeContext(
- Iterable metaAttributeSources,
- boolean onlyInheritable,
- MetaAttributeContext parentContext) {
+ private MetaAttributeContext createMetaAttributeContext( final Iterable< MetaAttributeSource > metaAttributeSources,
+ final boolean onlyInheritable,
+ final MetaAttributeContext parentContext ) {
final MetaAttributeContext subContext = new MetaAttributeContext( parentContext );
-
- for ( MetaAttributeSource metaAttributeSource : metaAttributeSources ) {
- if ( onlyInheritable & !metaAttributeSource.isInheritable() ) {
+ for ( final MetaAttributeSource metaAttributeSource : metaAttributeSources ) {
+ if ( onlyInheritable && !metaAttributeSource.isInheritable() ) {
continue;
}
-
final String name = metaAttributeSource.getName();
- final MetaAttribute inheritedMetaAttribute = parentContext.getMetaAttribute( name );
MetaAttribute metaAttribute = subContext.getLocalMetaAttribute( name );
- if ( metaAttribute == null || metaAttribute == inheritedMetaAttribute ) {
+ if ( metaAttribute == null || metaAttribute == parentContext.getMetaAttribute( name ) ) {
metaAttribute = new MetaAttribute( name );
subContext.add( metaAttribute );
}
metaAttribute.addValue( metaAttributeSource.getValue() );
}
-
return subContext;
}
- // Relational ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- private void bindPrimaryTable(EntitySource entitySource, final EntityBinding entityBinding) {
- final TableSpecificationSource tableSpecificationSource = entitySource.getPrimaryTable();
- if ( TableSource.class.isInstance( tableSpecificationSource ) ) {
- final Table table = createTable(
- (TableSource) tableSpecificationSource,
- new InferredNamingStrategy() {
- @Override
- public String inferredTableName() {
- return currentBindingContext.getNamingStrategy()
- .classToTableName( entityBinding.getEntity().getClassName() );
- }
- }
- );
- entityBinding.setPrimaryTable( table );
- // todo : ugh!
- entityBinding.setPrimaryTableName( table.getTableName().getName() );
- }
- else {
- entityBinding.setPrimaryTable( createInLineView( (InLineViewSource) tableSpecificationSource ) );
- }
- }
-
- private InLineView createInLineView(InLineViewSource inLineViewSource) {
- final Schema.Name databaseSchemaName = Helper.determineDatabaseSchemaName(
- inLineViewSource.getExplicitSchemaName(),
- inLineViewSource.getExplicitCatalogName(),
- currentBindingContext
- );
- final Identifier logicalName = Identifier.toIdentifier( inLineViewSource.getLogicalName() );
- return currentBindingContext.getMetadataImplementor()
- .getDatabase()
- .locateSchema( databaseSchemaName )
- .createInLineView( logicalName, inLineViewSource.getSelectStatement() );
- }
-
- private static interface InferredNamingStrategy {
- public String inferredTableName();
+ private SingularAttribute createSingularAttribute( final AttributeBindingContainer attributeBindingContainer,
+ final SingularAttributeSource attributeSource ) {
+ return attributeSource.isVirtualAttribute()
+ ? attributeBindingContainer.getAttributeContainer().createVirtualSingularAttribute( attributeSource.getName() )
+ : attributeBindingContainer.getAttributeContainer().createSingularAttribute( attributeSource.getName() );
}
- private Table createTable(TableSource tableSource, InferredNamingStrategy namingStrategy) {
- String explicitTableNameString = tableSource.getExplicitTableName();
- if ( explicitTableNameString == null ) {
- explicitTableNameString = namingStrategy.inferredTableName();
- }
- explicitTableNameString = quoteIdentifier( explicitTableNameString );
- final Identifier logicalName = Identifier.toIdentifier( explicitTableNameString );
-
- explicitTableNameString = currentBindingContext.getNamingStrategy().tableName( explicitTableNameString );
- explicitTableNameString = quoteIdentifier( explicitTableNameString );
- final Identifier physicalName = Identifier.toIdentifier( explicitTableNameString );
-
- final Schema.Name databaseSchemaName = Helper.determineDatabaseSchemaName(
- tableSource.getExplicitSchemaName(),
- tableSource.getExplicitCatalogName(),
- currentBindingContext
- );
-
- Table table = currentBindingContext.getMetadataImplementor()
- .getDatabase()
- .locateSchema( databaseSchemaName )
- .locateTable( logicalName );
- if ( table == null ) {
- table = currentBindingContext.getMetadataImplementor()
- .getDatabase()
- .locateSchema( databaseSchemaName )
- .createTable( logicalName, physicalName );
- }
- return table;
- }
-
- private void bindSecondaryTables(EntitySource entitySource, EntityBinding entityBinding) {
- final TableSpecification primaryEntityTable = entityBinding.getPrimaryTable();
-
- for ( SecondaryTableSource secondaryTableSource : entitySource.getSecondaryTables() ) {
- final TableSpecification secondaryTable;
- final TableSpecificationSource source = secondaryTableSource.getTableSource();
- if ( TableSource.class.isInstance( source ) ) {
- secondaryTable = createTable(
- (TableSource) source,
- new InferredNamingStrategy() {
- @Override
- public String inferredTableName() {
- throw new MappingException(
- "Secondary table must specify explicit name",
- currentBindingContext.getOrigin()
- );
- }
- }
- );
- }
- else {
- secondaryTable = createInLineView( (InLineViewSource) source );
- }
-
- // todo : really need a concept like SecondaryTableSource in the binding model as well
- // so that EntityBinding can know the proper foreign key to use to build SQL statements.
-
- ForeignKey foreignKey = null;
- if ( secondaryTableSource.getForeignKeyName() != null ) {
- foreignKey = secondaryTable.locateForeignKey( secondaryTableSource.getForeignKeyName() );
- if ( foreignKey == null ) {
- foreignKey = secondaryTable.createForeignKey(
- primaryEntityTable,
- secondaryTableSource.getForeignKeyName()
- );
+ private TableSpecification createTable( final TableSpecificationSource tableSpecSource,
+ final DefaultNamingStrategy defaultNamingStrategy ) {
+ final LocalBindingContext bindingContext = bindingContexts.peek();
+ final MappingDefaults mappingDefaults = bindingContext.getMappingDefaults();
+ final Schema.Name schemaName =
+ new Schema.Name( createIdentifier( tableSpecSource.getExplicitSchemaName(), mappingDefaults.getSchemaName() ),
+ createIdentifier( tableSpecSource.getExplicitCatalogName(), mappingDefaults.getCatalogName() ) );
+ final Schema schema = metadata.getDatabase().locateSchema( schemaName );
+ if ( tableSpecSource instanceof TableSource ) {
+ final TableSource tableSource = ( TableSource ) tableSpecSource;
+ String tableName = tableSource.getExplicitTableName();
+ if ( tableName == null ) {
+ if ( defaultNamingStrategy == null ) {
+ throw new MappingException( "An explicit name must be specified for the table", bindingContext.getOrigin() );
}
+ tableName = defaultNamingStrategy.defaultName();
}
- else {
- // for now lets assume we have to create it, but eventually we should look through the
- // candidate foreign keys referencing primary table also...
- foreignKey = secondaryTable.createForeignKey( primaryEntityTable, null );
- }
-
- for ( PrimaryKeyJoinColumnSource joinColumnSource : secondaryTableSource.getJoinColumns() ) {
- // todo : currently we only support columns here, not formulas
- // todo : apply naming strategy to infer missing column name
- Column fkColumn = secondaryTable.locateColumn( joinColumnSource.getColumnName() );
- if ( fkColumn == null ) {
- fkColumn = secondaryTable.createColumn( joinColumnSource.getColumnName() );
- if ( joinColumnSource.getColumnDefinition() != null ) {
- fkColumn.setSqlType( joinColumnSource.getColumnDefinition() );
- }
- }
- if ( joinColumnSource.getReferencedColumnName() != null ) {
- final Column referencedColumn = primaryEntityTable.locateColumn(
- joinColumnSource.getReferencedColumnName()
- );
- foreignKey.addColumnMapping( fkColumn, referencedColumn );
- }
- else {
- foreignKey.addColumn( fkColumn );
- }
- }
-
- entityBinding.addSecondaryTable( new SecondaryTable( secondaryTable, foreignKey ) );
- }
+ tableName = quotedIdentifier( tableName );
+ final Identifier logicalTableId = Identifier.toIdentifier( tableName );
+ tableName = quotedIdentifier( bindingContext.getNamingStrategy().tableName( tableName ) );
+ final Identifier physicalTableId = Identifier.toIdentifier( tableName );
+ System.out.println( "createTable: table = " + logicalTableId );
+ final Table table = schema.locateTable( logicalTableId );
+ return ( table == null ? schema.createTable( logicalTableId, physicalTableId ) : table );
+ }
+ final InLineViewSource inLineViewSource = ( InLineViewSource ) tableSpecSource;
+ System.out.println( "createTable: inLineView = " + inLineViewSource.getLogicalName() );
+ return schema.createInLineView( Identifier.toIdentifier( inLineViewSource.getLogicalName() ),
+ inLineViewSource.getSelectStatement() );
}
- private void bindTableUniqueConstraints(EntitySource entitySource, EntityBinding entityBinding) {
- for ( ConstraintSource constraintSource : entitySource.getConstraints() ) {
- if ( constraintSource instanceof UniqueConstraintSource ) {
- TableSpecification table = entityBinding.locateTable( constraintSource.getTableName() );
- if ( table == null ) {
- // throw exception !?
- }
- String constraintName = constraintSource.name();
- if ( constraintName == null ) {
- // create a default name
- }
-
- UniqueKey uniqueKey = table.getOrCreateUniqueKey( constraintName );
- for ( String columnName : constraintSource.columnNames() ) {
- uniqueKey.addColumn( table.locateOrCreateColumn( quoteIdentifier( columnName ) ) );
- }
- }
+ private EntityBinding entityBinding( final String entityName ) {
+ System.out.println( "getEntityBinding( " + entityName + " )" );
+ // Check if binding has already been created
+ EntityBinding entityBinding = metadata.getEntityBinding( entityName );
+ if ( entityBinding == null ) {
+ // Find appropriate source to create binding
+ final EntitySource entitySource = entitySourcesByName.get( entityName );
+ // Get super entity binding (creating it if necessary using recursive call to this method)
+ final EntityBinding superEntityBinding =
+ entitySource instanceof SubclassEntitySource
+ ? entityBinding( ( ( SubclassEntitySource ) entitySource ).superclassEntitySource().getEntityName() )
+ : null;
+ // Create entity binding
+ entityBinding =
+ superEntityBinding == null
+ ? bindEntities( entityHierarchiesByRootEntitySource.get( entitySource ) )
+ : bindEntity( entitySource, superEntityBinding );
}
+ return entityBinding;
}
- private List createSimpleRelationalValues(
- RelationalValueSourceContainer relationalValueSourceContainer,
- AttributeBindingContainer attributeBindingContainer,
- Attribute attribute,
- TableSpecification defaultTable) {
-
- List valueBindings = new ArrayList();
-
- if ( !relationalValueSourceContainer.relationalValueSources().isEmpty() ) {
- for ( RelationalValueSource valueSource : relationalValueSourceContainer.relationalValueSources() ) {
- TableSpecification resolvedTable = defaultTable;
- if ( valueSource.getContainingTableName() != null ) {
- resolvedTable = attributeBindingContainer
- .seekEntityBinding()
- .locateTable( valueSource.getContainingTableName() );
- }
- if ( ColumnSource.class.isInstance( valueSource ) ) {
- final ColumnSource columnSource = ColumnSource.class.cast( valueSource );
- final Column column =
- makeColumn(
- columnSource,
- relationalValueSourceContainer,
- resolvedTable,
- attribute.getName(),
- true
- );
- valueBindings.add(
- new RelationalValueBinding(
- column,
- decode( columnSource.isIncludedInInsert(), relationalValueSourceContainer.areValuesIncludedInInsertByDefault() ),
- decode(
- columnSource.isIncludedInUpdate(),
- relationalValueSourceContainer.areValuesIncludedInUpdateByDefault()
- )
- )
- );
- }
- else {
- valueBindings.add(
- new RelationalValueBinding(
- makeDerivedValue( ( (DerivedValueSource) valueSource ), resolvedTable )
- )
- );
- }
- }
+ private void mapSourcesByName( final EntitySource entitySource ) {
+ entitySourcesByName.put( entitySource.getEntityName(), entitySource );
+ for ( final AttributeSource attributeSource : entitySource.attributeSources() ) {
+ attributeSourcesByName.put( attributeSource.getName(), attributeSource );
}
- else {
- String name = metadata.getOptions()
- .getNamingStrategy()
- .propertyToColumnName( attribute.getName() );
- name = quoteIdentifier( name );
- Column column = defaultTable.locateOrCreateColumn( name );
- column.setNullable( relationalValueSourceContainer.areValuesNullableByDefault() );
- valueBindings.add( new RelationalValueBinding( column ) );
+ for ( final SubclassEntitySource subclassEntitySource : entitySource.subclassEntitySources() ) {
+ mapSourcesByName( subclassEntitySource );
}
- return valueBindings;
}
- private String quoteIdentifier(String string) {
- return currentBindingContext.isGloballyQuotedIdentifiers() ? StringHelper.quote( string ) : string;
+ private PluralAttributeElementNature pluralAttributeElementNature( final PluralAttributeSource attributeSource ) {
+ return PluralAttributeElementNature.valueOf( attributeSource.getElementSource().getNature().name() );
}
- private Value makeRelationalValue(
- TableSpecification table,
- RelationalValueSource valueSource,
- ColumnBindingDefaults columnBindingDefaults,
- Attribute attribute) {
- if ( ColumnSource.class.isInstance( valueSource ) ) {
- final ColumnSource columnSource = ColumnSource.class.cast( valueSource );
- return makeColumn(
- columnSource,
- columnBindingDefaults,
- table,
- attribute.getName(),
- true
- );
+ private SingularAttributeBinding pluralAttributeKeyBinding( final AttributeBindingContainer attributeBindingContainer,
+ final PluralAttributeSource attributeSource ) {
+ final EntityBinding entityBinding = attributeBindingContainer.seekEntityBinding();
+ final String referencedAttributeName = attributeSource.getKeySource().getReferencedEntityAttributeName();
+ final AttributeBinding referencedAttributeBinding =
+ referencedAttributeName == null
+ ? entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding()
+ : entityBinding.locateAttributeBinding( referencedAttributeName );
+ if ( referencedAttributeBinding == null ) {
+ throw new MappingException( "Plural atttribute key references an attribute binding that does not exist: " +
+ referencedAttributeBinding, bindingContexts.peek().getOrigin() );
}
- else {
- return makeDerivedValue( (DerivedValueSource) valueSource, table );
+ if ( !referencedAttributeBinding.getAttribute().isSingular() ) {
+ throw new MappingException( "Plural atttribute key references a plural attribute; it must be plural: " +
+ referencedAttributeName, bindingContexts.peek().getOrigin() );
}
+ return ( SingularAttributeBinding ) referencedAttributeBinding;
}
- private Column makeColumn(
- ColumnSource columnSource,
- ColumnBindingDefaults columnBindingDefaults,
- TableSpecification table,
- String defaultName,
- boolean isDefaultAttributeName) {
- if ( columnSource.getName() == null && defaultName == null ) {
- throw new MappingException(
- "Cannot resolve name for column because the no name was specified and default name is null.",
- currentBindingContext.getOrigin()
- );
- }
- String name;
- if ( columnSource.getName() != null ) {
- name = metadata.getOptions().getNamingStrategy().columnName( columnSource.getName() );
- }
- else if ( isDefaultAttributeName ) {
- name = metadata.getOptions().getNamingStrategy().propertyToColumnName( defaultName );
- }
- else {
- name = metadata.getOptions().getNamingStrategy().columnName( defaultName );
- }
- String resolvedColumnName = quoteIdentifier( name );
- final Column column = table.locateOrCreateColumn( resolvedColumnName );
- column.setNullable(
- decode( columnSource.isNullable(), columnBindingDefaults.areValuesNullableByDefault() )
- );
- column.setDefaultValue( columnSource.getDefaultValue() );
- column.setSqlType( columnSource.getSqlType() );
- column.setSize( columnSource.getSize() );
- column.setJdbcDataType( columnSource.getDatatype() );
- column.setReadFragment( columnSource.getReadFragment() );
- column.setWriteFragment( columnSource.getWriteFragment() );
- column.setUnique( columnSource.isUnique() );
- column.setCheckCondition( columnSource.getCheckCondition() );
- column.setComment( columnSource.getComment() );
- return column;
+ private String propertyAccessorName( final AttributeSource attributeSource ) {
+ return attributeSource.getPropertyAccessorName() == null ? bindingContexts.peek().getMappingDefaults().getPropertyAccessorName()
+ : attributeSource.getPropertyAccessorName();
}
- private boolean decode(TruthValue truthValue, boolean defaultValue) {
- switch ( truthValue ) {
- case FALSE: {
- return false;
- }
- case TRUE: {
- return true;
- }
- default: {
- return defaultValue;
+ private String quotedIdentifier( final String name ) {
+ return bindingContexts.peek().isGloballyQuotedIdentifiers() ? StringHelper.quote( name ) : name;
+ }
+
+ private void resolveHibernateResolvedType( final HibernateTypeDescriptor hibernateTypeDescriptor,
+ final String typeName,
+ final AbstractValue value ) {
+ final Properties typeProperties = new Properties();
+ typeProperties.putAll( hibernateTypeDescriptor.getTypeParameters() );
+ final Type resolvedType = metadata.getTypeResolver().heuristicType( typeName, typeProperties );
+ // Configure relational value JDBC type from Hibernate type descriptor now that its configured
+ if ( resolvedType != null ) {
+ hibernateTypeDescriptor.setResolvedTypeMapping( resolvedType );
+ if ( hibernateTypeDescriptor.getJavaTypeName() == null ) {
+ hibernateTypeDescriptor.setJavaTypeName( resolvedType.getReturnedClass().getName() );
}
+ value.setJdbcDataType( new JdbcDataType( resolvedType.sqlTypes( metadata )[ 0 ], resolvedType.getName(),
+ resolvedType.getReturnedClass() ) );
}
}
- private DerivedValue makeDerivedValue(DerivedValueSource derivedValueSource, TableSpecification table) {
- return table.locateOrCreateDerivedValue( derivedValueSource.getExpression() );
+ private boolean toBoolean( final TruthValue truthValue,
+ final boolean truthValueDefault ) {
+ if ( truthValue == TruthValue.TRUE ) {
+ return true;
+ }
+ if ( truthValue == TruthValue.FALSE ) {
+ return false;
+ }
+ return truthValueDefault;
}
- private void processFetchProfiles(EntitySource entitySource, EntityBinding entityBinding) {
- // todo : process the entity-local fetch-profile declaration
- }
+ private interface DefaultNamingStrategy {
+ String defaultName();
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/HibernateTypeHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/HibernateTypeHelper.java
index 0c77c7a2d772..ef206f80a072 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/HibernateTypeHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/HibernateTypeHelper.java
@@ -102,17 +102,16 @@ public class HibernateTypeHelper {
private static final Logger log = Logger.getLogger( HibernateTypeHelper.class );
private final Binder binder;
+ private final MetadataImplementor metadata;
- public HibernateTypeHelper(Binder binder) {
+ public HibernateTypeHelper( Binder binder,
+ MetadataImplementor metadata ) {
this.binder = binder;
+ this.metadata = metadata;
}
private org.hibernate.metamodel.spi.domain.Type makeJavaType(String name) {
- return binder.getCurrentBindingContext().makeJavaType( name );
- }
-
- private MetadataImplementor metadata() {
- return binder.getMetadata();
+ return binder.bindingContext().makeJavaType( name );
}
public void bindSingularAttributeTypeInformation(
@@ -183,7 +182,7 @@ private void processPluralAttributeKeyTypeInformation(PluralAttributeKeyBinding
// TODO: not sure about the following...
pluralAttributeKeyTypeDescriptor.setToOne( referencedTypeDescriptor.isToOne() );
pluralAttributeKeyTypeDescriptor.getTypeParameters().putAll( referencedTypeDescriptor.getTypeParameters() );
-
+
processPluralAttributeKeyInformation( keyBinding );
}
@@ -215,7 +214,7 @@ private void processPluralAttributeKeyInformation(PluralAttributeKeyBinding keyB
}
}
}
-
+
private Class> determineJavaType(final SingularAttribute attribute) {
try {
final Class> ownerClass = attribute.getAttributeContainer().getClassReference();
@@ -262,7 +261,7 @@ private void bindHibernateTypeInformation(
HibernateTypeDescriptor hibernateTypeDescriptor) {
final String explicitTypeName = typeSource.getName();
if ( explicitTypeName != null ) {
- final TypeDefinition typeDefinition = metadata().getTypeDefinition( explicitTypeName );
+ final TypeDefinition typeDefinition = metadata.getTypeDefinition( explicitTypeName );
if ( typeDefinition != null ) {
hibernateTypeDescriptor.setExplicitTypeName( typeDefinition.getTypeImplementorClass().getName() );
hibernateTypeDescriptor.getTypeParameters().putAll( typeDefinition.getParameters() );
@@ -318,7 +317,7 @@ public Type determineHibernateTypeFromDescriptor(HibernateTypeDescriptor hiberna
private Type getHeuristicType(String typeName, Properties typeParameters) {
if ( typeName != null ) {
try {
- return metadata().getTypeResolver().heuristicType( typeName, typeParameters );
+ return metadata.getTypeResolver().heuristicType( typeName, typeParameters );
}
catch (Exception ignore) {
}
@@ -452,7 +451,7 @@ public void pushHibernateTypeInformationDown(Type resolvedHibernateType, Value v
if ( AbstractValue.class.isInstance( value ) ) {
( (AbstractValue) value ).setJdbcDataType(
new JdbcDataType(
- resolvedHibernateType.sqlTypes( metadata() )[0],
+ resolvedHibernateType.sqlTypes( metadata )[0],
resolvedHibernateType.getName(),
resolvedHibernateType.getReturnedClass()
)
@@ -480,7 +479,7 @@ private void processCollectionTypeInformation(PluralAttributeBinding attributeBi
String typeName = attributeBinding.getHibernateTypeDescriptor().getExplicitTypeName();
if ( typeName != null ) {
resolvedType =
- metadata().getTypeResolver()
+ metadata.getTypeResolver()
.getTypeFactory()
.customCollection(
typeName,
@@ -500,7 +499,7 @@ private void processCollectionTypeInformation(PluralAttributeBinding attributeBi
}
private Type determineHibernateTypeFromCollectionType(PluralAttributeBinding attributeBinding) {
- final TypeFactory typeFactory = metadata().getTypeResolver().getTypeFactory();
+ final TypeFactory typeFactory = metadata.getTypeResolver().getTypeFactory();
switch ( attributeBinding.getAttribute().getNature() ) {
case SET: {
return typeFactory.set(