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:
parent
3a23f9d1b8
commit
aa7f7a7822
|
@ -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<String, SqlResultSetMapping> result set name, result set description
|
||||
*/
|
||||
protected Map sqlResultSetMappings;
|
||||
protected Map/*<String, SqlResultSetMapping>*/ 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
|
||||
* <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 );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* <tt><hibernate-mapping></tt> element.)
|
||||
* A collection of mappings from classes and collections to relational database tables. Represents a single
|
||||
* <tt><hibernate-mapping></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 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
|
||||
* <Table, ColumnNames >
|
||||
* 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)
|
||||
* <String, TableDescription>
|
||||
*/
|
||||
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.
|
||||
* <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 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 {
|
||||
//<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;
|
||||
}
|
||||
/**
|
||||
* Adds an entry to the extends queue queue.
|
||||
*
|
||||
* @param entry The entry to add.
|
||||
*/
|
||||
public void addToExtendsQueue(ExtendsQueueEntry entry);
|
||||
}
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue