HHH-10133 - CatalogSeparator of dialect metadata not used in runtime, just in schema tool
This commit is contained in:
parent
7354c7bfc3
commit
3571218183
|
@ -14,6 +14,11 @@ import org.hibernate.boot.model.naming.Identifier;
|
||||||
* <li>{@link java.sql.DatabaseMetaData#isCatalogAtStart}</li>
|
* <li>{@link java.sql.DatabaseMetaData#isCatalogAtStart}</li>
|
||||||
* <li>{@link java.sql.DatabaseMetaData#getCatalogSeparator()}</li>
|
* <li>{@link java.sql.DatabaseMetaData#getCatalogSeparator()}</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
|
* <p/>
|
||||||
|
* Also, be careful about the usage of {@link #render}. If the intention is get get the name
|
||||||
|
* as used in the database, the {@link org.hibernate.engine.jdbc.env.spi.JdbcEnvironment} ->
|
||||||
|
* {@link org.hibernate.engine.jdbc.env.spi.QualifiedObjectNameFormatter#format} should be
|
||||||
|
* used instead.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -22,5 +27,14 @@ public interface QualifiedName {
|
||||||
Identifier getSchemaName();
|
Identifier getSchemaName();
|
||||||
Identifier getObjectName();
|
Identifier getObjectName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a String-form of the qualified name.
|
||||||
|
* <p/>
|
||||||
|
* Depending on intention, may not be appropriate. May want
|
||||||
|
* {@link org.hibernate.engine.jdbc.env.spi.QualifiedObjectNameFormatter#format}
|
||||||
|
* instead. See {@link org.hibernate.engine.jdbc.env.spi.JdbcEnvironment#getQualifiedObjectNameFormatter}
|
||||||
|
*
|
||||||
|
* @return The string form
|
||||||
|
*/
|
||||||
String render();
|
String render();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.hibernate.boot.model.relational.InitCommand;
|
||||||
import org.hibernate.boot.model.relational.Namespace;
|
import org.hibernate.boot.model.relational.Namespace;
|
||||||
import org.hibernate.boot.model.relational.QualifiedTableName;
|
import org.hibernate.boot.model.relational.QualifiedTableName;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.jdbc.env.spi.QualifiedObjectNameFormatter;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.tool.hbm2ddl.ColumnMetadata;
|
import org.hibernate.tool.hbm2ddl.ColumnMetadata;
|
||||||
|
@ -106,6 +107,11 @@ public class Table implements RelationalModel, Serializable, Exportable {
|
||||||
this.isAbstract = isAbstract;
|
this.isAbstract = isAbstract;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Should use {@link QualifiedObjectNameFormatter#format} on QualifiedObjectNameFormatter
|
||||||
|
* obtained from {@link org.hibernate.engine.jdbc.env.spi.JdbcEnvironment}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public String getQualifiedName(Dialect dialect, String defaultCatalog, String defaultSchema) {
|
public String getQualifiedName(Dialect dialect, String defaultCatalog, String defaultSchema) {
|
||||||
if ( subselect != null ) {
|
if ( subselect != null ) {
|
||||||
return "( " + subselect + " )";
|
return "( " + subselect + " )";
|
||||||
|
@ -120,6 +126,11 @@ public class Table implements RelationalModel, Serializable, Exportable {
|
||||||
return qualify( usedCatalog, usedSchema, quotedName );
|
return qualify( usedCatalog, usedSchema, quotedName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Should use {@link QualifiedObjectNameFormatter#format} on QualifiedObjectNameFormatter
|
||||||
|
* obtained from {@link org.hibernate.engine.jdbc.env.spi.JdbcEnvironment}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String qualify(String catalog, String schema, String table) {
|
public static String qualify(String catalog, String schema, String table) {
|
||||||
StringBuilder qualifiedName = new StringBuilder();
|
StringBuilder qualifiedName = new StringBuilder();
|
||||||
if ( catalog != null ) {
|
if ( catalog != null ) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
import org.hibernate.TransientObjectException;
|
import org.hibernate.TransientObjectException;
|
||||||
|
import org.hibernate.boot.model.relational.Database;
|
||||||
import org.hibernate.cache.CacheException;
|
import org.hibernate.cache.CacheException;
|
||||||
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
|
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
|
||||||
import org.hibernate.cache.spi.entry.CacheEntryStructure;
|
import org.hibernate.cache.spi.entry.CacheEntryStructure;
|
||||||
|
@ -31,6 +32,7 @@ import org.hibernate.cache.spi.entry.UnstructuredCacheEntry;
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
|
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
|
||||||
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||||
|
@ -230,9 +232,12 @@ public abstract class AbstractCollectionPersister
|
||||||
CollectionRegionAccessStrategy cacheAccessStrategy,
|
CollectionRegionAccessStrategy cacheAccessStrategy,
|
||||||
PersisterCreationContext creationContext) throws MappingException, CacheException {
|
PersisterCreationContext creationContext) throws MappingException, CacheException {
|
||||||
|
|
||||||
|
final Database database = creationContext.getMetadata().getDatabase();
|
||||||
|
final JdbcEnvironment jdbcEnvironment = database.getJdbcEnvironment();
|
||||||
|
|
||||||
this.factory = creationContext.getSessionFactory();
|
this.factory = creationContext.getSessionFactory();
|
||||||
this.cacheAccessStrategy = cacheAccessStrategy;
|
this.cacheAccessStrategy = cacheAccessStrategy;
|
||||||
if ( factory.getSettings().isStructuredCacheEntriesEnabled() ) {
|
if ( factory.getSessionFactoryOptions().isStructuredCacheEntriesEnabled() ) {
|
||||||
cacheEntryStructure = collectionBinding.isMap()
|
cacheEntryStructure = collectionBinding.isMap()
|
||||||
? StructuredMapCacheEntry.INSTANCE
|
? StructuredMapCacheEntry.INSTANCE
|
||||||
: StructuredCollectionCacheEntry.INSTANCE;
|
: StructuredCollectionCacheEntry.INSTANCE;
|
||||||
|
@ -260,11 +265,7 @@ public abstract class AbstractCollectionPersister
|
||||||
isArray = collectionBinding.isArray();
|
isArray = collectionBinding.isArray();
|
||||||
subselectLoadable = collectionBinding.isSubselectLoadable();
|
subselectLoadable = collectionBinding.isSubselectLoadable();
|
||||||
|
|
||||||
qualifiedTableName = table.getQualifiedName(
|
qualifiedTableName = determineTableName( table, jdbcEnvironment );
|
||||||
dialect,
|
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
);
|
|
||||||
|
|
||||||
int spacesSize = 1 + collectionBinding.getSynchronizedTables().size();
|
int spacesSize = 1 + collectionBinding.getSynchronizedTables().size();
|
||||||
spaces = new String[spacesSize];
|
spaces = new String[spacesSize];
|
||||||
|
@ -284,7 +285,7 @@ public abstract class AbstractCollectionPersister
|
||||||
|
|
||||||
int batch = collectionBinding.getBatchSize();
|
int batch = collectionBinding.getBatchSize();
|
||||||
if ( batch == -1 ) {
|
if ( batch == -1 ) {
|
||||||
batch = factory.getSettings().getDefaultBatchFetchSize();
|
batch = factory.getSessionFactoryOptions().getDefaultBatchFetchSize();
|
||||||
}
|
}
|
||||||
batchSize = batch;
|
batchSize = batch;
|
||||||
|
|
||||||
|
@ -585,6 +586,17 @@ public abstract class AbstractCollectionPersister
|
||||||
initCollectionPropertyMap();
|
initCollectionPropertyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String determineTableName(Table table, JdbcEnvironment jdbcEnvironment) {
|
||||||
|
if ( table.getSubselect() != null ) {
|
||||||
|
return "( " + table.getSubselect() + " )";
|
||||||
|
}
|
||||||
|
|
||||||
|
return jdbcEnvironment.getQualifiedObjectNameFormatter().format(
|
||||||
|
table.getQualifiedTableName(),
|
||||||
|
jdbcEnvironment.getDialect()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private class ColumnMapperImpl implements ColumnMapper {
|
private class ColumnMapperImpl implements ColumnMapper {
|
||||||
@Override
|
@Override
|
||||||
public SqlValueReference[] map(String reference) {
|
public SqlValueReference[] map(String reference) {
|
||||||
|
|
|
@ -54,6 +54,7 @@ import org.hibernate.engine.internal.MutableEntityEntryFactory;
|
||||||
import org.hibernate.engine.internal.StatefulPersistenceContext;
|
import org.hibernate.engine.internal.StatefulPersistenceContext;
|
||||||
import org.hibernate.engine.internal.Versioning;
|
import org.hibernate.engine.internal.Versioning;
|
||||||
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
|
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
|
||||||
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.engine.spi.CachedNaturalIdValueSource;
|
import org.hibernate.engine.spi.CachedNaturalIdValueSource;
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
import org.hibernate.engine.spi.CascadeStyle;
|
||||||
import org.hibernate.engine.spi.CascadingActions;
|
import org.hibernate.engine.spi.CascadingActions;
|
||||||
|
@ -92,6 +93,7 @@ import org.hibernate.mapping.Component;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
import org.hibernate.mapping.Selectable;
|
import org.hibernate.mapping.Selectable;
|
||||||
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.metadata.ClassMetadata;
|
import org.hibernate.metadata.ClassMetadata;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||||
|
@ -5112,6 +5114,17 @@ public abstract class AbstractEntityPersister
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String determineTableName(Table table, JdbcEnvironment jdbcEnvironment) {
|
||||||
|
if ( table.getSubselect() != null ) {
|
||||||
|
return "( " + table.getSubselect() + " )";
|
||||||
|
}
|
||||||
|
|
||||||
|
return jdbcEnvironment.getQualifiedObjectNameFormatter().format(
|
||||||
|
table.getQualifiedTableName(),
|
||||||
|
jdbcEnvironment.getDialect()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityEntryFactory getEntityEntryFactory() {
|
public EntityEntryFactory getEntityEntryFactory() {
|
||||||
return this.entityEntryFactory;
|
return this.entityEntryFactory;
|
||||||
|
|
|
@ -18,9 +18,11 @@ import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
|
import org.hibernate.boot.model.relational.Database;
|
||||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||||
import org.hibernate.engine.OptimisticLockStyle;
|
import org.hibernate.engine.OptimisticLockStyle;
|
||||||
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.internal.DynamicFilterAliasGenerator;
|
import org.hibernate.internal.DynamicFilterAliasGenerator;
|
||||||
|
@ -133,6 +135,8 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
|
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
|
||||||
|
|
||||||
final SessionFactoryImplementor factory = creationContext.getSessionFactory();
|
final SessionFactoryImplementor factory = creationContext.getSessionFactory();
|
||||||
|
final Database database = creationContext.getMetadata().getDatabase();
|
||||||
|
final JdbcEnvironment jdbcEnvironment = database.getJdbcEnvironment();
|
||||||
|
|
||||||
// DISCRIMINATOR
|
// DISCRIMINATOR
|
||||||
|
|
||||||
|
@ -201,28 +205,24 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
|
|
||||||
final int idColumnSpan = getIdentifierColumnSpan();
|
final int idColumnSpan = getIdentifierColumnSpan();
|
||||||
|
|
||||||
ArrayList tables = new ArrayList();
|
ArrayList<String> tableNames = new ArrayList<String>();
|
||||||
ArrayList keyColumns = new ArrayList();
|
ArrayList<String[]> keyColumns = new ArrayList<String[]>();
|
||||||
ArrayList keyColumnReaders = new ArrayList();
|
ArrayList<String[]> keyColumnReaders = new ArrayList<String[]>();
|
||||||
ArrayList keyColumnReaderTemplates = new ArrayList();
|
ArrayList<String[]> keyColumnReaderTemplates = new ArrayList<String[]>();
|
||||||
ArrayList cascadeDeletes = new ArrayList();
|
ArrayList<Boolean> cascadeDeletes = new ArrayList<Boolean>();
|
||||||
Iterator titer = persistentClass.getTableClosureIterator();
|
Iterator tItr = persistentClass.getTableClosureIterator();
|
||||||
Iterator kiter = persistentClass.getKeyClosureIterator();
|
Iterator kItr = persistentClass.getKeyClosureIterator();
|
||||||
while ( titer.hasNext() ) {
|
while ( tItr.hasNext() ) {
|
||||||
Table tab = (Table) titer.next();
|
final Table table = (Table) tItr.next();
|
||||||
KeyValue key = (KeyValue) kiter.next();
|
final KeyValue key = (KeyValue) kItr.next();
|
||||||
String tabname = tab.getQualifiedName(
|
final String tableName = determineTableName( table, jdbcEnvironment );
|
||||||
factory.getDialect(),
|
tableNames.add( tableName );
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
);
|
|
||||||
tables.add( tabname );
|
|
||||||
String[] keyCols = new String[idColumnSpan];
|
String[] keyCols = new String[idColumnSpan];
|
||||||
String[] keyColReaders = new String[idColumnSpan];
|
String[] keyColReaders = new String[idColumnSpan];
|
||||||
String[] keyColReaderTemplates = new String[idColumnSpan];
|
String[] keyColReaderTemplates = new String[idColumnSpan];
|
||||||
Iterator citer = key.getColumnIterator();
|
Iterator cItr = key.getColumnIterator();
|
||||||
for ( int k = 0; k < idColumnSpan; k++ ) {
|
for ( int k = 0; k < idColumnSpan; k++ ) {
|
||||||
Column column = (Column) citer.next();
|
Column column = (Column) cItr.next();
|
||||||
keyCols[k] = column.getQuotedName( factory.getDialect() );
|
keyCols[k] = column.getQuotedName( factory.getDialect() );
|
||||||
keyColReaders[k] = column.getReadExpr( factory.getDialect() );
|
keyColReaders[k] = column.getReadExpr( factory.getDialect() );
|
||||||
keyColReaderTemplates[k] = column.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
|
keyColReaderTemplates[k] = column.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
|
||||||
|
@ -233,26 +233,21 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
cascadeDeletes.add( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() );
|
cascadeDeletes.add( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//Span of the tables directly mapped by this entity and super-classes, if any
|
//Span of the tableNames directly mapped by this entity and super-classes, if any
|
||||||
coreTableSpan = tables.size();
|
coreTableSpan = tableNames.size();
|
||||||
|
|
||||||
isNullableTable = new boolean[persistentClass.getJoinClosureSpan()];
|
isNullableTable = new boolean[persistentClass.getJoinClosureSpan()];
|
||||||
|
|
||||||
int tableIndex = 0;
|
int tableIndex = 0;
|
||||||
Iterator joinIter = persistentClass.getJoinClosureIterator();
|
Iterator joinItr = persistentClass.getJoinClosureIterator();
|
||||||
while ( joinIter.hasNext() ) {
|
while ( joinItr.hasNext() ) {
|
||||||
Join join = (Join) joinIter.next();
|
Join join = (Join) joinItr.next();
|
||||||
|
|
||||||
isNullableTable[tableIndex++] = join.isOptional();
|
isNullableTable[tableIndex++] = join.isOptional();
|
||||||
|
|
||||||
Table table = join.getTable();
|
Table table = join.getTable();
|
||||||
|
final String tableName = determineTableName( table, jdbcEnvironment );
|
||||||
String tableName = table.getQualifiedName(
|
tableNames.add( tableName );
|
||||||
factory.getDialect(),
|
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
);
|
|
||||||
tables.add( tableName );
|
|
||||||
|
|
||||||
KeyValue key = join.getKey();
|
KeyValue key = join.getKey();
|
||||||
int joinIdColumnSpan = key.getColumnSpan();
|
int joinIdColumnSpan = key.getColumnSpan();
|
||||||
|
@ -261,10 +256,10 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
String[] keyColReaders = new String[joinIdColumnSpan];
|
String[] keyColReaders = new String[joinIdColumnSpan];
|
||||||
String[] keyColReaderTemplates = new String[joinIdColumnSpan];
|
String[] keyColReaderTemplates = new String[joinIdColumnSpan];
|
||||||
|
|
||||||
Iterator citer = key.getColumnIterator();
|
Iterator cItr = key.getColumnIterator();
|
||||||
|
|
||||||
for ( int k = 0; k < joinIdColumnSpan; k++ ) {
|
for ( int k = 0; k < joinIdColumnSpan; k++ ) {
|
||||||
Column column = (Column) citer.next();
|
Column column = (Column) cItr.next();
|
||||||
keyCols[k] = column.getQuotedName( factory.getDialect() );
|
keyCols[k] = column.getQuotedName( factory.getDialect() );
|
||||||
keyColReaders[k] = column.getReadExpr( factory.getDialect() );
|
keyColReaders[k] = column.getReadExpr( factory.getDialect() );
|
||||||
keyColReaderTemplates[k] = column.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
|
keyColReaderTemplates[k] = column.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
|
||||||
|
@ -275,64 +270,55 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
cascadeDeletes.add( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() );
|
cascadeDeletes.add( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() );
|
||||||
}
|
}
|
||||||
|
|
||||||
naturalOrderTableNames = ArrayHelper.toStringArray( tables );
|
naturalOrderTableNames = ArrayHelper.toStringArray( tableNames );
|
||||||
naturalOrderTableKeyColumns = ArrayHelper.to2DStringArray( keyColumns );
|
naturalOrderTableKeyColumns = ArrayHelper.to2DStringArray( keyColumns );
|
||||||
naturalOrderTableKeyColumnReaders = ArrayHelper.to2DStringArray( keyColumnReaders );
|
naturalOrderTableKeyColumnReaders = ArrayHelper.to2DStringArray( keyColumnReaders );
|
||||||
naturalOrderTableKeyColumnReaderTemplates = ArrayHelper.to2DStringArray( keyColumnReaderTemplates );
|
naturalOrderTableKeyColumnReaderTemplates = ArrayHelper.to2DStringArray( keyColumnReaderTemplates );
|
||||||
naturalOrderCascadeDeleteEnabled = ArrayHelper.toBooleanArray( cascadeDeletes );
|
naturalOrderCascadeDeleteEnabled = ArrayHelper.toBooleanArray( cascadeDeletes );
|
||||||
|
|
||||||
ArrayList subtables = new ArrayList();
|
ArrayList<String> subclassTableNames = new ArrayList<String>();
|
||||||
ArrayList isConcretes = new ArrayList();
|
ArrayList<Boolean> isConcretes = new ArrayList<Boolean>();
|
||||||
ArrayList isDeferreds = new ArrayList();
|
ArrayList<Boolean> isDeferreds = new ArrayList<Boolean>();
|
||||||
ArrayList isLazies = new ArrayList();
|
ArrayList<Boolean> isLazies = new ArrayList<Boolean>();
|
||||||
|
|
||||||
keyColumns = new ArrayList();
|
keyColumns = new ArrayList<String[]>();
|
||||||
titer = persistentClass.getSubclassTableClosureIterator();
|
tItr = persistentClass.getSubclassTableClosureIterator();
|
||||||
while ( titer.hasNext() ) {
|
while ( tItr.hasNext() ) {
|
||||||
Table tab = (Table) titer.next();
|
Table tab = (Table) tItr.next();
|
||||||
isConcretes.add( persistentClass.isClassOrSuperclassTable( tab ) );
|
isConcretes.add( persistentClass.isClassOrSuperclassTable( tab ) );
|
||||||
isDeferreds.add( Boolean.FALSE );
|
isDeferreds.add( Boolean.FALSE );
|
||||||
isLazies.add( Boolean.FALSE );
|
isLazies.add( Boolean.FALSE );
|
||||||
String tabname = tab.getQualifiedName(
|
final String tableName = determineTableName( tab, jdbcEnvironment );
|
||||||
factory.getDialect(),
|
subclassTableNames.add( tableName );
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
);
|
|
||||||
subtables.add( tabname );
|
|
||||||
String[] key = new String[idColumnSpan];
|
String[] key = new String[idColumnSpan];
|
||||||
Iterator citer = tab.getPrimaryKey().getColumnIterator();
|
Iterator cItr = tab.getPrimaryKey().getColumnIterator();
|
||||||
for ( int k = 0; k < idColumnSpan; k++ ) {
|
for ( int k = 0; k < idColumnSpan; k++ ) {
|
||||||
key[k] = ( (Column) citer.next() ).getQuotedName( factory.getDialect() );
|
key[k] = ( (Column) cItr.next() ).getQuotedName( factory.getDialect() );
|
||||||
}
|
}
|
||||||
keyColumns.add( key );
|
keyColumns.add( key );
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add joins
|
//Add joins
|
||||||
joinIter = persistentClass.getSubclassJoinClosureIterator();
|
joinItr = persistentClass.getSubclassJoinClosureIterator();
|
||||||
while ( joinIter.hasNext() ) {
|
while ( joinItr.hasNext() ) {
|
||||||
Join join = (Join) joinIter.next();
|
final Join join = (Join) joinItr.next();
|
||||||
|
final Table joinTable = join.getTable();
|
||||||
|
|
||||||
Table tab = join.getTable();
|
isConcretes.add( persistentClass.isClassOrSuperclassTable( joinTable ) );
|
||||||
|
|
||||||
isConcretes.add( persistentClass.isClassOrSuperclassTable( tab ) );
|
|
||||||
isDeferreds.add( join.isSequentialSelect() );
|
isDeferreds.add( join.isSequentialSelect() );
|
||||||
isLazies.add( join.isLazy() );
|
isLazies.add( join.isLazy() );
|
||||||
|
|
||||||
String tabname = tab.getQualifiedName(
|
String joinTableName = determineTableName( joinTable, jdbcEnvironment );
|
||||||
factory.getDialect(),
|
subclassTableNames.add( joinTableName );
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
);
|
|
||||||
subtables.add( tabname );
|
|
||||||
String[] key = new String[idColumnSpan];
|
String[] key = new String[idColumnSpan];
|
||||||
Iterator citer = tab.getPrimaryKey().getColumnIterator();
|
Iterator citer = joinTable.getPrimaryKey().getColumnIterator();
|
||||||
for ( int k = 0; k < idColumnSpan; k++ ) {
|
for ( int k = 0; k < idColumnSpan; k++ ) {
|
||||||
key[k] = ( (Column) citer.next() ).getQuotedName( factory.getDialect() );
|
key[k] = ( (Column) citer.next() ).getQuotedName( factory.getDialect() );
|
||||||
}
|
}
|
||||||
keyColumns.add( key );
|
keyColumns.add( key );
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] naturalOrderSubclassTableNameClosure = ArrayHelper.toStringArray( subtables );
|
String[] naturalOrderSubclassTableNameClosure = ArrayHelper.toStringArray( subclassTableNames );
|
||||||
String[][] naturalOrderSubclassTableKeyColumnClosure = ArrayHelper.to2DStringArray( keyColumns );
|
String[][] naturalOrderSubclassTableKeyColumnClosure = ArrayHelper.to2DStringArray( keyColumns );
|
||||||
isClassOrSuperclassTable = ArrayHelper.toBooleanArray( isConcretes );
|
isClassOrSuperclassTable = ArrayHelper.toBooleanArray( isConcretes );
|
||||||
subclassTableSequentialSelect = ArrayHelper.toBooleanArray( isDeferreds );
|
subclassTableSequentialSelect = ArrayHelper.toBooleanArray( isDeferreds );
|
||||||
|
@ -347,9 +333,9 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suppose an entity Client extends Person, mapped to the tables CLIENT and PERSON respectively.
|
* Suppose an entity Client extends Person, mapped to the tableNames CLIENT and PERSON respectively.
|
||||||
* For the Client entity:
|
* For the Client entity:
|
||||||
* naturalOrderTableNames -> PERSON, CLIENT; this reflects the sequence in which the tables are
|
* naturalOrderTableNames -> PERSON, CLIENT; this reflects the sequence in which the tableNames are
|
||||||
* added to the meta-data when the annotated entities are processed.
|
* added to the meta-data when the annotated entities are processed.
|
||||||
* However, in some instances, for example when generating joins, the CLIENT table needs to be
|
* However, in some instances, for example when generating joins, the CLIENT table needs to be
|
||||||
* the first table as it will the driving table.
|
* the first table as it will the driving table.
|
||||||
|
@ -357,7 +343,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tableSpan = naturalOrderTableNames.length;
|
tableSpan = naturalOrderTableNames.length;
|
||||||
tableNames = reverse( naturalOrderTableNames, coreTableSpan );
|
this.tableNames = reverse( naturalOrderTableNames, coreTableSpan );
|
||||||
tableKeyColumns = reverse( naturalOrderTableKeyColumns, coreTableSpan );
|
tableKeyColumns = reverse( naturalOrderTableKeyColumns, coreTableSpan );
|
||||||
tableKeyColumnReaders = reverse( naturalOrderTableKeyColumnReaders, coreTableSpan );
|
tableKeyColumnReaders = reverse( naturalOrderTableKeyColumnReaders, coreTableSpan );
|
||||||
tableKeyColumnReaderTemplates = reverse( naturalOrderTableKeyColumnReaderTemplates, coreTableSpan );
|
tableKeyColumnReaderTemplates = reverse( naturalOrderTableKeyColumnReaderTemplates, coreTableSpan );
|
||||||
|
@ -365,7 +351,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
subclassTableKeyColumnClosure = reverse( naturalOrderSubclassTableKeyColumnClosure, coreTableSpan );
|
subclassTableKeyColumnClosure = reverse( naturalOrderSubclassTableKeyColumnClosure, coreTableSpan );
|
||||||
|
|
||||||
spaces = ArrayHelper.join(
|
spaces = ArrayHelper.join(
|
||||||
tableNames,
|
this.tableNames,
|
||||||
ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() )
|
ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -408,10 +394,10 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
throw new AssertionFailure( "Tablespan does not match height of joined-subclass hiearchy." );
|
throw new AssertionFailure( "Tablespan does not match height of joined-subclass hiearchy." );
|
||||||
}
|
}
|
||||||
|
|
||||||
joinIter = persistentClass.getJoinClosureIterator();
|
joinItr = persistentClass.getJoinClosureIterator();
|
||||||
int j = coreTableSpan;
|
int j = coreTableSpan;
|
||||||
while ( joinIter.hasNext() ) {
|
while ( joinItr.hasNext() ) {
|
||||||
Join join = (Join) joinIter.next();
|
Join join = (Join) joinItr.next();
|
||||||
|
|
||||||
customSQLInsert[j] = join.getCustomSQLInsert();
|
customSQLInsert[j] = join.getCustomSQLInsert();
|
||||||
insertCallable[j] = customSQLInsert[j] != null && join.isCustomInsertCallable();
|
insertCallable[j] = customSQLInsert[j] != null && join.isCustomInsertCallable();
|
||||||
|
@ -444,7 +430,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
factory.getSettings().getDefaultCatalogName(),
|
||||||
factory.getSettings().getDefaultSchemaName()
|
factory.getSettings().getDefaultSchemaName()
|
||||||
);
|
);
|
||||||
propertyTableNumbers[i] = getTableId( tabname, tableNames );
|
propertyTableNumbers[i] = getTableId( tabname, this.tableNames );
|
||||||
naturalOrderPropertyTableNumbers[i] = getTableId( tabname, naturalOrderTableNames );
|
naturalOrderPropertyTableNumbers[i] = getTableId( tabname, naturalOrderTableNames );
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,10 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.model.relational.Database;
|
||||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||||
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.internal.DynamicFilterAliasGenerator;
|
import org.hibernate.internal.DynamicFilterAliasGenerator;
|
||||||
|
@ -123,6 +125,9 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
|
|
||||||
final SessionFactoryImplementor factory = creationContext.getSessionFactory();
|
final SessionFactoryImplementor factory = creationContext.getSessionFactory();
|
||||||
|
|
||||||
|
final Database database = creationContext.getMetadata().getDatabase();
|
||||||
|
final JdbcEnvironment jdbcEnvironment = database.getJdbcEnvironment();
|
||||||
|
|
||||||
// CLASS + TABLE
|
// CLASS + TABLE
|
||||||
|
|
||||||
joinSpan = persistentClass.getJoinClosureSpan() + 1;
|
joinSpan = persistentClass.getJoinClosureSpan() + 1;
|
||||||
|
@ -131,11 +136,8 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
isNullableTable = new boolean[joinSpan];
|
isNullableTable = new boolean[joinSpan];
|
||||||
keyColumnNames = new String[joinSpan][];
|
keyColumnNames = new String[joinSpan][];
|
||||||
final Table table = persistentClass.getRootTable();
|
final Table table = persistentClass.getRootTable();
|
||||||
qualifiedTableNames[0] = table.getQualifiedName(
|
qualifiedTableNames[0] = determineTableName( table, jdbcEnvironment );
|
||||||
factory.getDialect(),
|
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
);
|
|
||||||
isInverseTable[0] = false;
|
isInverseTable[0] = false;
|
||||||
isNullableTable[0] = false;
|
isNullableTable[0] = false;
|
||||||
keyColumnNames[0] = getIdentifierColumnNames();
|
keyColumnNames[0] = getIdentifierColumnNames();
|
||||||
|
@ -174,11 +176,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
int j = 1;
|
int j = 1;
|
||||||
while ( joinIter.hasNext() ) {
|
while ( joinIter.hasNext() ) {
|
||||||
Join join = (Join) joinIter.next();
|
Join join = (Join) joinIter.next();
|
||||||
qualifiedTableNames[j] = join.getTable().getQualifiedName(
|
qualifiedTableNames[j] = determineTableName( join.getTable(), jdbcEnvironment );
|
||||||
factory.getDialect(),
|
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
);
|
|
||||||
isInverseTable[j] = join.isInverse();
|
isInverseTable[j] = join.isInverse();
|
||||||
isNullableTable[j] = join.isOptional();
|
isNullableTable[j] = join.isOptional();
|
||||||
cascadeDeleteEnabled[j] = join.getKey().isCascadeDeleteEnabled() &&
|
cascadeDeleteEnabled[j] = join.getKey().isCascadeDeleteEnabled() &&
|
||||||
|
|
|
@ -19,10 +19,12 @@ import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.model.relational.Database;
|
||||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||||
import org.hibernate.cfg.Settings;
|
import org.hibernate.cfg.Settings;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
@ -74,8 +76,6 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
|
|
||||||
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
|
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
|
||||||
|
|
||||||
final SessionFactoryImplementor factory = creationContext.getSessionFactory();
|
|
||||||
|
|
||||||
if ( getIdentifierGenerator() instanceof IdentityGenerator ) {
|
if ( getIdentifierGenerator() instanceof IdentityGenerator ) {
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
"Cannot use identity column key generation with <union-subclass> mapping for: " +
|
"Cannot use identity column key generation with <union-subclass> mapping for: " +
|
||||||
|
@ -83,18 +83,13 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final SessionFactoryImplementor factory = creationContext.getSessionFactory();
|
||||||
|
final Database database = creationContext.getMetadata().getDatabase();
|
||||||
|
final JdbcEnvironment jdbcEnvironment = database.getJdbcEnvironment();
|
||||||
|
|
||||||
// TABLE
|
// TABLE
|
||||||
|
|
||||||
tableName = persistentClass.getTable().getQualifiedName(
|
tableName = determineTableName( persistentClass.getTable(), jdbcEnvironment );
|
||||||
factory.getDialect(),
|
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
);
|
|
||||||
/*rootTableName = persistentClass.getRootTable().getQualifiedName(
|
|
||||||
factory.getDialect(),
|
|
||||||
factory.getDefaultCatalog(),
|
|
||||||
factory.getDefaultSchema()
|
|
||||||
);*/
|
|
||||||
|
|
||||||
//Custom SQL
|
//Custom SQL
|
||||||
|
|
||||||
|
@ -173,14 +168,8 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
HashSet subclassTables = new HashSet();
|
HashSet subclassTables = new HashSet();
|
||||||
iter = persistentClass.getSubclassTableClosureIterator();
|
iter = persistentClass.getSubclassTableClosureIterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
Table table = (Table) iter.next();
|
final Table table = (Table) iter.next();
|
||||||
subclassTables.add(
|
subclassTables.add( determineTableName( table, jdbcEnvironment ) );
|
||||||
table.getQualifiedName(
|
|
||||||
factory.getDialect(),
|
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
subclassSpaces = ArrayHelper.toStringArray( subclassTables );
|
subclassSpaces = ArrayHelper.toStringArray( subclassTables );
|
||||||
|
|
||||||
|
@ -198,11 +187,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
Table tab = (Table) iter.next();
|
Table tab = (Table) iter.next();
|
||||||
if ( !tab.isAbstractUnionTable() ) {
|
if ( !tab.isAbstractUnionTable() ) {
|
||||||
String tableName = tab.getQualifiedName(
|
final String tableName = determineTableName( tab, jdbcEnvironment );
|
||||||
factory.getDialect(),
|
|
||||||
factory.getSettings().getDefaultCatalogName(),
|
|
||||||
factory.getSettings().getDefaultSchemaName()
|
|
||||||
);
|
|
||||||
tableNames.add( tableName );
|
tableNames.add( tableName );
|
||||||
String[] key = new String[idColumnSpan];
|
String[] key = new String[idColumnSpan];
|
||||||
Iterator citer = tab.getPrimaryKey().getColumnIterator();
|
Iterator citer = tab.getPrimaryKey().getColumnIterator();
|
||||||
|
|
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.boot.database.qualfiedTableNaming;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class JdbcMocks {
|
||||||
|
|
||||||
|
public static Connection createConnection(String databaseName, int majorVersion) {
|
||||||
|
return createConnection( databaseName, majorVersion, -9999 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Connection createConnection(String databaseName, int majorVersion, int minorVersion) {
|
||||||
|
DatabaseMetaDataHandler metadataHandler = new DatabaseMetaDataHandler( databaseName, majorVersion, minorVersion );
|
||||||
|
ConnectionHandler connectionHandler = new ConnectionHandler();
|
||||||
|
|
||||||
|
DatabaseMetaData metadataProxy = ( DatabaseMetaData ) Proxy.newProxyInstance(
|
||||||
|
ClassLoader.getSystemClassLoader(),
|
||||||
|
new Class[] {DatabaseMetaData.class},
|
||||||
|
metadataHandler
|
||||||
|
);
|
||||||
|
|
||||||
|
Connection connectionProxy = ( Connection ) Proxy.newProxyInstance(
|
||||||
|
ClassLoader.getSystemClassLoader(),
|
||||||
|
new Class[] { Connection.class },
|
||||||
|
connectionHandler
|
||||||
|
);
|
||||||
|
|
||||||
|
metadataHandler.setConnectionProxy( connectionProxy );
|
||||||
|
connectionHandler.setMetadataProxy( metadataProxy );
|
||||||
|
|
||||||
|
return connectionProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ConnectionHandler implements InvocationHandler {
|
||||||
|
private DatabaseMetaData metadataProxy;
|
||||||
|
|
||||||
|
public void setMetadataProxy(DatabaseMetaData metadataProxy) {
|
||||||
|
this.metadataProxy = metadataProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
|
final String methodName = method.getName();
|
||||||
|
if ( "getMetaData".equals( methodName ) ) {
|
||||||
|
return metadataProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "toString".equals( methodName ) ) {
|
||||||
|
return "Connection proxy [@" + hashCode() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "hashCode".equals( methodName ) ) {
|
||||||
|
return Integer.valueOf( this.hashCode() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "getCatalog".equals( methodName ) ) {
|
||||||
|
return "DB1";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "supportsRefCursors".equals( methodName ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( canThrowSQLException( method ) ) {
|
||||||
|
throw new SQLException();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DatabaseMetaDataHandler implements InvocationHandler {
|
||||||
|
private final String databaseName;
|
||||||
|
private final int majorVersion;
|
||||||
|
private final int minorVersion;
|
||||||
|
|
||||||
|
private Connection connectionProxy;
|
||||||
|
|
||||||
|
public void setConnectionProxy(Connection connectionProxy) {
|
||||||
|
this.connectionProxy = connectionProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DatabaseMetaDataHandler(String databaseName, int majorVersion) {
|
||||||
|
this( databaseName, majorVersion, -9999 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private DatabaseMetaDataHandler(String databaseName, int majorVersion, int minorVersion) {
|
||||||
|
this.databaseName = databaseName;
|
||||||
|
this.majorVersion = majorVersion;
|
||||||
|
this.minorVersion = minorVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
|
final String methodName = method.getName();
|
||||||
|
if ( "getDatabaseProductName".equals( methodName ) ) {
|
||||||
|
return databaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "getDatabaseMajorVersion".equals( methodName ) ) {
|
||||||
|
return Integer.valueOf( majorVersion );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "getDatabaseMinorVersion".equals( methodName ) ) {
|
||||||
|
return Integer.valueOf( minorVersion );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "getConnection".equals( methodName ) ) {
|
||||||
|
return connectionProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "toString".equals( methodName ) ) {
|
||||||
|
return "DatabaseMetaData proxy [db-name=" + databaseName + ", version=" + majorVersion + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "hashCode".equals( methodName ) ) {
|
||||||
|
return Integer.valueOf( this.hashCode() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "supportsNamedParameters".equals( methodName ) ) {
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "supportsResultSetType".equals( methodName ) ) {
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "supportsGetGeneratedKeys".equals( methodName ) ) {
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "supportsBatchUpdates".equals( methodName ) ) {
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "dataDefinitionIgnoredInTransactions".equals( methodName ) ) {
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "dataDefinitionCausesTransactionCommit".equals( methodName ) ) {
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "getSQLKeywords".equals( methodName ) ) {
|
||||||
|
return "after,ansi,append,attach,audit,before,bitmap,boolean,buffered,byte,cache,call,cluster,clustersize,codeset,database,datafiles,dataskip,datetime,dba,dbdate,dbmoney,debug,define,delimiter,deluxe,detach,dirty,distributions,document,each,elif,exclusive,exit,explain,express,expression,extend,extent,file,fillfactor,foreach,format,fraction,fragment,gk,hash,high,hold,hybrid,if,index,init,labeleq,labelge,labelgt,labelle,labellt,let,listing,lock,log,low,matches,maxerrors,medium,mode,modify,money,mounting,new,nvarchar,off,old,operational,optical,optimization,page,pdqpriority,pload,private,raise,range,raw,recordend,recover,referencing,rejectfile,release,remainder,rename,reserve,resolution,resource,resume,return,returning,returns,ridlist,robin,rollforward,round,row,rowids,sameas,samples,schedule,scratch,serial,share,skall,skinhibit,skshow,smallfloat,stability,standard,start,static,statistics,stdev,step,sync,synonym,system,temp,text,timeout,trace,trigger,units,unlock,variance,wait,while,xload,xunload" ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "getSQLStateType".equals( methodName ) ) {
|
||||||
|
return DatabaseMetaData.sqlStateXOpen ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "locatorsUpdateCopy".equals( methodName ) ) {
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "getTypeInfo".equals( methodName ) ) {
|
||||||
|
com.sun.rowset.CachedRowSetImpl rowSet = new com.sun.rowset.CachedRowSetImpl();
|
||||||
|
return rowSet ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "storesLowerCaseIdentifiers".equals( methodName ) ) {
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "storesUpperCaseIdentifiers".equals( methodName ) ) {
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "getCatalogSeparator".equals( methodName ) ) {
|
||||||
|
return ":" ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( "isCatalogAtStart".equals( methodName ) ) {
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( canThrowSQLException( method ) ) {
|
||||||
|
throw new SQLException();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean canThrowSQLException(Method method) {
|
||||||
|
final Class[] exceptions = method.getExceptionTypes();
|
||||||
|
for ( Class exceptionType : exceptions ) {
|
||||||
|
if ( SQLException.class.isAssignableFrom( exceptionType ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.boot.database.qualfiedTableNaming;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
import org.hibernate.boot.model.naming.Identifier;
|
||||||
|
import org.hibernate.boot.model.relational.Namespace;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
|
||||||
|
import org.hibernate.mapping.Table;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.persister.entity.SingleTableEntityPersister;
|
||||||
|
import org.hibernate.tool.schema.internal.StandardTableExporter;
|
||||||
|
|
||||||
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class QualifiedTableNamingTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] { Box.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean createSchema() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addSettings(Map settings) {
|
||||||
|
super.addSettings( settings );
|
||||||
|
settings.put( AvailableSettings.DIALECT, TestDialect.class );
|
||||||
|
settings.put( AvailableSettings.CONNECTION_PROVIDER, MockedConnectionProvider.class.getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQualifiedNameSeparator() throws Exception {
|
||||||
|
Namespace.Name namespaceName = new Namespace.Name(
|
||||||
|
Identifier.toIdentifier( "DB1" ),
|
||||||
|
Identifier.toIdentifier( "PUBLIC" )
|
||||||
|
);
|
||||||
|
|
||||||
|
String expectedName = null;
|
||||||
|
|
||||||
|
for ( Namespace namespace : metadata().getDatabase().getNamespaces() ) {
|
||||||
|
if ( !namespace.getName().equals( namespaceName ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals( 1, namespace.getTables().size() );
|
||||||
|
|
||||||
|
expectedName = metadata().getDatabase().getJdbcEnvironment().getQualifiedObjectNameFormatter().format(
|
||||||
|
namespace.getTables().iterator().next().getQualifiedTableName(),
|
||||||
|
getDialect()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNotNull( expectedName );
|
||||||
|
|
||||||
|
SingleTableEntityPersister persister = (SingleTableEntityPersister) sessionFactory().getEntityPersister( Box.class.getName() );
|
||||||
|
assertEquals( expectedName, persister.getTableName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Box")
|
||||||
|
@javax.persistence.Table(name = "Box", schema = "PUBLIC", catalog = "DB1")
|
||||||
|
public static class Box {
|
||||||
|
@Id
|
||||||
|
public Integer id;
|
||||||
|
public String value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TestDialect extends Dialect {
|
||||||
|
@Override
|
||||||
|
public NameQualifierSupport getNameQualifierSupport() {
|
||||||
|
return NameQualifierSupport.BOTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MockedConnectionProvider implements ConnectionProvider {
|
||||||
|
private Connection connection;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection() throws SQLException {
|
||||||
|
if (connection == null) {
|
||||||
|
connection = JdbcMocks.createConnection( "db1", 0 );
|
||||||
|
}
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeConnection(Connection conn) throws SQLException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsAggressiveRelease() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUnwrappableAs(Class unwrapType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T unwrap(Class<T> unwrapType) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue