diff --git a/core/src/main/java/org/hibernate/cfg/Configuration.java b/core/src/main/java/org/hibernate/cfg/Configuration.java index 917542c977..8ea6c00aa7 100644 --- a/core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/core/src/main/java/org/hibernate/cfg/Configuration.java @@ -66,11 +66,15 @@ import org.hibernate.MappingException; import org.hibernate.MappingNotFoundException; import org.hibernate.SessionFactory; import org.hibernate.SessionFactoryObserver; +import org.hibernate.DuplicateMappingException; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.function.SQLFunction; import org.hibernate.engine.FilterDefinition; import org.hibernate.engine.Mapping; +import org.hibernate.engine.NamedQueryDefinition; +import org.hibernate.engine.NamedSQLQueryDefinition; +import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.event.AutoFlushEventListener; import org.hibernate.event.DeleteEventListener; import org.hibernate.event.DirtyCheckEventListener; @@ -115,6 +119,9 @@ import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.mapping.UniqueKey; import org.hibernate.mapping.FetchProfile; +import org.hibernate.mapping.DenormalizedTable; +import org.hibernate.mapping.TypeDef; +import org.hibernate.mapping.Column; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.secure.JACCConfiguration; import org.hibernate.tool.hbm2ddl.DatabaseMetadata; @@ -156,68 +163,73 @@ public class Configuration implements Serializable { protected Map collections; protected Map tables; protected List auxiliaryDatabaseObjects; - protected Map sqlFunctions; + protected Map namedQueries; protected Map namedSqlQueries; - /** - * Map result set name, result set description - */ - protected Map sqlResultSetMappings; + protected Map/**/ sqlResultSetMappings; + + protected Map typeDefs; protected Map filterDefinitions; protected Map fetchProfiles; + + protected Map tableNameBinding; + protected Map columnNameBindingPerTable; + protected List secondPasses; protected List propertyReferences; // protected List extendsQueue; protected Map extendsQueue; - protected Map tableNameBinding; - protected Map columnNameBindingPerTable; + + protected Map sqlFunctions; + private Interceptor interceptor; private Properties properties; private EntityResolver entityResolver; private EntityNotFoundDelegate entityNotFoundDelegate; protected transient XMLHelper xmlHelper; - protected transient Map typeDefs; - protected NamingStrategy namingStrategy; + private SessionFactoryObserver sessionFactoryObserver; private EventListeners eventListeners; protected final SettingsFactory settingsFactory; - private SessionFactoryObserver sessionFactoryObserver; + private transient Mapping mapping = buildMapping(); protected void reset() { classes = new HashMap(); imports = new HashMap(); collections = new HashMap(); tables = new TreeMap(); + namedQueries = new HashMap(); namedSqlQueries = new HashMap(); sqlResultSetMappings = new HashMap(); - xmlHelper = new XMLHelper(); + typeDefs = new HashMap(); + filterDefinitions = new HashMap(); + fetchProfiles = new HashMap(); + auxiliaryDatabaseObjects = new ArrayList(); + + tableNameBinding = new HashMap(); + columnNameBindingPerTable = new HashMap(); + propertyReferences = new ArrayList(); secondPasses = new ArrayList(); +// extendsQueue = new ArrayList(); + extendsQueue = new HashMap(); + + namingStrategy = DefaultNamingStrategy.INSTANCE; + xmlHelper = new XMLHelper(); interceptor = EmptyInterceptor.INSTANCE; properties = Environment.getProperties(); entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER; eventListeners = new EventListeners(); - filterDefinitions = new HashMap(); - fetchProfiles = new HashMap(); -// extendsQueue = new ArrayList(); - extendsQueue = new HashMap(); - auxiliaryDatabaseObjects = new ArrayList(); - tableNameBinding = new HashMap(); - columnNameBindingPerTable = new HashMap(); - namingStrategy = DefaultNamingStrategy.INSTANCE; + sqlFunctions = new HashMap(); } - private transient Mapping mapping = buildMapping(); - - - protected Configuration(SettingsFactory settingsFactory) { this.settingsFactory = settingsFactory; reset(); @@ -710,25 +722,7 @@ public class Configuration implements Serializable { * mappings to. */ public Mappings createMappings() { - return new Mappings( - classes, - collections, - tables, - namedQueries, - namedSqlQueries, - sqlResultSetMappings, - imports, - secondPasses, - propertyReferences, - namingStrategy, - typeDefs, - filterDefinitions, - fetchProfiles, - extendsQueue, - auxiliaryDatabaseObjects, - tableNameBinding, - columnNameBindingPerTable - ); + return new MappingsImpl(); } @@ -2185,8 +2179,8 @@ public class Configuration implements Serializable { filterDefinitions.put( definition.getFilterName(), definition ); } - public Map getFetchProfiles() { - return fetchProfiles; + public Iterator iterateFetchProfiles() { + return fetchProfiles.values().iterator(); } public void addFetchProfile(FetchProfile fetchProfile) { @@ -2212,4 +2206,494 @@ public class Configuration implements Serializable { public void setSessionFactoryObserver(SessionFactoryObserver sessionFactoryObserver) { this.sessionFactoryObserver = sessionFactoryObserver; } + + + // Mappings impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Internal implementation of the Mappings interface giving access to the Configuration's internal + * metadata repository state ({@link Configuration#classes}, {@link Configuration#tables}, etc). + */ + protected class MappingsImpl implements Mappings, Serializable { + + private String schemaName; + + public String getSchemaName() { + return schemaName; + } + + public void setSchemaName(String schemaName) { + this.schemaName = schemaName; + } + + + private String catalogName; + + public String getCatalogName() { + return catalogName; + } + + public void setCatalogName(String catalogName) { + this.catalogName = catalogName; + } + + + private String defaultPackage; + + public String getDefaultPackage() { + return defaultPackage; + } + + public void setDefaultPackage(String defaultPackage) { + this.defaultPackage = defaultPackage; + } + + + private boolean autoImport; + + public boolean isAutoImport() { + return autoImport; + } + + public void setAutoImport(boolean autoImport) { + this.autoImport = autoImport; + } + + + private boolean defaultLazy; + + public boolean isDefaultLazy() { + return defaultLazy; + } + + public void setDefaultLazy(boolean defaultLazy) { + this.defaultLazy = defaultLazy; + } + + + private String defaultCascade; + + public String getDefaultCascade() { + return defaultCascade; + } + + public void setDefaultCascade(String defaultCascade) { + this.defaultCascade = defaultCascade; + } + + + private String defaultAccess; + + public String getDefaultAccess() { + return defaultAccess; + } + + public void setDefaultAccess(String defaultAccess) { + this.defaultAccess = defaultAccess; + } + + + public NamingStrategy getNamingStrategy() { + return namingStrategy; + } + + public void setNamingStrategy(NamingStrategy namingStrategy) { + Configuration.this.namingStrategy = namingStrategy; + } + + + public Iterator iterateClasses() { + return classes.values().iterator(); + } + + public PersistentClass getClass(String entityName) { + return ( PersistentClass ) classes.get( entityName ); + } + + public PersistentClass locatePersistentClassByEntityName(String entityName) { + PersistentClass persistentClass = ( PersistentClass ) classes.get( entityName ); + if ( persistentClass == null ) { + String actualEntityName = ( String ) imports.get( entityName ); + if ( StringHelper.isNotEmpty( actualEntityName ) ) { + persistentClass = ( PersistentClass ) classes.get( actualEntityName ); + } + } + return persistentClass; + } + + public void addClass(PersistentClass persistentClass) throws DuplicateMappingException { + Object old = classes.put( persistentClass.getEntityName(), persistentClass ); + if ( old != null ) { + throw new DuplicateMappingException( "class/entity", persistentClass.getEntityName() ); + } + } + + public void addImport(String entityName, String rename) throws DuplicateMappingException { + String existing = ( String ) imports.put( rename, entityName ); + if ( existing != null ) { + if ( existing.equals( entityName ) ) { + log.info( "duplicate import: {} -> {}", entityName, rename ); + } + else { + throw new DuplicateMappingException( + "duplicate import: " + rename + " refers to both " + entityName + + " and " + existing + " (try using auto-import=\"false\")", + "import", + rename + ); + } + } + } + + public Collection getCollection(String role) { + return ( Collection ) collections.get( role ); + } + + public Iterator iterateCollections() { + return collections.values().iterator(); + } + + public void addCollection(Collection collection) throws DuplicateMappingException { + Object old = collections.put( collection.getRole(), collection ); + if ( old != null ) { + throw new DuplicateMappingException( "collection role", collection.getRole() ); + } + } + + public Table getTable(String schema, String catalog, String name) { + String key = Table.qualify(catalog, schema, name); + return (Table) tables.get(key); + } + + public Iterator iterateTables() { + return tables.values().iterator(); + } + + public Table addTable( + String schema, + String catalog, + String name, + String subselect, + boolean isAbstract) { + String key = subselect == null ? Table.qualify( catalog, schema, name ) : subselect; + Table table = ( Table ) tables.get( key ); + + if ( table == null ) { + table = new Table(); + table.setAbstract( isAbstract ); + table.setName( name ); + table.setSchema( schema ); + table.setCatalog( catalog ); + table.setSubselect( subselect ); + tables.put( key, table ); + } + else { + if ( !isAbstract ) { + table.setAbstract( false ); + } + } + + return table; + } + + public Table addDenormalizedTable( + String schema, + String catalog, + String name, + boolean isAbstract, + String subselect, + Table includedTable) throws DuplicateMappingException { + String key = subselect == null ? Table.qualify(catalog, schema, name) : subselect; + if ( tables.containsKey( key ) ) { + throw new DuplicateMappingException( "table", name ); + } + + Table table = new DenormalizedTable( includedTable ); + table.setAbstract( isAbstract ); + table.setName( name ); + table.setSchema( schema ); + table.setCatalog( catalog ); + table.setSubselect( subselect ); + + tables.put( key, table ); + return table; + } + + public NamedQueryDefinition getQuery(String name) { + return ( NamedQueryDefinition ) namedQueries.get( name ); + } + + public void addQuery(String name, NamedQueryDefinition query) throws DuplicateMappingException { + checkQueryName( name ); + namedQueries.put( name.intern(), query ); + } + + private void checkQueryName(String name) throws DuplicateMappingException { + if ( namedQueries.containsKey( name ) || namedSqlQueries.containsKey( name ) ) { + throw new DuplicateMappingException( "query", name ); + } + } + + public NamedSQLQueryDefinition getSQLQuery(String name) { + return ( NamedSQLQueryDefinition ) namedSqlQueries.get( name ); + } + + public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws DuplicateMappingException { + checkQueryName( name ); + namedSqlQueries.put( name.intern(), query ); + } + + public ResultSetMappingDefinition getResultSetMapping(String name) { + return (ResultSetMappingDefinition) sqlResultSetMappings.get(name); + } + + public void addResultSetMapping(ResultSetMappingDefinition sqlResultSetMapping) throws DuplicateMappingException { + Object old = sqlResultSetMappings.put( sqlResultSetMapping.getName(), sqlResultSetMapping ); + if ( old != null ) { + throw new DuplicateMappingException( "resultSet", sqlResultSetMapping.getName() ); + } + + } + + public TypeDef getTypeDef(String typeName) { + return ( TypeDef ) typeDefs.get( typeName ); + } + + public void addTypeDef(String typeName, String typeClass, Properties paramMap) { + TypeDef def = new TypeDef( typeClass, paramMap ); + typeDefs.put( typeName, def ); + log.debug( "Added " + typeName + " with class " + typeClass ); + } + + public Map getFilterDefinitions() { + return filterDefinitions; + } + + public FilterDefinition getFilterDefinition(String name) { + return ( FilterDefinition ) filterDefinitions.get( name ); + } + + public void addFilterDefinition(FilterDefinition definition) { + filterDefinitions.put( definition.getFilterName(), definition ); + } + + public FetchProfile findOrCreateFetchProfile(String name) { + FetchProfile profile = ( FetchProfile ) fetchProfiles.get( name ); + if ( profile == null ) { + profile = new FetchProfile( name ); + fetchProfiles.put( name, profile ); + } + return profile; + } + + public Iterator iterateAuxliaryDatabaseObjects() { + return auxiliaryDatabaseObjects.iterator(); + } + + public ListIterator iterateAuxliaryDatabaseObjectsInReverse() { + return auxiliaryDatabaseObjects.listIterator( auxiliaryDatabaseObjects.size() ); + } + + public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) { + auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject ); + } + + /** + * Internal struct used to help track physical table names to logical table names. + */ + private class TableDescription implements Serializable { + final String logicalName; + final Table denormalizedSupertable; + + TableDescription(String logicalName, Table denormalizedSupertable) { + this.logicalName = logicalName; + this.denormalizedSupertable = denormalizedSupertable; + } + } + + public String getLogicalTableName(Table table) throws MappingException { + return getLogicalTableName( table.getQuotedSchema(), table.getCatalog(), table.getQuotedName() ); + } + + private String getLogicalTableName(String schema, String catalog, String physicalName) throws MappingException { + String key = buildTableNameKey( schema, catalog, physicalName ); + TableDescription descriptor = (TableDescription) tableNameBinding.get( key ); + if (descriptor == null) { + throw new MappingException( "Unable to find physical table: " + physicalName); + } + return descriptor.logicalName; + } + + public void addTableBinding( + String schema, + String catalog, + String logicalName, + String physicalName, + Table denormalizedSuperTable) throws DuplicateMappingException { + String key = buildTableNameKey( schema, catalog, physicalName ); + TableDescription tableDescription = new TableDescription( logicalName, denormalizedSuperTable ); + TableDescription oldDescriptor = ( TableDescription ) tableNameBinding.put( key, tableDescription ); + if ( oldDescriptor != null && ! oldDescriptor.logicalName.equals( logicalName ) ) { + //TODO possibly relax that + throw new DuplicateMappingException( + "Same physical table name [" + physicalName + "] references several logical table names: [" + + oldDescriptor.logicalName + "], [" + logicalName + ']', + "table", + physicalName + ); + } + } + + private String buildTableNameKey(String schema, String catalog, String finalName) { + StringBuffer keyBuilder = new StringBuffer(); + if (schema != null) keyBuilder.append( schema ); + keyBuilder.append( "."); + if (catalog != null) keyBuilder.append( catalog ); + keyBuilder.append( "."); + keyBuilder.append( finalName ); + return keyBuilder.toString(); + } + + /** + * Internal struct used to maintain xref between physical and logical column + * names for a table. Mainly this is used to ensure that the defined + * {@link NamingStrategy} is not creating duplicate column names. + */ + private class TableColumnNameBinding implements Serializable { + private final String tableName; + private Map/**/ logicalToPhysical = new HashMap(); + private Map/**/ physicalToLogical = new HashMap(); + + private TableColumnNameBinding(String tableName) { + this.tableName = tableName; + } + + public void addBinding(String logicalName, Column physicalColumn) { + bindLogicalToPhysical( logicalName, physicalColumn ); + bindPhysicalToLogical( logicalName, physicalColumn ); + } + + private void bindLogicalToPhysical(String logicalName, Column physicalColumn) throws DuplicateMappingException { + final String logicalKey = logicalName.toLowerCase(); + final String physicalName = physicalColumn.getQuotedName(); + final String existingPhysicalName = ( String ) logicalToPhysical.put( logicalKey, physicalName ); + if ( existingPhysicalName != null ) { + boolean areSamePhysicalColumn = physicalColumn.isQuoted() + ? existingPhysicalName.equals( physicalName ) + : existingPhysicalName.equalsIgnoreCase( physicalName ); + if ( ! areSamePhysicalColumn ) { + throw new DuplicateMappingException( + " Table [" + tableName + "] contains logical column name [" + logicalName + + "] referenced by multiple physical column names: [" + existingPhysicalName + + "], [" + physicalName + "]", + "column-binding", + tableName + "." + logicalName + ); + } + } + } + + private void bindPhysicalToLogical(String logicalName, Column physicalColumn) throws DuplicateMappingException { + final String physicalName = physicalColumn.getQuotedName(); + final String existingLogicalName = ( String ) physicalToLogical.put( physicalName, logicalName ); + if ( existingLogicalName != null && ! existingLogicalName.equals( logicalName ) ) { + throw new DuplicateMappingException( + " Table [" + tableName + "] contains phyical column name [" + physicalName + + "] represented by different logical column names: [" + existingLogicalName + + "], [" + logicalName + "]", + "column-binding", + tableName + "." + physicalName + ); + } + } + } + + public void addColumnBinding(String logicalName, Column physicalColumn, Table table) throws DuplicateMappingException { + TableColumnNameBinding binding = ( TableColumnNameBinding ) columnNameBindingPerTable.get( table ); + if ( binding == null ) { + binding = new TableColumnNameBinding( table.getName() ); + columnNameBindingPerTable.put( table, binding ); + } + binding.addBinding( logicalName, physicalColumn ); + } + + public String getPhysicalColumnName(String logicalName, Table table) throws MappingException { + logicalName = logicalName.toLowerCase(); + String finalName = null; + Table currentTable = table; + do { + TableColumnNameBinding binding = ( TableColumnNameBinding ) columnNameBindingPerTable.get( currentTable ); + if ( binding != null ) { + finalName = ( String ) binding.logicalToPhysical.get( logicalName ); + } + String key = buildTableNameKey( + currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() + ); + TableDescription description = ( TableDescription ) tableNameBinding.get( key ); + if ( description != null ) { + currentTable = description.denormalizedSupertable; + } + } while ( finalName == null && currentTable != null ); + + if ( finalName == null ) { + throw new MappingException( + "Unable to find column with logical name " + logicalName + " in table " + table.getName() + ); + } + return finalName; + } + + public String getLogicalColumnName(String physicalName, Table table) throws MappingException { + String logical = null; + Table currentTable = table; + TableDescription description = null; + do { + TableColumnNameBinding binding = ( TableColumnNameBinding ) columnNameBindingPerTable.get( currentTable ); + if ( binding != null ) { + logical = ( String ) binding.physicalToLogical.get( physicalName ); + } + String key = buildTableNameKey( + currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() + ); + description = ( TableDescription ) tableNameBinding.get( key ); + if ( description != null ) { + currentTable = description.denormalizedSupertable; + } + } + while ( logical == null && currentTable != null && description != null ); + if ( logical == null ) { + throw new MappingException( + "Unable to find logical column name from physical name " + + physicalName + " in table " + table.getName() + ); + } + return logical; + } + + public void addSecondPass(SecondPass sp) { + addSecondPass( sp, false ); + } + + public void addSecondPass(SecondPass sp, boolean onTopOfTheQueue) { + if ( onTopOfTheQueue ) { + secondPasses.add( 0, sp ); + } + else { + secondPasses.add( sp ); + } + } + + public void addPropertyReference(String referencedClass, String propertyName) { + propertyReferences.add( new PropertyReference( referencedClass, propertyName, false ) ); + } + + public void addUniquePropertyReference(String referencedClass, String propertyName) { + propertyReferences.add( new PropertyReference( referencedClass, propertyName, true ) ); + } + + public void addToExtendsQueue(ExtendsQueueEntry entry) { + extendsQueue.put( entry, null ); + } + + } } diff --git a/core/src/main/java/org/hibernate/cfg/Mappings.java b/core/src/main/java/org/hibernate/cfg/Mappings.java index 2d458295a9..c653b3993b 100644 --- a/core/src/main/java/org/hibernate/cfg/Mappings.java +++ b/core/src/main/java/org/hibernate/cfg/Mappings.java @@ -26,13 +26,10 @@ package org.hibernate.cfg; import java.io.Serializable; import java.util.Iterator; -import java.util.List; -import java.util.Map; import java.util.Properties; -import java.util.HashMap; +import java.util.Map; +import java.util.ListIterator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.DuplicateMappingException; import org.hibernate.MappingException; import org.hibernate.engine.FilterDefinition; @@ -40,542 +37,485 @@ import org.hibernate.engine.NamedQueryDefinition; import org.hibernate.engine.NamedSQLQueryDefinition; import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.mapping.Collection; -import org.hibernate.mapping.DenormalizedTable; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Table; import org.hibernate.mapping.TypeDef; import org.hibernate.mapping.AuxiliaryDatabaseObject; import org.hibernate.mapping.Column; import org.hibernate.mapping.FetchProfile; -import org.hibernate.util.StringHelper; /** - * A collection of mappings from classes and collections to - * relational database tables. (Represents a single - * <hibernate-mapping> element.) + * A collection of mappings from classes and collections to relational database tables. Represents a single + * <hibernate-mapping> element. + *

+ * todo : the statement about this representing a single mapping element is simply not true if it was ever the case. + * this contract actually represents 3 scopes of information:

    + *
  1. bounded state : this is information which is indeed scoped by a single mapping
  2. + *
  3. unbounded state : this is information which is Configuration wide (think of metadata repository)
  4. + *
  5. transient state : state which changed at its own pace (naming strategy)
  6. + *
+ * * @author Gavin King + * @author Steve Ebersole */ -public class Mappings implements Serializable { - - private static final Logger log = LoggerFactory.getLogger(Mappings.class); - - protected final Map classes; - protected final Map collections; - protected final Map tables; - protected final Map queries; - protected final Map sqlqueries; - protected final Map resultSetMappings; - protected final Map typeDefs; - protected final List secondPasses; - protected final Map imports; - protected String schemaName; - protected String catalogName; - protected String defaultCascade; - protected String defaultPackage; - protected String defaultAccess; - protected boolean autoImport; - protected boolean defaultLazy; - protected final List propertyReferences; - protected final NamingStrategy namingStrategy; - protected final Map filterDefinitions; - protected final Map fetchProfiles; - protected final List auxiliaryDatabaseObjects; - - protected final Map extendsQueue; -// private final List extendsQueue; +public interface Mappings { /** - * binding table between the logical column name and the name out of the naming strategy - * for each table. - * According that when the column name is not set, the property name is considered as such - * This means that while theorically possible through the naming strategy contract, it is - * forbidden to have 2 real columns having the same logical name - * + * Get the current naming strategy. + * + * @return The current naming strategy. */ - protected final Map columnNameBindingPerTable; - /** - * binding between logical table name and physical one (ie after the naming strategy has been applied) - * - */ - protected final Map tableNameBinding; - - - Mappings( - final Map classes, - final Map collections, - final Map tables, - final Map queries, - final Map sqlqueries, - final Map sqlResultSetMappings, - final Map imports, - final List secondPasses, - final List propertyReferences, - final NamingStrategy namingStrategy, - final Map typeDefs, - final Map filterDefinitions, - final Map fetchProfiles, -// final List extendsQueue, - final Map extendsQueue, - final List auxiliaryDatabaseObjects, - final Map tableNamebinding, - final Map columnNameBindingPerTable) { - this.classes = classes; - this.collections = collections; - this.queries = queries; - this.sqlqueries = sqlqueries; - this.resultSetMappings = sqlResultSetMappings; - this.tables = tables; - this.imports = imports; - this.secondPasses = secondPasses; - this.propertyReferences = propertyReferences; - this.namingStrategy = namingStrategy; - this.typeDefs = typeDefs; - this.filterDefinitions = filterDefinitions; - this.fetchProfiles = fetchProfiles; - this.extendsQueue = extendsQueue; - this.auxiliaryDatabaseObjects = auxiliaryDatabaseObjects; - this.tableNameBinding = tableNamebinding; - this.columnNameBindingPerTable = columnNameBindingPerTable; - } - - public void addClass(PersistentClass persistentClass) throws MappingException { - Object old = classes.put( persistentClass.getEntityName(), persistentClass ); - if ( old!=null ) { - throw new DuplicateMappingException( "class/entity", persistentClass.getEntityName() ); - } - } - public void addCollection(Collection collection) throws MappingException { - Object old = collections.put( collection.getRole(), collection ); - if ( old!=null ) { - throw new DuplicateMappingException( "collection role", collection.getRole() ); - } - } - public PersistentClass getClass(String className) { - return (PersistentClass) classes.get(className); - } - public Collection getCollection(String role) { - return (Collection) collections.get(role); - } - - public void addImport(String className, String rename) throws MappingException { - String existing = (String) imports.put(rename, className); - if ( existing!=null ) { - if ( existing.equals(className) ) { - log.info( "duplicate import: " + className + "->" + rename ); - } - else { - throw new DuplicateMappingException( - "duplicate import: " + rename + - " refers to both " + className + - " and " + existing + - " (try using auto-import=\"false\")", - "import", - rename - ); - } - } - } - - public Table addTable(String schema, - String catalog, - String name, - String subselect, - boolean isAbstract - ) { - String key = subselect==null ? - Table.qualify(catalog, schema, name) : - subselect; - Table table = (Table) tables.get(key); - - if (table == null) { - table = new Table(); - table.setAbstract(isAbstract); - table.setName(name); - table.setSchema(schema); - table.setCatalog(catalog); - table.setSubselect(subselect); - tables.put(key, table); - } - else { - if (!isAbstract) table.setAbstract(false); - } - - return table; - } - - public Table addDenormalizedTable( - String schema, - String catalog, - String name, - boolean isAbstract, - String subselect, - Table includedTable) - throws MappingException { - String key = subselect==null ? - Table.qualify(catalog, schema, name) : - subselect; - if ( tables.containsKey(key) ) { - throw new DuplicateMappingException("table", name); - } - - Table table = new DenormalizedTable(includedTable); - table.setAbstract(isAbstract); - table.setName(name); - table.setSchema(schema); - table.setCatalog(catalog); - table.setSubselect(subselect); - tables.put(key, table); - return table; - } - - public Table getTable(String schema, String catalog, String name) { - String key = Table.qualify(catalog, schema, name); - return (Table) tables.get(key); - } - - public String getSchemaName() { - return schemaName; - } - - public String getCatalogName() { - return catalogName; - } - - public String getDefaultCascade() { - return defaultCascade; - } + public NamingStrategy getNamingStrategy(); /** - * Sets the schemaName. - * @param schemaName The schemaName to set + * Set the current naming strategy. + * + * @param namingStrategy The naming strategy to use. */ - public void setSchemaName(String schemaName) { - this.schemaName = schemaName; - } + public void setNamingStrategy(NamingStrategy namingStrategy); + + /** + * Returns the currently bound default schema name. + * + * @return The currently bound schema name + */ + public String getSchemaName(); + + /** + * Sets the currently bound default schema name. + * + * @param schemaName The schema name to bind as the current default. + */ + public void setSchemaName(String schemaName); + + /** + * Returns the currently bound default catalog name. + * + * @return The currently bound catalog name, or null if none. + */ + public String getCatalogName(); /** - * Sets the catalogName. - * @param catalogName The catalogName to set + * Sets the currently bound default catalog name. + * + * @param catalogName The catalog name to use as the current default. */ - public void setCatalogName(String catalogName) { - this.catalogName = catalogName; - } + public void setCatalogName(String catalogName); /** - * Sets the defaultCascade. - * @param defaultCascade The defaultCascade to set + * Get the currently bound default package name. + * + * @return The currently bound default package name */ - public void setDefaultCascade(String defaultCascade) { - this.defaultCascade = defaultCascade; - } + public String getDefaultPackage(); /** - * sets the default access strategy - * @param defaultAccess the default access strategy. + * Set the current default package name. + * + * @param defaultPackage The package name to set as the current default. */ - public void setDefaultAccess(String defaultAccess) { - this.defaultAccess = defaultAccess; - } - - public String getDefaultAccess() { - return defaultAccess; - } - - public void addQuery(String name, NamedQueryDefinition query) throws MappingException { - checkQueryExist(name); - queries.put( name.intern(), query ); - } - - public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws MappingException { - checkQueryExist(name); - sqlqueries.put( name.intern(), query ); - } - - private void checkQueryExist(String name) throws MappingException { - if ( sqlqueries.containsKey(name) || queries.containsKey(name) ) { - throw new DuplicateMappingException("query", name); - } - } - - public void addResultSetMapping(ResultSetMappingDefinition sqlResultSetMapping) { - final String name = sqlResultSetMapping.getName(); - if ( resultSetMappings.containsKey(name) ) { - throw new DuplicateMappingException("resultSet", name); - } - resultSetMappings.put(name, sqlResultSetMapping); - } - - public ResultSetMappingDefinition getResultSetMapping(String name) { - return (ResultSetMappingDefinition) resultSetMappings.get(name); - } - - - public NamedQueryDefinition getQuery(String name) { - return (NamedQueryDefinition) queries.get(name); - } - - public void addSecondPass(SecondPass sp) { - addSecondPass(sp, false); - } - - public void addSecondPass(SecondPass sp, boolean onTopOfTheQueue) { - if (onTopOfTheQueue) { - secondPasses.add(0, sp); - } - else { - secondPasses.add(sp); - } - } + public void setDefaultPackage(String defaultPackage); /** - * Returns the autoImport. - * @return boolean + * Determine whether auto importing of entity names is currently enabled. + * + * @return True if currently enabled; false otherwise. */ - public boolean isAutoImport() { - return autoImport; - } + public boolean isAutoImport(); /** - * Sets the autoImport. - * @param autoImport The autoImport to set + * Set whether to enable auto importing of entity names. + * + * @param autoImport True to enable; false to diasable. + * @see #addImport */ - public void setAutoImport(boolean autoImport) { - this.autoImport = autoImport; - } - - void addUniquePropertyReference(String referencedClass, String propertyName) { - PropertyReference upr = new PropertyReference(); - upr.referencedClass = referencedClass; - upr.propertyName = propertyName; - upr.unique = true; - propertyReferences.add(upr); - } - - void addPropertyReference(String referencedClass, String propertyName) { - PropertyReference upr = new PropertyReference(); - upr.referencedClass = referencedClass; - upr.propertyName = propertyName; - propertyReferences.add(upr); - } - - private String buildTableNameKey(String schema, String catalog, String finalName) { - StringBuffer keyBuilder = new StringBuffer(); - if (schema != null) keyBuilder.append( schema ); - keyBuilder.append( "."); - if (catalog != null) keyBuilder.append( catalog ); - keyBuilder.append( "."); - keyBuilder.append( finalName ); - return keyBuilder.toString(); - } - - static final class PropertyReference implements Serializable { - String referencedClass; - String propertyName; - boolean unique; - } + public void setAutoImport(boolean autoImport); /** - * @return Returns the defaultPackage. + * Determine whether default laziness is currently enabled. + * + * @return True if enabled, false otherwise. */ - public String getDefaultPackage() { - return defaultPackage; - } + public boolean isDefaultLazy(); /** - * @param defaultPackage The defaultPackage to set. + * Set whether to enable default laziness. + * + * @param defaultLazy True to enable, false to disable. */ - public void setDefaultPackage(String defaultPackage) { - this.defaultPackage = defaultPackage; - } + public void setDefaultLazy(boolean defaultLazy); - public NamingStrategy getNamingStrategy() { - return namingStrategy; - } + /** + * Get the current default cascade style. + * + * @return The current default cascade style. + */ + public String getDefaultCascade(); - public void addTypeDef(String typeName, String typeClass, Properties paramMap) { - TypeDef def = new TypeDef(typeClass, paramMap); - typeDefs.put(typeName, def); - log.debug("Added " + typeName + " with class " + typeClass); - } + /** + * Sets the current default cascade style. + * . + * @param defaultCascade The cascade style to set as the current default. + */ + public void setDefaultCascade(String defaultCascade); - public TypeDef getTypeDef(String typeName) { - return (TypeDef) typeDefs.get(typeName); - } + /** + * Get the current default property access style. + * + * @return The current default property access style. + */ + public String getDefaultAccess(); - public Iterator iterateCollections() { - return collections.values().iterator(); - } - - public Iterator iterateTables() { - return tables.values().iterator(); - } + /** + * Sets the current default property access style. + * + * @param defaultAccess The access style to use as the current default. + */ + public void setDefaultAccess(String defaultAccess); - public Map getFilterDefinitions() { - return filterDefinitions; - } - public void addFilterDefinition(FilterDefinition definition) { - filterDefinitions.put( definition.getFilterName(), definition ); - } - - public FilterDefinition getFilterDefinition(String name) { - return (FilterDefinition) filterDefinitions.get(name); - } + /** + * Retrieves an iterator over the entity metadata present in this repository. + * + * @return Iterator over class metadata. + */ + public Iterator iterateClasses(); - public Map getFetchProfiles() { - return fetchProfiles; - } + /** + * Retrieves the entity mapping metadata for the given entity name. + * + * @param entityName The entity name for which to retrieve the metadata. + * @return The entity mapping metadata, or null if none found matching given entity name. + */ + public PersistentClass getClass(String entityName); - public FetchProfile findOrCreateFetchProfile(String name) { - FetchProfile profile = ( FetchProfile ) fetchProfiles.get( name ); - if ( profile == null ) { - profile = new FetchProfile( name ); - fetchProfiles.put( name, profile ); - } - return profile; - } + /** + * Retrieves the entity mapping metadata for the given entity name, potentially accounting + * for imports. + * + * @param entityName The entity name for which to retrieve the metadata. + * @return The entity mapping metadata, or null if none found matching given entity name. + */ + public PersistentClass locatePersistentClassByEntityName(String entityName); - public boolean isDefaultLazy() { - return defaultLazy; - } - public void setDefaultLazy(boolean defaultLazy) { - this.defaultLazy = defaultLazy; - } + /** + * Add entity mapping metadata. + * + * @param persistentClass The entity metadata + * @throws DuplicateMappingException Indicates there4 was already an extry + * corresponding to the given entity name. + */ + public void addClass(PersistentClass persistentClass) throws DuplicateMappingException; - public void addToExtendsQueue(ExtendsQueueEntry entry) { - extendsQueue.put( entry, null ); - } + /** + * Adds an import (HQL entity rename) to the repository. + * + * @param entityName The entity name being renamed. + * @param rename The rename + * @throws DuplicateMappingException If rename already is mapped to another + * entity name in this repository. + */ + public void addImport(String entityName, String rename) throws DuplicateMappingException; - public PersistentClass locatePersistentClassByEntityName(String entityName) { - PersistentClass persistentClass = ( PersistentClass ) classes.get( entityName ); - if ( persistentClass == null ) { - String actualEntityName = ( String ) imports.get( entityName ); - if ( StringHelper.isNotEmpty( actualEntityName ) ) { - persistentClass = ( PersistentClass ) classes.get( actualEntityName ); - } - } - return persistentClass; - } + /** + * Retrieves the collection mapping metadata for the given collection role. + * + * @param role The collection role for which to retrieve the metadata. + * @return The collection mapping metadata, or null if no matching collection role found. + */ + public Collection getCollection(String role); - public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) { - auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject ); - } + /** + * Returns an iterator over collection metadata. + * + * @return Iterator over collection metadata. + */ + public Iterator iterateCollections(); + /** + * Add collection mapping metadata to this repository. + * + * @param collection The collection metadata + * @throws DuplicateMappingException Indicates there was already an entry + * corresponding to the given collection role + */ + public void addCollection(Collection collection) throws DuplicateMappingException; + + /** + * Returns the named table metadata. + * + * @param schema The named schema in which the table belongs (or null). + * @param catalog The named catalog in which the table belongs (or null). + * @param name The table name + * @return The table metadata, or null. + */ + public Table getTable(String schema, String catalog, String name); + + /** + * Returns an iterator over table metadata. + * + * @return Iterator over table metadata. + */ + public Iterator iterateTables(); + + /** + * Adds table metedata to this repository returning the created + * metadata instance. + * + * @param schema The named schema in which the table belongs (or null). + * @param catalog The named catalog in which the table belongs (or null). + * @param name The table name + * @param subselect A select statement wwich defines a logical table, much + * like a DB view. + * @param isAbstract Is the table abstract (i.e. not really existing in the DB)? + * @return The created table metadata, or the existing reference. + */ + public Table addTable(String schema, String catalog, String name, String subselect, boolean isAbstract); + + /** + * Adds a 'denormalized table' to this repository. + * + * @param schema The named schema in which the table belongs (or null). + * @param catalog The named catalog in which the table belongs (or null). + * @param name The table name + * @param isAbstract Is the table abstract (i.e. not really existing in the DB)? + * @param subselect A select statement wwich defines a logical table, much + * like a DB view. + * @param includedTable ??? + * @return The created table metadata. + * @throws DuplicateMappingException If such a table mapping already exists. + */ + public Table addDenormalizedTable(String schema, String catalog, String name, boolean isAbstract, String subselect, Table includedTable) + throws DuplicateMappingException; + + /** + * Get named query metadata by name. + * + * @param name The named query name + * @return The query metadata, or null. + */ + public NamedQueryDefinition getQuery(String name); + + /** + * Adds metadata for a named query to this repository. + * + * @param name The name + * @param query The metadata + * @throws DuplicateMappingException If a query already exists with that name. + */ + public void addQuery(String name, NamedQueryDefinition query) throws DuplicateMappingException; + + /** + * Get named SQL query metadata. + * + * @param name The named SQL query name. + * @return The meatdata, or null if none found. + */ + public NamedSQLQueryDefinition getSQLQuery(String name); + + /** + * Adds metadata for a named SQL query to this repository. + * + * @param name The name + * @param query The metadata + * @throws DuplicateMappingException If a query already exists with that name. + */ + public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws DuplicateMappingException; + + /** + * Get the metadata for a named SQL result set mapping. + * + * @param name The mapping name. + * @return The SQL result set mapping metadat, or null if none found. + */ + public ResultSetMappingDefinition getResultSetMapping(String name); + + /** + * Adds the metadata for a named SQL result set mapping to this repository. + * + * @param sqlResultSetMapping The metadata + * @throws DuplicateMappingException If metadata for another SQL result mapping was + * already found under the given name. + */ + public void addResultSetMapping(ResultSetMappingDefinition sqlResultSetMapping) throws DuplicateMappingException; + + /** + * Retrieve a type definition by name. + * + * @param typeName The name of the type definition to retrieve. + * @return The type definition, or null if none found. + */ + public TypeDef getTypeDef(String typeName); + + /** + * Adds a type definition to this metadata repository. + * + * @param typeName The type name. + * @param typeClass The class implementing the {@link org.hibernate.type.Type} contract. + * @param paramMap Map of parameters to be used to configure the type after instantiation. + */ + public void addTypeDef(String typeName, String typeClass, Properties paramMap); + + /** + * Retrieves the copmplete map of filter definitions. + * + * @return The filter definition map. + */ + public Map getFilterDefinitions(); + + /** + * Retrieves a filter definition by name. + * + * @param name The name of the filter defintion to retrieve. + * @return The filter definition, or null. + */ + public FilterDefinition getFilterDefinition(String name); + + /** + * Adds a filter definition to this repository. + * + * @param definition The filter definition to add. + */ + public void addFilterDefinition(FilterDefinition definition); + + /** + * Retrieves a fetch profile by either finding one currently in this repository matching the given name + * or by creating one (and adding it). + * + * @param name The name of the profile. + * @return The fetch profile metadata. + */ + public FetchProfile findOrCreateFetchProfile(String name); + + /** + * Retrieves an iterator over the metadata pertaining to all auxilary database objects int this repository. + * + * @return Iterator over the auxilary database object metadata. + */ + public Iterator iterateAuxliaryDatabaseObjects(); + + /** + * Same as {@link #iterateAuxliaryDatabaseObjects()} except that here the iterator is reversed. + * + * @return The reversed iterator. + */ + public ListIterator iterateAuxliaryDatabaseObjectsInReverse(); + + /** + * Add metadata pertaining to an auxilary database object to this repository. + * + * @param auxiliaryDatabaseObject The metadata. + */ + public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject); + + /** + * Get the logical table name mapped for the given physical table. + * + * @param table The table for which to determine the logical name. + * @return The logical name. + * @throws MappingException Indicates that no logical name was bound for the given physical table. + */ + public String getLogicalTableName(Table table) throws MappingException; + + /** + * Adds a table binding to this repository. + * + * @param schema The schema in which the table belongs (may be null). + * @param catalog The catalog in which the table belongs (may be null). + * @param logicalName The logical table name. + * @param physicalName The physical table name. + * @param denormalizedSuperTable ??? + * @throws DuplicateMappingException Indicates physical table was already bound to another logical name. + */ public void addTableBinding( - String schema, String catalog, String logicalName, String physicalName, Table denormalizedSuperTable - ) { - String key = buildTableNameKey( schema, catalog, physicalName ); - TableDescription tableDescription = new TableDescription( - logicalName, denormalizedSuperTable - ); - TableDescription oldDescriptor = (TableDescription) tableNameBinding.put( key, tableDescription ); - if ( oldDescriptor != null && ! oldDescriptor.logicalName.equals( logicalName ) ) { - //TODO possibly relax that - throw new MappingException("Same physical table name reference several logical table names: " - + physicalName + " => " + "'" + oldDescriptor.logicalName + "' and '" + logicalName + "'"); + String schema, + String catalog, + String logicalName, + String physicalName, + Table denormalizedSuperTable) throws DuplicateMappingException; + + /** + * Binds the given 'physicalColumn' to the give 'logicalName' within the given 'table'. + * + * @param logicalName The logical column name binding. + * @param physicalColumn The physical column metadata. + * @param table The table metadata. + * @throws DuplicateMappingException Indicates a duplicate binding for either the physical column name + * or the logical column name. + */ + public void addColumnBinding(String logicalName, Column physicalColumn, Table table) throws DuplicateMappingException; + + /** + * Find the physical column name for the given logical column name within the given table. + * + * @param logicalName The logical name binding. + * @param table The table metatdata. + * @return The physical column name. + * @throws MappingException Indicates that no such binding was found. + */ + public String getPhysicalColumnName(String logicalName, Table table) throws MappingException; + + /** + * Find the logical column name against whcih the given physical column name was bound within the given table. + * + * @param physicalName The physical column name + * @param table The table metadata. + * @return The logical column name. + * @throws MappingException Indicates that no such binding was found. + */ + public String getLogicalColumnName(String physicalName, Table table) throws MappingException; + + /** + * Adds a second-pass to the end of the current queue. + * + * @param sp The second pass to add. + */ + public void addSecondPass(SecondPass sp); + + /** + * Adds a second pass. + * @param sp The second pass to add. + * @param onTopOfTheQueue True to add to the beginning of the queue; false to add to the end. + */ + public void addSecondPass(SecondPass sp, boolean onTopOfTheQueue); + + /** + * Represents a property-ref mapping. + *

+ * TODO : currently needs to be exposed because Configuration needs access to it for second-pass processing + */ + public static final class PropertyReference implements Serializable { + public final String referencedClass; + public final String propertyName; + public final boolean unique; + + public PropertyReference(String referencedClass, String propertyName, boolean unique) { + this.referencedClass = referencedClass; + this.propertyName = propertyName; + this.unique = unique; } } - public void addColumnBinding(String logicalName, Column finalColumn, Table table) { - ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(table); - if (binding == null) { - binding = new ColumnNames(); - columnNameBindingPerTable.put(table, binding); - } - String oldFinalName = (String) binding.logicalToPhysical.put( - logicalName.toLowerCase(), - finalColumn.getQuotedName() - ); - if ( oldFinalName != null && - ! ( finalColumn.isQuoted() ? - oldFinalName.equals( finalColumn.getQuotedName() ) : - oldFinalName.equalsIgnoreCase( finalColumn.getQuotedName() ) ) ) { - //TODO possibly relax that - throw new MappingException("Same logical column name referenced by different physical ones: " - + table.getName() + "." + logicalName + " => '" + oldFinalName + "' and '" + finalColumn.getQuotedName() + "'" ); - } - String oldLogicalName = (String) binding.physicalToLogical.put( - finalColumn.getQuotedName(), - logicalName - ); - if ( oldLogicalName != null && ! oldLogicalName.equals( logicalName ) ) { - //TODO possibly relax that - throw new MappingException("Same physical column represented by different logical column names: " - + table.getName() + "." + finalColumn.getQuotedName() + " => '" + oldLogicalName + "' and '" + logicalName + "'"); - } - } + /** + * Adds a property reference binding to this repository. + * + * @param referencedClass The referenced entity name. + * @param propertyName The referenced property name. + */ + public void addPropertyReference(String referencedClass, String propertyName); - private String getLogicalTableName(String schema, String catalog, String physicalName) { - String key = buildTableNameKey( schema, catalog, physicalName ); - TableDescription descriptor = (TableDescription) tableNameBinding.get( key ); - if (descriptor == null) { - throw new MappingException( "Unable to find physical table: " + physicalName); - } - return descriptor.logicalName; - } + /** + * Adds a property reference binding to this repository where said proeprty reference is marked as unique. + * + * @param referencedClass The referenced entity name. + * @param propertyName The referenced property name. + */ + public void addUniquePropertyReference(String referencedClass, String propertyName); - public String getPhysicalColumnName(String logicalName, Table table) { - logicalName = logicalName.toLowerCase(); - String finalName = null; - Table currentTable = table; - do { - ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(currentTable); - if (binding != null) { - finalName = (String) binding.logicalToPhysical.get( logicalName ); - } - String key = buildTableNameKey( currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() ); - TableDescription description = (TableDescription) tableNameBinding.get(key); - if (description != null) currentTable = description.denormalizedSupertable; - } - while (finalName == null && currentTable != null); - if (finalName == null) { - throw new MappingException( "Unable to find column with logical name " - + logicalName + " in table " + table.getName() ); - } - return finalName; - } - - public String getLogicalColumnName(String physicalName, Table table) { - String logical = null; - Table currentTable = table; - TableDescription description = null; - do { - ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(currentTable); - if (binding != null) { - logical = (String) binding.physicalToLogical.get( physicalName ); - } - String key = buildTableNameKey( currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() ); - description = (TableDescription) tableNameBinding.get(key); - if (description != null) currentTable = description.denormalizedSupertable; - } - while (logical == null && currentTable != null && description != null); - if (logical == null) { - throw new MappingException( "Unable to find logical column name from physical name " - + physicalName + " in table " + table.getName() ); - } - return logical; - } - - public String getLogicalTableName(Table table) { - return getLogicalTableName( table.getQuotedSchema(), table.getCatalog(), table.getQuotedName() ); - } - - static public class ColumnNames implements Serializable { - // - public Map logicalToPhysical = new HashMap(); - // - public Map physicalToLogical = new HashMap(); - public ColumnNames() { - } - } - - static public class TableDescription implements Serializable { - public TableDescription(String logicalName, Table denormalizedSupertable) { - this.logicalName = logicalName; - this.denormalizedSupertable = denormalizedSupertable; - } - - public String logicalName; - public Table denormalizedSupertable; - } + /** + * Adds an entry to the extends queue queue. + * + * @param entry The entry to add. + */ + public void addToExtendsQueue(ExtendsQueueEntry entry); } \ No newline at end of file diff --git a/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java b/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java index b099e61e6f..79ca7b5693 100644 --- a/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java +++ b/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java @@ -420,7 +420,7 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI // this needs to happen after persisters are all ready to go... this.fetchProfiles = new HashMap(); - itr = cfg.getFetchProfiles().values().iterator(); + itr = cfg.iterateFetchProfiles(); while ( itr.hasNext() ) { final org.hibernate.mapping.FetchProfile mappingProfile = ( org.hibernate.mapping.FetchProfile ) itr.next();