HHH-3439 : Mappings

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@15210 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2008-09-17 16:44:23 +00:00
parent 3a23f9d1b8
commit aa7f7a7822
3 changed files with 956 additions and 532 deletions

View File

@ -66,11 +66,15 @@ import org.hibernate.MappingException;
import org.hibernate.MappingNotFoundException; import org.hibernate.MappingNotFoundException;
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
import org.hibernate.SessionFactoryObserver; import org.hibernate.SessionFactoryObserver;
import org.hibernate.DuplicateMappingException;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.function.SQLFunction; import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.FilterDefinition; import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.Mapping; 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.AutoFlushEventListener;
import org.hibernate.event.DeleteEventListener; import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.DirtyCheckEventListener; import org.hibernate.event.DirtyCheckEventListener;
@ -115,6 +119,9 @@ import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey; import org.hibernate.mapping.UniqueKey;
import org.hibernate.mapping.FetchProfile; 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.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.JACCConfiguration; import org.hibernate.secure.JACCConfiguration;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata; import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
@ -156,68 +163,73 @@ public class Configuration implements Serializable {
protected Map collections; protected Map collections;
protected Map tables; protected Map tables;
protected List auxiliaryDatabaseObjects; protected List auxiliaryDatabaseObjects;
protected Map sqlFunctions;
protected Map namedQueries; protected Map namedQueries;
protected Map namedSqlQueries; protected Map namedSqlQueries;
/** protected Map/*<String, SqlResultSetMapping>*/ sqlResultSetMappings;
* Map<String, SqlResultSetMapping> result set name, result set description
*/ protected Map typeDefs;
protected Map sqlResultSetMappings;
protected Map filterDefinitions; protected Map filterDefinitions;
protected Map fetchProfiles; protected Map fetchProfiles;
protected Map tableNameBinding;
protected Map columnNameBindingPerTable;
protected List secondPasses; protected List secondPasses;
protected List propertyReferences; protected List propertyReferences;
// protected List extendsQueue; // protected List extendsQueue;
protected Map extendsQueue; protected Map extendsQueue;
protected Map tableNameBinding;
protected Map columnNameBindingPerTable; protected Map sqlFunctions;
private Interceptor interceptor; private Interceptor interceptor;
private Properties properties; private Properties properties;
private EntityResolver entityResolver; private EntityResolver entityResolver;
private EntityNotFoundDelegate entityNotFoundDelegate; private EntityNotFoundDelegate entityNotFoundDelegate;
protected transient XMLHelper xmlHelper; protected transient XMLHelper xmlHelper;
protected transient Map typeDefs;
protected NamingStrategy namingStrategy; protected NamingStrategy namingStrategy;
private SessionFactoryObserver sessionFactoryObserver;
private EventListeners eventListeners; private EventListeners eventListeners;
protected final SettingsFactory settingsFactory; protected final SettingsFactory settingsFactory;
private SessionFactoryObserver sessionFactoryObserver; private transient Mapping mapping = buildMapping();
protected void reset() { protected void reset() {
classes = new HashMap(); classes = new HashMap();
imports = new HashMap(); imports = new HashMap();
collections = new HashMap(); collections = new HashMap();
tables = new TreeMap(); tables = new TreeMap();
namedQueries = new HashMap(); namedQueries = new HashMap();
namedSqlQueries = new HashMap(); namedSqlQueries = new HashMap();
sqlResultSetMappings = new HashMap(); sqlResultSetMappings = new HashMap();
xmlHelper = new XMLHelper();
typeDefs = new HashMap(); typeDefs = new HashMap();
filterDefinitions = new HashMap();
fetchProfiles = new HashMap();
auxiliaryDatabaseObjects = new ArrayList();
tableNameBinding = new HashMap();
columnNameBindingPerTable = new HashMap();
propertyReferences = new ArrayList(); propertyReferences = new ArrayList();
secondPasses = new ArrayList(); secondPasses = new ArrayList();
// extendsQueue = new ArrayList();
extendsQueue = new HashMap();
namingStrategy = DefaultNamingStrategy.INSTANCE;
xmlHelper = new XMLHelper();
interceptor = EmptyInterceptor.INSTANCE; interceptor = EmptyInterceptor.INSTANCE;
properties = Environment.getProperties(); properties = Environment.getProperties();
entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER; entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER;
eventListeners = new EventListeners(); 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(); sqlFunctions = new HashMap();
} }
private transient Mapping mapping = buildMapping();
protected Configuration(SettingsFactory settingsFactory) { protected Configuration(SettingsFactory settingsFactory) {
this.settingsFactory = settingsFactory; this.settingsFactory = settingsFactory;
reset(); reset();
@ -710,25 +722,7 @@ public class Configuration implements Serializable {
* mappings to. * mappings to.
*/ */
public Mappings createMappings() { public Mappings createMappings() {
return new Mappings( return new MappingsImpl();
classes,
collections,
tables,
namedQueries,
namedSqlQueries,
sqlResultSetMappings,
imports,
secondPasses,
propertyReferences,
namingStrategy,
typeDefs,
filterDefinitions,
fetchProfiles,
extendsQueue,
auxiliaryDatabaseObjects,
tableNameBinding,
columnNameBindingPerTable
);
} }
@ -2185,8 +2179,8 @@ public class Configuration implements Serializable {
filterDefinitions.put( definition.getFilterName(), definition ); filterDefinitions.put( definition.getFilterName(), definition );
} }
public Map getFetchProfiles() { public Iterator iterateFetchProfiles() {
return fetchProfiles; return fetchProfiles.values().iterator();
} }
public void addFetchProfile(FetchProfile fetchProfile) { public void addFetchProfile(FetchProfile fetchProfile) {
@ -2212,4 +2206,494 @@ public class Configuration implements Serializable {
public void setSessionFactoryObserver(SessionFactoryObserver sessionFactoryObserver) { public void setSessionFactoryObserver(SessionFactoryObserver sessionFactoryObserver) {
this.sessionFactoryObserver = sessionFactoryObserver; this.sessionFactoryObserver = sessionFactoryObserver;
} }
// Mappings impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Internal implementation of the Mappings interface giving access to the Configuration's internal
* <tt>metadata repository</tt> 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/*<String, String>*/ logicalToPhysical = new HashMap();
private Map/*<String, String>*/ 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 );
}
}
} }

View File

@ -26,13 +26,10 @@ package org.hibernate.cfg;
import java.io.Serializable; import java.io.Serializable;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties; 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.DuplicateMappingException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.engine.FilterDefinition; import org.hibernate.engine.FilterDefinition;
@ -40,542 +37,485 @@ import org.hibernate.engine.NamedQueryDefinition;
import org.hibernate.engine.NamedSQLQueryDefinition; import org.hibernate.engine.NamedSQLQueryDefinition;
import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.mapping.Collection; import org.hibernate.mapping.Collection;
import org.hibernate.mapping.DenormalizedTable;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.mapping.TypeDef; import org.hibernate.mapping.TypeDef;
import org.hibernate.mapping.AuxiliaryDatabaseObject; import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.FetchProfile; import org.hibernate.mapping.FetchProfile;
import org.hibernate.util.StringHelper;
/** /**
* A collection of mappings from classes and collections to * A collection of mappings from classes and collections to relational database tables. Represents a single
* relational database tables. (Represents a single * <tt>&lt;hibernate-mapping&gt;</tt> element.
* <tt>&lt;hibernate-mapping&gt;</tt> element.) * <p/>
* 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: <ol>
* <li><i>bounded</i> state : this is information which is indeed scoped by a single mapping</li>
* <li><i>unbounded</i> state : this is information which is Configuration wide (think of metadata repository)</li>
* <li><i>transient</i> state : state which changed at its own pace (naming strategy)</li>
* </ol>
*
* @author Gavin King * @author Gavin King
* @author Steve Ebersole
*/ */
public class Mappings implements Serializable { public interface Mappings {
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;
/** /**
* binding table between the logical column name and the name out of the naming strategy * Get the current naming strategy.
* for each table. *
* According that when the column name is not set, the property name is considered as such * @return The current naming strategy.
* This means that while theorically possible through the naming strategy contract, it is
* forbidden to have 2 real columns having the same logical name
* <Table, ColumnNames >
*/ */
protected final Map columnNameBindingPerTable; public NamingStrategy getNamingStrategy();
/** /**
* binding between logical table name and physical one (ie after the naming strategy has been applied) * Set the current naming strategy.
* <String, TableDescription> *
* @param namingStrategy The naming strategy to use.
*/ */
protected final Map tableNameBinding; 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 currently bound default catalog name.
*
* @param catalogName The catalog name to use as the current default.
*/
public void setCatalogName(String catalogName);
/**
* Get the currently bound default package name.
*
* @return The currently bound default package name
*/
public String getDefaultPackage();
/**
* Set the current default package name.
*
* @param defaultPackage The package name to set as the current default.
*/
public void setDefaultPackage(String defaultPackage);
/**
* Determine whether auto importing of entity names is currently enabled.
*
* @return True if currently enabled; false otherwise.
*/
public boolean isAutoImport();
/**
* Set whether to enable auto importing of entity names.
*
* @param autoImport True to enable; false to diasable.
* @see #addImport
*/
public void setAutoImport(boolean autoImport);
/**
* Determine whether default laziness is currently enabled.
*
* @return True if enabled, false otherwise.
*/
public boolean isDefaultLazy();
/**
* Set whether to enable default laziness.
*
* @param defaultLazy True to enable, false to disable.
*/
public void setDefaultLazy(boolean defaultLazy);
/**
* Get the current default cascade style.
*
* @return The current default cascade style.
*/
public String getDefaultCascade();
/**
* Sets the current default cascade style.
* .
* @param defaultCascade The cascade style to set as the current default.
*/
public void setDefaultCascade(String defaultCascade);
/**
* Get the current default property access style.
*
* @return The current default property access style.
*/
public String getDefaultAccess();
/**
* Sets the current default property access style.
*
* @param defaultAccess The access style to use as the current default.
*/
public void setDefaultAccess(String defaultAccess);
Mappings( /**
final Map classes, * Retrieves an iterator over the entity metadata present in this repository.
final Map collections, *
final Map tables, * @return Iterator over class metadata.
final Map queries, */
final Map sqlqueries, public Iterator iterateClasses();
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 ); * Retrieves the entity mapping metadata for the given entity name.
if ( old!=null ) { *
throw new DuplicateMappingException( "class/entity", persistentClass.getEntityName() ); * @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 void addCollection(Collection collection) throws MappingException { public PersistentClass getClass(String entityName);
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); * Retrieves the entity mapping metadata for the given entity name, potentially accounting
if ( existing!=null ) { * for imports.
if ( existing.equals(className) ) { *
log.info( "duplicate import: " + className + "->" + rename ); * @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.
else { */
throw new DuplicateMappingException( public PersistentClass locatePersistentClassByEntityName(String entityName);
"duplicate import: " + rename +
" refers to both " + className +
" and " + existing +
" (try using auto-import=\"false\")",
"import",
rename
);
}
}
}
public Table addTable(String schema, /**
String catalog, * Add entity mapping metadata.
String name, *
String subselect, * @param persistentClass The entity metadata
boolean isAbstract * @throws DuplicateMappingException Indicates there4 was already an extry
) { * corresponding to the given entity name.
String key = subselect==null ? */
Table.qualify(catalog, schema, name) : public void addClass(PersistentClass persistentClass) throws DuplicateMappingException;
subselect;
Table table = (Table) tables.get(key);
if (table == null) { /**
table = new Table(); * Adds an import (HQL entity rename) to the repository.
table.setAbstract(isAbstract); *
table.setName(name); * @param entityName The entity name being renamed.
table.setSchema(schema); * @param rename The rename
table.setCatalog(catalog); * @throws DuplicateMappingException If rename already is mapped to another
table.setSubselect(subselect); * entity name in this repository.
tables.put(key, table); */
} public void addImport(String entityName, String rename) throws DuplicateMappingException;
else {
if (!isAbstract) table.setAbstract(false);
}
return table; /**
} * 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 Table addDenormalizedTable( /**
* 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 schema,
String catalog, String catalog,
String name, String logicalName,
boolean isAbstract, String physicalName,
String subselect, Table denormalizedSuperTable) throws DuplicateMappingException;
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;
}
/** /**
* Sets the schemaName. * Binds the given 'physicalColumn' to the give 'logicalName' within the given 'table'.
* @param schemaName The schemaName to set *
* @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 setSchemaName(String schemaName) { public void addColumnBinding(String logicalName, Column physicalColumn, Table table) throws DuplicateMappingException;
this.schemaName = schemaName;
}
/** /**
* Sets the catalogName. * Find the physical column name for the given logical column name within the given table.
* @param catalogName The catalogName to set *
* @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 void setCatalogName(String catalogName) { public String getPhysicalColumnName(String logicalName, Table table) throws MappingException;
this.catalogName = catalogName;
}
/** /**
* Sets the defaultCascade. * Find the logical column name against whcih the given physical column name was bound within the given table.
* @param defaultCascade The defaultCascade to set *
* @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 void setDefaultCascade(String defaultCascade) { public String getLogicalColumnName(String physicalName, Table table) throws MappingException;
this.defaultCascade = defaultCascade;
}
/** /**
* sets the default access strategy * Adds a second-pass to the end of the current queue.
* @param defaultAccess the default access strategy. *
* @param sp The second pass to add.
*/ */
public void setDefaultAccess(String defaultAccess) { public void addSecondPass(SecondPass sp);
this.defaultAccess = defaultAccess;
}
public String getDefaultAccess() { /**
return defaultAccess; * 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);
public void addQuery(String name, NamedQueryDefinition query) throws MappingException { /**
checkQueryExist(name); * Represents a property-ref mapping.
queries.put( name.intern(), query ); * <p/>
} * 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 void addSQLQuery(String name, NamedSQLQueryDefinition query) throws MappingException { public PropertyReference(String referencedClass, String propertyName, boolean unique) {
checkQueryExist(name); this.referencedClass = referencedClass;
sqlqueries.put( name.intern(), query ); this.propertyName = propertyName;
} this.unique = unique;
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);
} }
} }
/** /**
* Returns the autoImport. * Adds a property reference binding to this repository.
* @return boolean *
* @param referencedClass The referenced entity name.
* @param propertyName The referenced property name.
*/ */
public boolean isAutoImport() { public void addPropertyReference(String referencedClass, String propertyName);
return autoImport;
}
/** /**
* Sets the autoImport. * Adds a property reference binding to this repository where said proeprty reference is marked as unique.
* @param autoImport The autoImport to set *
* @param referencedClass The referenced entity name.
* @param propertyName The referenced property name.
*/ */
public void setAutoImport(boolean autoImport) { public void addUniquePropertyReference(String referencedClass, String propertyName);
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;
}
/** /**
* @return Returns the defaultPackage. * Adds an entry to the extends queue queue.
*
* @param entry The entry to add.
*/ */
public String getDefaultPackage() { public void addToExtendsQueue(ExtendsQueueEntry entry);
return defaultPackage;
}
/**
* @param defaultPackage The defaultPackage to set.
*/
public void setDefaultPackage(String defaultPackage) {
this.defaultPackage = defaultPackage;
}
public NamingStrategy getNamingStrategy() {
return namingStrategy;
}
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 TypeDef getTypeDef(String typeName) {
return (TypeDef) typeDefs.get(typeName);
}
public Iterator iterateCollections() {
return collections.values().iterator();
}
public Iterator iterateTables() {
return tables.values().iterator();
}
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);
}
public Map getFetchProfiles() {
return fetchProfiles;
}
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 boolean isDefaultLazy() {
return defaultLazy;
}
public void setDefaultLazy(boolean defaultLazy) {
this.defaultLazy = defaultLazy;
}
public void addToExtendsQueue(ExtendsQueueEntry entry) {
extendsQueue.put( entry, null );
}
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 addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) {
auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject );
}
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 + "'");
}
}
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 + "'");
}
}
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;
}
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 {
//<String, String>
public Map logicalToPhysical = new HashMap();
//<String, String>
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;
}
} }

View File

@ -420,7 +420,7 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
// this needs to happen after persisters are all ready to go... // this needs to happen after persisters are all ready to go...
this.fetchProfiles = new HashMap(); this.fetchProfiles = new HashMap();
itr = cfg.getFetchProfiles().values().iterator(); itr = cfg.iterateFetchProfiles();
while ( itr.hasNext() ) { while ( itr.hasNext() ) {
final org.hibernate.mapping.FetchProfile mappingProfile = final org.hibernate.mapping.FetchProfile mappingProfile =
( org.hibernate.mapping.FetchProfile ) itr.next(); ( org.hibernate.mapping.FetchProfile ) itr.next();