HHH-7380 - union subclass support

This commit is contained in:
Strong Liu 2012-12-07 15:59:05 +08:00
parent addadfccd4
commit 1b2469325d
34 changed files with 396 additions and 123 deletions

View File

@ -65,6 +65,7 @@ import org.hibernate.metamodel.spi.binding.AttributeBindingContainer;
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
import org.hibernate.metamodel.spi.binding.BasicPluralAttributeElementBinding;
import org.hibernate.metamodel.spi.binding.BasicPluralAttributeIndexBinding;
import org.hibernate.metamodel.spi.binding.Cascadeable;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer;
import org.hibernate.metamodel.spi.binding.CompositePluralAttributeElementBinding;
@ -181,10 +182,10 @@ public class Binder {
Binder.class.getName()
);
private static org.hibernate.internal.util.ValueHolder< Class< ? >> createSingularAttributeJavaType(
private static ValueHolder< Class< ? >> createSingularAttributeJavaType(
final Class< ? > attributeContainerClassReference,
final String attributeName ) {
org.hibernate.internal.util.ValueHolder.DeferredInitializer< Class< ? >> deferredInitializer =
ValueHolder.DeferredInitializer< Class< ? >> deferredInitializer =
new org.hibernate.internal.util.ValueHolder.DeferredInitializer< Class< ? >>() {
public Class< ? > initialize() {
return ReflectHelper.reflectedPropertyClass(
@ -192,7 +193,7 @@ public class Binder {
attributeName );
}
};
return new org.hibernate.internal.util.ValueHolder< Class< ? >>( deferredInitializer );
return new ValueHolder< Class< ? >>( deferredInitializer );
}
private static org.hibernate.internal.util.ValueHolder< Class< ? >> createSingularAttributeJavaType(
@ -557,7 +558,23 @@ public class Binder {
defaultElementJavaClassReference == null ? null : defaultElementJavaClassReference.getValue().getName()
);
bindHibernateResolvedType( elementBinding.getHibernateTypeDescriptor(), resolvedType );
elementBinding.setCascadeStyle( determineCascadeStyle( elementSource.getCascadeStyles() ) );
/**
* TODO
* don't know why, but see org.hibernate.mapping.Property#getCompositeCascadeStyle
*
* and not sure if this is the right place to apply this logic, apparently source level is not okay, so here it is, for now.
*/
for ( AttributeBinding ab : compositeAttributeBindingContainer.attributeBindings() ) {
if ( ab.isCascadeable() ) {
CascadeStyle cascadeStyle = Cascadeable.class.cast( ab ).getCascadeStyle();
if ( cascadeStyle != CascadeStyles.NONE ) {
elementBinding.setCascadeStyle( CascadeStyles.ALL );
}
}
}
if ( elementBinding.getCascadeStyle() == null || elementBinding.getCascadeStyle() == CascadeStyles.NONE ) {
elementBinding.setCascadeStyle( determineCascadeStyle( elementSource.getCascadeStyles() ) );
}
}
private void bindCollectionIndex(
@ -832,6 +849,7 @@ public class Binder {
// Create new entity binding
entityBinding = createEntityBinding( entitySource, superEntityBinding );
entityBinding.setMutable( entityBinding.getHierarchyDetails().getRootEntityBinding().isMutable() );
markSuperEntityTableAbstractIfNecessary(superEntityBinding);
bindPrimaryTable( entityBinding, entitySource );
bindSubEntityPrimaryKey( entityBinding, entitySource );
bindSecondaryTables( entityBinding, entitySource );
@ -844,11 +862,30 @@ public class Binder {
}
}
private void markSuperEntityTableAbstractIfNecessary(EntityBinding superEntityBinding) {
if ( superEntityBinding == null ) {
return;
}
if ( superEntityBinding.getHierarchyDetails().getInheritanceType() != InheritanceType.TABLE_PER_CLASS ) {
return;
}
if ( superEntityBinding.isAbstract() != Boolean.TRUE ) {
return;
}
if ( !Table.class.isInstance( superEntityBinding.getPrimaryTable() ) ) {
return;
}
Table.class.cast( superEntityBinding.getPrimaryTable() ).setPhysicalTable( false );
}
private void bindSubEntityPrimaryKey(final EntityBinding entityBinding, final EntitySource entitySource) {
final InheritanceType inheritanceType = entityBinding.getHierarchyDetails().getInheritanceType();
final EntityBinding superEntityBinding = entityBinding.getSuperEntityBinding();
if ( superEntityBinding == null ) {
throw new AssertionFailure( "super entitybinding is null " );
}
if ( inheritanceType == InheritanceType.TABLE_PER_CLASS ) {
}
if ( inheritanceType == InheritanceType.JOINED ) {
SubclassEntitySource subclassEntitySource = (SubclassEntitySource) entitySource;
@ -1957,11 +1994,14 @@ public class Binder {
);
}
if ( attributeSource instanceof IndexedPluralAttributeSource ) {
if ( attributeBinding.getAttribute().getNature().isIndexable() && attributeSource instanceof IndexedPluralAttributeSource ) {
attributeBinding.setIndex( true );
bindCollectionIndex(
( IndexedPluralAttributeBinding ) attributeBinding,
( ( IndexedPluralAttributeSource ) attributeSource ).getIndexSource(),
defaultCollectionIndexJavaTypeName( reflectedCollectionJavaTypes ) );
} else {
attributeBinding.setIndex( false );
}
bindCollectionTablePrimaryKey( attributeBinding, attributeSource );
@ -1974,6 +2014,7 @@ public class Binder {
final InheritanceType inheritanceType = entityBinding.getHierarchyDetails().getInheritanceType();
final TableSpecification table;
final String tableName;
// single table and sub entity
if ( superEntityBinding != null && inheritanceType == InheritanceType.SINGLE_TABLE ) {
table = superEntityBinding.getPrimaryTable();
tableName = superEntityBinding.getPrimaryTableName();
@ -1983,7 +2024,15 @@ public class Binder {
: entitySource.getEntityName();
entityBinding.setDiscriminatorMatchValue( discriminatorValue );
}
// single table and root entity
// joined
// table per class and non-abstract entity
else {
Table includedTable = null;
if(superEntityBinding!=null && inheritanceType == InheritanceType.TABLE_PER_CLASS && Table.class.isInstance( superEntityBinding.getPrimaryTable() )){
includedTable = Table.class.cast( superEntityBinding.getPrimaryTable());
}
table = createTable(
entitySource.getPrimaryTable(), new DefaultNamingStrategy() {
@ -1993,7 +2042,8 @@ public class Binder {
.getEntity().getName();
return bindingContexts.peek().getNamingStrategy().classToTableName( name );
}
}
},
includedTable
);
tableName = table.getLogicalName().getText();
}
@ -2029,6 +2079,8 @@ public class Binder {
column = table.createColumn( joinColumnSource.getName() );
if ( joinColumnSource.getSqlType() != null ) {
column.setSqlType( joinColumnSource.getSqlType() );
} else {
throw new NotYetImplementedException( "join key column sql type is not binded if not explicitly set" );
}
}
joinColumns.add( column );
@ -2534,10 +2586,15 @@ public class Binder {
? attributeBindingContainer.getAttributeContainer().createSyntheticSingularAttribute( attributeSource.getName() )
: attributeBindingContainer.getAttributeContainer().createSingularAttribute( attributeSource.getName() );
}
private TableSpecification createTable(final TableSpecificationSource tableSpecSource,
final DefaultNamingStrategy defaultNamingStrategy){
return createTable( tableSpecSource, defaultNamingStrategy, null );
}
private TableSpecification createTable(
final TableSpecificationSource tableSpecSource,
final DefaultNamingStrategy defaultNamingStrategy) {
final DefaultNamingStrategy defaultNamingStrategy,
final Table includedTable) {
final LocalBindingContext bindingContext = bindingContexts.peek();
final MappingDefaults mappingDefaults = bindingContext.getMappingDefaults();
@ -2556,7 +2613,7 @@ public class Binder {
throw bindingContext().makeMappingException( "An explicit name must be specified for the table" );
}
String tableName = defaultNamingStrategy.defaultName();
tableSpec = createTableSpecification( bindingContext, schema, tableName );
tableSpec = createTableSpecification( bindingContext, schema, tableName, includedTable );
}
else if ( tableSpecSource instanceof TableSource ) {
final TableSource tableSource = ( TableSource ) tableSpecSource;
@ -2567,7 +2624,7 @@ public class Binder {
}
tableName = defaultNamingStrategy.defaultName();
}
tableSpec = createTableSpecification( bindingContext, schema, tableName );
tableSpec = createTableSpecification( bindingContext, schema, tableName, includedTable );
}
else {
final InLineViewSource inLineViewSource = ( InLineViewSource ) tableSpecSource;
@ -2581,13 +2638,25 @@ public class Binder {
}
private TableSpecification createTableSpecification(LocalBindingContext bindingContext, Schema schema, String tableName) {
TableSpecification tableSpec;
return createTableSpecification( bindingContext, schema, tableName, null );
}
private TableSpecification createTableSpecification(LocalBindingContext bindingContext, Schema schema, String tableName, Table includedTable) {
tableName = quotedIdentifier( tableName );
final Identifier logicalTableId = Identifier.toIdentifier( tableName );
tableName = quotedIdentifier( bindingContext.getNamingStrategy().tableName( tableName ) );
final Identifier physicalTableId = Identifier.toIdentifier( tableName );
final Table table = schema.locateTable( logicalTableId );
tableSpec = ( table == null ? schema.createTable( logicalTableId, physicalTableId ) : table );
if ( table != null ) {
return table;
}
TableSpecification tableSpec;
if ( includedTable == null ) {
tableSpec = schema.createTable( logicalTableId, physicalTableId );
}
else {
tableSpec = schema.createDenormalizedTable( logicalTableId, physicalTableId, includedTable );
}
return tableSpec;
}

View File

@ -131,7 +131,7 @@ public class EntitySourceImpl implements EntitySource {
@Override
public boolean isAbstract() {
return false;
return entityClass.isAbstract();
}
@Override

View File

@ -93,6 +93,11 @@ public class ConfiguredClass {
*/
private final Class<?> clazz;
/**
* Is this class abstract?
*/
private final boolean isAbstract;
/**
* The default access type for this entity
*/
@ -154,6 +159,7 @@ public class ConfiguredClass {
this.parent = parent;
this.classInfo = classInfo;
this.clazz = context.locateClassByName( classInfo.toString() );
this.isAbstract = ReflectHelper.isAbstractClass( this.clazz );
this.classAccessType = determineClassAccessType( defaultAccessType );
this.customTuplizer = determineCustomTuplizer();
@ -183,6 +189,10 @@ public class ConfiguredClass {
return parent;
}
public boolean isAbstract() {
return isAbstract;
}
public EntityBindingContext getLocalBindingContext() {
return localBindingContext;
}

View File

@ -498,6 +498,7 @@ public abstract class AbstractEntitySourceImpl
}
public void add(SubclassEntitySourceImpl subclassEntitySource) {
subclassEntitySource.injectHierarchy( entityHierarchy );
entityHierarchy.processSubclass( subclassEntitySource );
subclassEntitySources.add( subclassEntitySource );
}

View File

@ -59,6 +59,7 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi
private String where;
private String orderBy;
private boolean sorted;
private boolean index;
private Comparator< ? > comparator;
private String customLoaderName;
@ -249,6 +250,14 @@ public abstract class AbstractPluralAttributeBinding extends AbstractAttributeBi
public void setMutable(boolean mutable) {
this.mutable = mutable;
}
@Override
public boolean hasIndex() {
return index;
}
public void setIndex(boolean index) {
this.index = index;
}
@Override
public int getBatchSize() {

View File

@ -29,6 +29,8 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.CascadeStyles;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.spi.domain.AttributeContainer;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
@ -45,7 +47,7 @@ import org.hibernate.metamodel.spi.source.MetaAttributeContext;
*/
public class CompositeAttributeBinding
extends AbstractSingularAttributeBinding
implements SingularNonAssociationAttributeBinding, CompositeAttributeBindingContainer {
implements SingularNonAssociationAttributeBinding, CompositeAttributeBindingContainer, Cascadeable {
private final AbstractCompositeAttributeBindingContainer compositeAttributeBindingContainer;
@ -220,6 +222,34 @@ public class CompositeAttributeBinding
return false;
}
@Override
public boolean isCascadeable() {
for ( AttributeBinding attributeBinding : attributeBindings() ) {
if ( attributeBinding.isCascadeable() ) {
return true;
}
}
return false;
}
@Override
public CascadeStyle getCascadeStyle() {
for ( AttributeBinding attributeBinding : attributeBindings() ) {
if ( attributeBinding.isCascadeable() ) {
CascadeStyle cascadeStyle = Cascadeable.class.cast( attributeBinding ).getCascadeStyle();
if ( cascadeStyle != CascadeStyles.NONE ) {
return CascadeStyles.ALL;
}
}
}
return CascadeStyles.NONE;
}
@Override
public void setCascadeStyle(CascadeStyle cascadeStyle) {
throw new IllegalAccessError( "Composite attribute is not supposed to have cascade" );
}
@Override
public boolean isNullable() {
// return false if there are any singular attributes are non-nullable

View File

@ -78,6 +78,8 @@ public interface PluralAttributeBinding extends AttributeBinding, Fetchable {
boolean isSorted();
boolean hasIndex();
Comparator getComparator();
int getBatchSize();

View File

@ -128,15 +128,15 @@ public abstract class AbstractConstraint implements Constraint {
}
protected void internalAddColumn(Column column) {
if ( column.getTable() != getTable() ) {
throw new AssertionFailure(
String.format(
"Unable to add column to constraint; tables [%s, %s] did not match",
column.getTable().toLoggableString(),
getTable().toLoggableString()
)
);
}
// if ( column.getTable() != getTable() ) {
// throw new AssertionFailure(
// String.format(
// "Unable to add column to constraint; tables [%s, %s] did not match",
// column.getTable().toLoggableString(),
// getTable().toLoggableString()
// )
// );
// }
columns.add( column );
}

View File

@ -102,6 +102,11 @@ public abstract class AbstractTableSpecification implements TableSpecification {
@Override
public DerivedValue locateOrCreateDerivedValue(String fragment) {
DerivedValue value = locateDerivedValue( fragment );
return value != null ? value : createDerivedValue( fragment );
}
protected DerivedValue locateDerivedValue(String fragment) {
final Identifier identifier = Identifier.toIdentifier( fragment );
if ( valueMap.containsKey( identifier ) ) {
Value value = valueMap.get( identifier );
@ -109,6 +114,11 @@ public abstract class AbstractTableSpecification implements TableSpecification {
return DerivedValue.class.cast( value );
}
}
return null;
}
protected DerivedValue createDerivedValue(String fragment) {
final Identifier identifier = Identifier.toIdentifier( fragment );
final DerivedValue value = new DerivedValue( this, valueList.size(), fragment );
valueMap.put( identifier, value );
valueList.add( value );

View File

@ -0,0 +1,76 @@
package org.hibernate.metamodel.spi.relational;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.hibernate.internal.util.collections.JoinedIterable;
/**
* @author Strong Liu <stliu@hibernate.org>
*/
public class DenormalizedTable extends Table {
private final Table includedTable;
public DenormalizedTable(Schema database, Identifier logicalName, Identifier physicalName, Table includedTable) {
super( database, logicalName, physicalName );
this.includedTable = includedTable;
}
@Override
public List<Value> values() {
List<Value> values = new ArrayList<Value>( super.values().size() + includedTable.values().size() );
values.addAll( super.values() );
values.addAll( includedTable.values() );
return Collections.unmodifiableList( values );
}
@Override
public Column locateColumn(String name) {
Column column = includedTable.locateColumn( name );
if(column!=null){
return column;
}
return super.locateColumn( name );
}
@Override
public boolean hasValue(Value value) {
return includedTable.hasValue( value ) || super.hasValue( value );
}
@Override
protected DerivedValue locateDerivedValue(String fragment) {
DerivedValue value = includedTable.locateDerivedValue( fragment );
return value != null ? value : super.locateDerivedValue( fragment );
}
@Override
public Iterable<ForeignKey> getForeignKeys() {
return new JoinedIterable<ForeignKey>(
Arrays.asList(
includedTable.getForeignKeys(),
super.getForeignKeys()
)
);
}
@Override
public Iterable<ForeignKey> locateForeignKey(TableSpecification targetTable) {
Iterable<ForeignKey> fks = includedTable.locateForeignKey( targetTable );
return fks != null ? fks : super.locateForeignKey( targetTable );
}
@Override
protected <T extends Constraint> T locateConstraint(Iterable<T> constraints, String name) {
T t = includedTable.locateConstraint( constraints, name );
return t != null ? t : super.locateConstraint( constraints, name );
}
@Override
public PrimaryKey getPrimaryKey() {
return includedTable.getPrimaryKey();
}
}

View File

@ -88,6 +88,12 @@ public class Schema {
return table;
}
public DenormalizedTable createDenormalizedTable(Identifier logicalTableName, Identifier physicalTableName, Table includedTable) {
DenormalizedTable table = new DenormalizedTable( this, logicalTableName, physicalTableName, includedTable );
tables.put( logicalTableName, table );
return table;
}
public Iterable<Table> getTables() {
return tables.values();
}

View File

@ -48,6 +48,7 @@ public class Table extends AbstractTableSpecification implements Exportable {
private Identifier logicalName;
private ObjectName qualifiedName;
private String exportIdentifier;
private boolean isPhysicalTable = true;
private final Set<Index> indexes = new LinkedHashSet<Index>();
private final Set<UniqueKey> uniqueKeys = new LinkedHashSet<UniqueKey>();
@ -95,6 +96,19 @@ public class Table extends AbstractTableSpecification implements Exportable {
return physicalName;
}
/**
* Is this a physical table or should it be a virtual table representing as root entity in table-per-class hierarchy.
*
* It's {@code false} only when the entity is {@code abstract} and also having union sub-class
*/
public boolean isPhysicalTable() {
return isPhysicalTable;
}
public void setPhysicalTable(boolean physicalTable) {
isPhysicalTable = physicalTable;
}
/**
* Gets the qualified table name.
*
@ -245,13 +259,8 @@ public class Table extends AbstractTableSpecification implements Exportable {
alter.append( " default " )
.append( defaultValue );
}
if ( column.isNullable() ) {
alter.append( dialect.getNullColumnString() );
}
else {
alter.append( " not null" );
}
String nullablePostfix = column.isNullable() ? dialect.getNullColumnString() : " not null";
alter.append( nullablePostfix );
boolean useUniqueConstraint = column.isUnique()
&& dialect.supportsUnique()

View File

@ -821,7 +821,7 @@ public abstract class AbstractCollectionPersister
// INDEX AND ROW SELECT
hasIndex = collection.getAttribute().getNature().isIndexable();
hasIndex = collection.hasIndex();
indexContainsFormula = false;
if ( hasIndex ) {
// NativeSQL: collect index column and auto-aliases
@ -926,7 +926,7 @@ public abstract class AbstractCollectionPersister
}
sqlSelectSizeString = generateSelectSizeString(
collection.getAttribute().getNature().isIndexable() &&
collection.hasIndex() &&
collection.getAttribute().getNature() != PluralAttribute.Nature.MAP
);
sqlDetectRowByIndexString = generateDetectRowByIndexString();

View File

@ -260,9 +260,10 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
}
private CustomSQLMetadata parse(CustomSQL customSql) {
final String sql = customSql.getSql();
final boolean callable = sql != null && customSql.isCallable();
final ExecuteUpdateResultCheckStyle checkStyle = sql == null
final boolean callable = customSql != null && customSql.isCallable();
final String sql = customSql == null ? null: customSql.getSql();
final ExecuteUpdateResultCheckStyle checkStyle = customSql == null
? ExecuteUpdateResultCheckStyle.COUNT
: customSql.getCheckStyle() == null
? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
@ -341,11 +342,13 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
//TODO: i'm not sure, but perhaps we should exclude
// abstract denormalized tables?
int spacesSize = 1 + entityBinding.getSynchronizedTableNames().length;
String[] synchronizedTableNames = entityBinding.getSynchronizedTableNames();
int spacesSize = 1 +synchronizedTableNames.length;
spaces = new String[spacesSize];
spaces[0] = tableName;
String[] synchronizedTableNames = entityBinding.getSynchronizedTableNames();
System.arraycopy( synchronizedTableNames, 0, spaces, 1, spacesSize );
if ( ArrayHelper.isNotEmpty( synchronizedTableNames ) ) {
System.arraycopy( synchronizedTableNames, 0, spaces, 1, spacesSize );
}
HashSet<String> subclassTables = new HashSet<String>();
Iterable<EntityBinding> iter = entityBinding.getPreOrderSubEntityBindingClosure();
@ -543,68 +546,95 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
}
private boolean isNotAbstractUnionTable(EntityBinding entityBinding) {
return !entityBinding.isAbstract() && entityBinding.getHierarchyDetails()
.getInheritanceType() != InheritanceType.TABLE_PER_CLASS;
// return !entityBinding.isAbstract() && entityBinding.getHierarchyDetails()
// .getInheritanceType() != InheritanceType.TABLE_PER_CLASS;
return !entityBinding.isAbstract();
}
private void visitEntityHierarchy(EntityBinding entityBinding, Callback callback){
EntityBinding rootEntityBinding = entityBinding.getHierarchyDetails().getRootEntityBinding();
callback.execute( rootEntityBinding );
visitSubEntityBindings( rootEntityBinding, callback );
}
private void visitSubEntityBindings(EntityBinding superEntityBinding, Callback callback){
Iterable<EntityBinding> entityBindings= superEntityBinding.getDirectSubEntityBindings();
for(EntityBinding entityBinding : entityBindings){
callback.execute( entityBinding );
}
for(EntityBinding entityBinding : entityBindings){
visitSubEntityBindings( entityBinding, callback );
}
}
private static interface Callback{
void execute(EntityBinding entityBinding);
}
protected String generateSubquery(EntityBinding entityBinding){
Dialect dialect = getFactory().getDialect();
Settings settings = getFactory().getSettings();
final Dialect dialect = getFactory().getDialect();
if ( !entityBinding.hasSubEntityBindings() ) {
return entityBinding.getPrimaryTable().getQualifiedName( dialect );
}
HashSet<org.hibernate.metamodel.spi.relational.Column> columns = new LinkedHashSet<org.hibernate.metamodel.spi.relational.Column>();
Iterable<EntityBinding> subEntityBindings = entityBinding.getPreOrderSubEntityBindingClosure();
Iterator<EntityBinding> siter = new JoinedIterator<EntityBinding>(
new SingletonIterator<EntityBinding>(entityBinding),
subEntityBindings.iterator()
);
while ( siter.hasNext() ) {
EntityBinding eb = siter.next();
if ( isNotAbstractUnionTable( eb ) ) {
TableSpecification table = entityBinding.getPrimaryTable();
for ( Value v : table.values() ) {
if ( org.hibernate.metamodel.spi.relational.Column.class.isInstance( v ) ) {
columns.add( org.hibernate.metamodel.spi.relational.Column.class.cast( v ) );
final HashSet<org.hibernate.metamodel.spi.relational.Column> columns = new LinkedHashSet<org.hibernate.metamodel.spi.relational.Column>();
// Iterable<EntityBinding> subEntityBindings = entityBinding.getHierarchyDetails()..getEntityBindingClosure();
// for(EntityBinding eb : subEntityBindings){
// if ( isNotAbstractUnionTable( eb ) ) {
// TableSpecification table = entityBinding.getPrimaryTable();
// for ( Value v : table.values() ) {
// if ( org.hibernate.metamodel.spi.relational.Column.class.isInstance( v ) ) {
// columns.add( org.hibernate.metamodel.spi.relational.Column.class.cast( v ) );
// }
// }
// }
// }
visitEntityHierarchy(
entityBinding, new Callback() {
@Override
public void execute(EntityBinding eb) {
if ( isNotAbstractUnionTable( eb ) ) {
TableSpecification table = eb.getPrimaryTable();
for ( Value v : table.values() ) {
if ( org.hibernate.metamodel.spi.relational.Column.class.isInstance( v ) ) {
columns.add( org.hibernate.metamodel.spi.relational.Column.class.cast( v ) );
}
}
}
}
}
);
StringBuilder buf = new StringBuilder()
final StringBuilder buf = new StringBuilder()
.append("( ");
siter = new JoinedIterator<EntityBinding>(
new SingletonIterator<EntityBinding>(entityBinding),
subEntityBindings.iterator()
);
while ( siter.hasNext() ) {
EntityBinding eb = siter.next();
TableSpecification table = eb.getPrimaryTable();
if ( isNotAbstractUnionTable( eb )) {
//TODO: move to .sql package!!
buf.append("select ");
for(org.hibernate.metamodel.spi.relational.Column column : columns){
if(!table.hasValue( column )){
buf.append( dialect.getSelectClauseNullString(column.getJdbcDataType().getTypeCode()) )
.append(" as ");
visitSubEntityBindings( entityBinding, new Callback() {
@Override
public void execute(EntityBinding eb) {
TableSpecification table = eb.getPrimaryTable();
if ( isNotAbstractUnionTable( eb )) {
//TODO: move to .sql package!!
buf.append("select ");
for(org.hibernate.metamodel.spi.relational.Column column : columns){
if(!table.hasValue( column )){
buf.append( dialect.getSelectClauseNullString(column.getJdbcDataType().getTypeCode()) )
.append(" as ");
}
buf.append( column.getColumnName().getText( dialect ) );
buf.append( ", " );
}
buf.append( eb.getSubEntityBindingId() )
.append( " as clazz_" );
buf.append(" from ")
.append( table.getQualifiedName( dialect ));
buf.append(" union ");
if ( dialect.supportsUnionAll() ) {
buf.append("all ");
}
buf.append( column.getColumnName().getText( dialect ) );
buf.append( ", " );
}
buf.append( eb.getSubEntityBindingId() )
.append( " as clazz_" );
buf.append(" from ")
.append( table.getQualifiedName( dialect ));
buf.append(" union ");
if ( dialect.supportsUnionAll() ) {
buf.append("all ");
}
}
}
} );
if ( buf.length() > 2 ) {
//chop the last union (all)

View File

@ -94,6 +94,9 @@ public class SchemaCreatorImpl implements SchemaCreator {
}
for ( Table table : schema.getTables() ) {
if( !table.isPhysicalTable() ){
continue;
}
checkExportIdentifier( table, exportIdentifiers );
applySqlStrings( targets, dialect.getTableExporter().getSqlCreateStrings( table, jdbcEnvironment ) );

View File

@ -80,6 +80,9 @@ public class SchemaDropperImpl implements SchemaDropper {
for ( Schema schema : database.getSchemas() ) {
for ( Table table : schema.getTables() ) {
if( !table.isPhysicalTable() ){
continue;
}
if ( dialect.dropConstraints() ) {
// we need to drop constraints prior to dropping table

View File

@ -82,6 +82,9 @@ public class SchemaMigratorImpl implements SchemaMigrator {
}
for ( Table table : schema.getTables() ) {
if( !table.isPhysicalTable() ){
continue;
}
checkExportIdentifier( table, exportIdentifiers );
final TableInformation tableInformation = existingDatabase.getTableInformation( table.getTableName() );
if ( tableInformation == null ) {

View File

@ -44,6 +44,9 @@ public class SchemaValidatorImpl implements SchemaValidator {
public void doValidation(Database database, DatabaseInformation databaseInformation) {
for ( Schema schema : database.getSchemas() ) {
for ( Table table : schema.getTables() ) {
if( !table.isPhysicalTable() ){
continue;
}
final TableInformation tableInformation = databaseInformation.getTableInformation(
table.getTableName()
);

View File

@ -30,10 +30,8 @@ import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@FailureExpectedWithNewMetamodel
public class CascadeToEmbeddedManyToOneTest extends BaseCoreFunctionalTestCase {
@Test

View File

@ -27,6 +27,7 @@ import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
@ -53,7 +54,7 @@ class CodedPairSetHolder implements Serializable {
private String code;
@ElementCollection
@JoinTable(name = "CODED_PAIR_HOLDER_PAIR_SET", joinColumns = @JoinColumn(name = "CODED_PAIR_HOLDER_ID"))
@CollectionTable(name = "CODED_PAIR_HOLDER_PAIR_SET", joinColumns = @JoinColumn(name = "CODED_PAIR_HOLDER_ID"))
@ForeignKey(name = "FK_PAIR_SET")
private final Set<PersonPair> pairs = new HashSet<PersonPair>(0);

View File

@ -26,6 +26,7 @@ package org.hibernate.test.annotations.collectionelement;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
@ -55,9 +56,7 @@ public class EntityWithAnElementCollection {
@ElementCollection
// HHH-7732 -- "EntityWithAnElementCollection_someStrings" is too long for Oracle.
@JoinTable(
name = "SomeStrings",
joinColumns = @JoinColumn( name = "EWAEC_ID") )
@CollectionTable(name = "SomeStrings", joinColumns = @JoinColumn( name = "EWAEC_ID") )
public Set<String> getSomeStrings() {
return someStrings;
}

View File

@ -27,14 +27,12 @@ import org.hibernate.Session;
import org.junit.Test;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/**
* @author Steve Ebersole
*/
@FailureExpectedWithNewMetamodel
public class QueryTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {

View File

@ -26,7 +26,6 @@ package org.hibernate.test.annotations.collectionelement.indexedCollection;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
@ -34,7 +33,6 @@ import static org.junit.Assert.assertEquals;
/**
* @author Emmanuel Bernard
*/
@FailureExpectedWithNewMetamodel
public class IndexedCollectionOfElementsTest extends BaseCoreFunctionalTestCase {
@Test
public void testIndexedCollectionOfElements() throws Exception {

View File

@ -2,6 +2,7 @@
package org.hibernate.test.annotations.collectionelement.indexedCollection;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
@ -22,7 +23,7 @@ import org.hibernate.annotations.Type;
public class Sale {
@Id @GeneratedValue private Integer id;
@ElementCollection
@JoinTable(
@CollectionTable(
name = "contact",
joinColumns = @JoinColumn(name = "n_key_person"))
@CollectionId(

View File

@ -32,7 +32,6 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/**
* @author Steve Ebersole
*/
@FailureExpectedWithNewMetamodel
public class ElementCollectionSortingTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {

View File

@ -25,6 +25,7 @@ package org.hibernate.test.annotations.collectionelement.ordered;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@ -74,7 +75,7 @@ public class Person {
@ElementCollection
@JoinColumn
@JoinTable(name = "T_NICKNAMES_A")
@CollectionTable(name = "T_NICKNAMES_A")
@OrderBy
public Set<String> getNickNamesAscendingNaturalSort() {
return nickNamesAscendingNaturalSort;
@ -86,7 +87,7 @@ public class Person {
@ElementCollection
@JoinColumn
@JoinTable(name = "T_NICKNAMES_D")
@CollectionTable(name = "T_NICKNAMES_D")
@OrderBy( "desc" )
public Set<String> getNickNamesDescendingNaturalSort() {
return nickNamesDescendingNaturalSort;
@ -100,7 +101,7 @@ public class Person {
@ElementCollection
@JoinColumn
@OrderBy
@JoinTable(name = "T_ADDRESS_A")
@CollectionTable(name = "T_ADDRESS_A")
public Set<Address> getAddressesAscendingNaturalSort() {
return addressesAscendingNaturalSort;
}
@ -112,7 +113,7 @@ public class Person {
@ElementCollection
@JoinColumn
@OrderBy( "desc" )
@JoinTable(name = "T_ADDRESS_D")
@CollectionTable(name = "T_ADDRESS_D")
public Set<Address> getAddressesDescendingNaturalSort() {
return addressesDescendingNaturalSort;
}
@ -124,7 +125,7 @@ public class Person {
@ElementCollection
@JoinColumn
@OrderBy( "city" )
@JoinTable(name = "T_ADD_CITY_A")
@CollectionTable(name = "T_ADD_CITY_A")
public Set<Address> getAddressesCityAscendingSort() {
return addressesCityAscendingSort;
}
@ -136,7 +137,7 @@ public class Person {
@ElementCollection
@JoinColumn
@OrderBy( "city desc" )
@JoinTable(name = "T_ADD_CITY_D")
@CollectionTable(name = "T_ADD_CITY_D")
public Set<Address> getAddressesCityDescendingSort() {
return addressesCityDescendingSort;
}

View File

@ -27,7 +27,6 @@ import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.test.util.SchemaUtil;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
@ -36,7 +35,6 @@ import static org.junit.Assert.assertTrue;
/**
* @author Emmanuel Bernard
*/
@FailureExpectedWithNewMetamodel
public class DerivedIdentitySimpleParentEmbeddedDepTest extends BaseCoreFunctionalTestCase {
@Test
public void testManyToOne() throws Exception {

View File

@ -27,7 +27,6 @@ import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.test.util.SchemaUtil;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
@ -37,7 +36,6 @@ import static org.junit.Assert.assertTrue;
/**
* @author Emmanuel Bernard
*/
@FailureExpectedWithNewMetamodel
public class DerivedIdentityEmbeddedIdParentIdClassTest extends BaseCoreFunctionalTestCase {
@Test
public void testManyToOne() throws Exception {

View File

@ -4,6 +4,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
@ -57,7 +58,7 @@ public class Atmosphere {
@ElementCollection
@Column(name="composition_rate")
@MapKeyJoinColumns( { @MapKeyJoinColumn(name="gas_id" ) } ) //use @MapKeyJoinColumns explicitly for tests
@JoinTable(name = "Composite", joinColumns = @JoinColumn(name = "atmosphere_id"))
@CollectionTable(name = "Composite", joinColumns = @JoinColumn(name = "atmosphere_id"))
public Map<Gas, Double> composition = new HashMap<Gas, Double>();
//use default JPA 2 column name for map key

View File

@ -3,6 +3,7 @@ package org.hibernate.test.annotations.override;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.FetchType;
@ -25,7 +26,7 @@ public abstract class Entry implements Serializable {
private Long id;
@ElementCollection(fetch = FetchType.EAGER)
@JoinTable(name = "TAGS", joinColumns = @JoinColumn(name = "ID"))
@CollectionTable(name = "TAGS", joinColumns = @JoinColumn(name = "ID"))
@Column(name = "KEYWORD")
@Fetch(FetchMode.JOIN)
private Set<String> tags = new HashSet<String>();

View File

@ -31,7 +31,6 @@ import org.hibernate.JDBCException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
@ -40,7 +39,6 @@ import static org.junit.Assert.fail;
/**
* @author Emmanuel Bernard
*/
@FailureExpectedWithNewMetamodel
public class TablePerClassTest extends BaseCoreFunctionalTestCase {
@Test
public void testUnionSubClass() throws Exception {

View File

@ -26,7 +26,6 @@ package org.hibernate.test.component.cascading.toone;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertNotNull;
@ -42,7 +41,6 @@ public class CascadeToComponentAssociationTest extends BaseCoreFunctionalTestCas
}
@Test
@FailureExpectedWithNewMetamodel
public void testMerging() {
// step1, we create a document with owner
Session session = openSession();

View File

@ -31,14 +31,12 @@ import org.hibernate.Session;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/**
* @author Steve Ebersole
*/
@FailureExpectedWithNewMetamodel
@RequiresDialect(H2Dialect.class)
public class DoesNotWorkTest extends BaseCoreFunctionalTestCase {
@Override

View File

@ -26,12 +26,16 @@ package org.hibernate.test.util;
import java.util.Iterator;
import org.hibernate.AssertionFailure;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.spi.MetadataImplementor;
import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.Identifier;
import org.hibernate.metamodel.spi.relational.PrimaryKey;
import org.hibernate.metamodel.spi.relational.Schema;
import org.hibernate.metamodel.spi.relational.TableSpecification;
/**
@ -42,7 +46,7 @@ import org.hibernate.metamodel.spi.relational.TableSpecification;
public abstract class SchemaUtil {
public static boolean isColumnPresent(
String tableName, String columnName, Metadata metadata ) {
String tableName, String columnName, MetadataImplementor metadata ) {
try {
TableSpecification table = getTable( tableName, metadata );
return ( table.locateColumn( columnName ) == null ) ? false : true;
@ -51,7 +55,7 @@ public abstract class SchemaUtil {
}
}
public static boolean isTablePresent( String tableName, Metadata metadata ) {
public static boolean isTablePresent( String tableName, MetadataImplementor metadata ) {
try {
TableSpecification table = getTable( tableName, metadata );
return ( table == null ) ? false : true;
@ -61,33 +65,51 @@ public abstract class SchemaUtil {
}
public static EntityBinding getEntityBinding(
Class<?> entityClass, Metadata metadata ) {
Class<?> entityClass, MetadataImplementor metadata ) {
return metadata.getEntityBinding( entityClass.getName() );
}
public static TableSpecification getTable(
Class<?> entityClass, Metadata metadata ) throws AssertionFailure {
Class<?> entityClass, MetadataImplementor metadata ) throws AssertionFailure {
return getEntityBinding( entityClass, metadata ).getPrimaryTable();
}
public static TableSpecification getTable(String schemaName, String tableName, MetadataImplementor metadata) throws AssertionFailure{
if( StringHelper.isNotEmpty(schemaName)){
Schema schema = metadata.getDatabase().getSchema( null, schemaName );
if(schema == null){
throw new AssertionFailure( "can't find schema "+ schemaName );
}
return schema.locateTable( Identifier.toIdentifier(tableName) );
} else {
Iterable<Schema> schemas = metadata.getDatabase().getSchemas();
for(Schema schema : schemas){
TableSpecification table = schema.locateTable( Identifier.toIdentifier( tableName ) );
if(table != null){
return table;
}
}
}
throw new AssertionFailure( "can't find table " +tableName );
}
public static TableSpecification getTable(
String tableName, Metadata metadata ) throws AssertionFailure {
final EntityBinding binding = metadata.getEntityBinding( tableName );
return binding.locateTable( tableName );
String tableName, MetadataImplementor metadata ) throws AssertionFailure {
return getTable( null, tableName, metadata );
}
public static Column getColumn( Class<?> entityClass, String columnName,
Metadata metadata ) throws AssertionFailure {
MetadataImplementor metadata ) throws AssertionFailure {
return getTable( entityClass, metadata ).locateColumn( columnName );
}
public static Column getColumn( String tableName, String columnName,
Metadata metadata ) throws AssertionFailure {
MetadataImplementor metadata ) throws AssertionFailure {
return getTable( tableName, metadata ).locateColumn( columnName );
}
public static Column getColumnByAttribute( Class<?> entityClass,
String attributeName, Metadata metadata ) throws AssertionFailure {
String attributeName, MetadataImplementor metadata ) throws AssertionFailure {
EntityBinding binding = getEntityBinding( entityClass, metadata );
AttributeBinding attributeBinding = binding.locateAttributeBinding(
attributeName );
@ -96,7 +118,7 @@ public abstract class SchemaUtil {
}
public static PrimaryKey getPrimaryKey( Class<?> entityClass,
Metadata metadata ) throws AssertionFailure {
MetadataImplementor metadata ) throws AssertionFailure {
return getTable( entityClass, metadata ).getPrimaryKey();
}