HHH-7830 : union-subclass support
This commit is contained in:
parent
ba0f96639e
commit
e55c1bb47e
|
@ -685,7 +685,7 @@ public class Binder {
|
|||
quotedIdentifier( secondaryTableSource.getExplicitForeignKeyName() ),
|
||||
table,
|
||||
joinRelationalValueBindings,
|
||||
determineForeignKeyTargetTable( entityBinding, targetColumns ),
|
||||
determineForeignKeyTargetTable( entityBinding, secondaryTableSource ),
|
||||
targetColumns
|
||||
);
|
||||
SecondaryTable secondaryTable = new SecondaryTable( table, foreignKey );
|
||||
|
@ -1205,7 +1205,7 @@ public class Binder {
|
|||
quotedIdentifier( attributeSource.getExplicitForeignKeyName() ),
|
||||
attributeBinding.getRelationalValueBindings().get( 0 ).getTable(),
|
||||
attributeBinding.getRelationalValueBindings(),
|
||||
determineForeignKeyTargetTable( attributeBinding.getReferencedEntityBinding(), targetColumns ),
|
||||
determineForeignKeyTargetTable( attributeBinding.getReferencedEntityBinding(), attributeSource ),
|
||||
targetColumns
|
||||
);
|
||||
}
|
||||
|
@ -1328,7 +1328,7 @@ public class Binder {
|
|||
quotedIdentifier( attributeSource.getExplicitForeignKeyName() ),
|
||||
foreignKeyRelationalValueBindings.get( 0 ).getTable(),
|
||||
foreignKeyRelationalValueBindings,
|
||||
determineForeignKeyTargetTable( attributeBinding.getReferencedEntityBinding(), targetColumns ),
|
||||
determineForeignKeyTargetTable( attributeBinding.getReferencedEntityBinding(), attributeSource ),
|
||||
targetColumns
|
||||
);
|
||||
}
|
||||
|
@ -1896,7 +1896,7 @@ public class Binder {
|
|||
quotedIdentifier( elementSource.getExplicitForeignKeyName() ),
|
||||
collectionTable,
|
||||
elementBinding.getRelationalValueBindings(),
|
||||
determineForeignKeyTargetTable( referencedEntityBinding, targetColumns ),
|
||||
determineForeignKeyTargetTable( referencedEntityBinding, elementSource ),
|
||||
targetColumns
|
||||
);
|
||||
}
|
||||
|
@ -2196,44 +2196,13 @@ public class Binder {
|
|||
final String referencedAttributeName = resolutionDelegate.getReferencedAttributeName();
|
||||
if ( referencedAttributeName == null ) {
|
||||
referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding(
|
||||
resolutionDelegate.getJoinColumns(
|
||||
new JoinColumnResolutionContext() {
|
||||
@Override
|
||||
public List<Value> resolveRelationalValuesForAttribute(String attributeName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Column resolveColumn(String logicalColumnName, String logicalTableName, String logicalSchemaName, String logicalCatalogName) {
|
||||
for ( AttributeBinding attributeBinding : attributeBindingContainer.attributeBindings() ) {
|
||||
if ( SingularAttributeBinding.class.isInstance( attributeBinding ) ) {
|
||||
SingularAttributeBinding singularAttributeBinding = SingularAttributeBinding.class
|
||||
.cast(
|
||||
attributeBinding
|
||||
);
|
||||
for ( RelationalValueBinding relationalValueBinding : singularAttributeBinding
|
||||
.getRelationalValueBindings() ) {
|
||||
if ( Column.class.isInstance( relationalValueBinding.getValue() ) ) {
|
||||
Identifier columnIdentifier = createIdentifier( logicalColumnName);
|
||||
Column column = Column.class.cast( relationalValueBinding.getValue() );
|
||||
if ( column.getColumnName().equals( columnIdentifier ) ) {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
)
|
||||
resolutionDelegate.getJoinColumns( new JoinColumnResolutionContextImpl( entityBinding ) )
|
||||
);
|
||||
}
|
||||
else {
|
||||
referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( referencedAttributeName );
|
||||
}
|
||||
|
||||
|
||||
if ( referencedAttributeBinding == null ) {
|
||||
referencedAttributeBinding = attributeBinding(
|
||||
entityBinding.getEntity().getName(),
|
||||
|
@ -2402,7 +2371,7 @@ public class Binder {
|
|||
quotedIdentifier( keySource.getExplicitForeignKeyName() ),
|
||||
collectionTable,
|
||||
sourceRelationalBindings,
|
||||
determineForeignKeyTargetTable( attributeBinding.getContainer().seekEntityBinding(), targetColumns ),
|
||||
determineForeignKeyTargetTable( attributeBinding.getContainer().seekEntityBinding(), keySource ),
|
||||
targetColumns
|
||||
);
|
||||
foreignKey.setDeleteRule( keySource.getOnDeleteAction() );
|
||||
|
@ -2539,7 +2508,7 @@ public class Binder {
|
|||
quotedIdentifier( subclassEntitySource.getExplicitForeignKeyName() ),
|
||||
entityBinding.getPrimaryTable(),
|
||||
sourceColumns,
|
||||
determineForeignKeyTargetTable( superEntityBinding, targetColumns ),
|
||||
determineForeignKeyTargetTable( superEntityBinding, subclassEntitySource ),
|
||||
targetColumns
|
||||
);
|
||||
|
||||
|
@ -2851,60 +2820,7 @@ public class Binder {
|
|||
}
|
||||
else {
|
||||
final List<Column> columns = new ArrayList<Column>();
|
||||
final JoinColumnResolutionContext resolutionContext =
|
||||
new JoinColumnResolutionContext() {
|
||||
@Override
|
||||
public Column resolveColumn(
|
||||
String logicalColumnName,
|
||||
String logicalTableName,
|
||||
String logicalSchemaName,
|
||||
String logicalCatalogName) {
|
||||
// ignore table, schema, catalog name
|
||||
Column column = entityBinding.getPrimaryTable().locateColumn( logicalColumnName );
|
||||
if ( column == null ) {
|
||||
column = entityBinding.getPrimaryTable().createColumn( logicalColumnName );
|
||||
}
|
||||
return column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Value> resolveRelationalValuesForAttribute(String attributeName) {
|
||||
if ( attributeName == null ) {
|
||||
List<Value> values = new ArrayList<Value>();
|
||||
for ( Column column : entityBinding.getPrimaryTable().getPrimaryKey().getColumns() ) {
|
||||
values.add( column );
|
||||
}
|
||||
return values;
|
||||
}
|
||||
final AttributeBinding referencedAttributeBinding =
|
||||
entityBinding.locateAttributeBindingByPath( attributeName, true );
|
||||
if ( referencedAttributeBinding == null ) {
|
||||
throw bindingContext().makeMappingException(
|
||||
String.format(
|
||||
"Could not resolve named referenced property [%s] against entity [%s]",
|
||||
attributeName,
|
||||
entityBinding.getEntity().getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
if ( !referencedAttributeBinding.getAttribute().isSingular() ) {
|
||||
throw bindingContext().makeMappingException(
|
||||
String.format(
|
||||
"Referenced property [%s] against entity [%s] is a plural attribute; it must be a singular attribute.",
|
||||
attributeName,
|
||||
entityBinding.getEntity().getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
List<RelationalValueBinding> valueBindings =
|
||||
( (SingularAttributeBinding) referencedAttributeBinding ).getRelationalValueBindings();
|
||||
List<Value> values = new ArrayList<Value>( valueBindings.size() );
|
||||
for ( RelationalValueBinding valueBinding : valueBindings ) {
|
||||
values.add( valueBinding.getValue() );
|
||||
}
|
||||
return values;
|
||||
}
|
||||
};
|
||||
final JoinColumnResolutionContext resolutionContext = new JoinColumnResolutionContextImpl( entityBinding );
|
||||
for ( Value relationalValue : fkColumnResolutionDelegate.getJoinColumns( resolutionContext ) ) {
|
||||
if ( !Column.class.isInstance( relationalValue ) ) {
|
||||
throw bindingContext().makeMappingException(
|
||||
|
@ -2917,41 +2833,19 @@ public class Binder {
|
|||
}
|
||||
}
|
||||
|
||||
private TableSpecification determineForeignKeyTargetTable(final EntityBinding entityBinding,
|
||||
final List<Column> targetColumns) {
|
||||
TableSpecification table = null;
|
||||
TableSpecification actualTable = null;
|
||||
boolean first = true;
|
||||
for ( Column column : targetColumns) {
|
||||
if ( first ) {
|
||||
table = column.getTable();
|
||||
if ( entityBinding.hasTable( table.getLogicalName().getText() ) ) {
|
||||
actualTable = table;
|
||||
}
|
||||
else {
|
||||
if ( entityBinding.getHierarchyDetails().getInheritanceType() == InheritanceType.TABLE_PER_CLASS &&
|
||||
column == entityBinding.getPrimaryTable().locateColumn( column.getColumnName().getText() ) ) {
|
||||
actualTable = entityBinding.getPrimaryTable();
|
||||
}
|
||||
else {
|
||||
throw bindingContext().makeMappingException( "improve this message!!!" );
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
if ( !table.equals( column.getTable() ) ) {
|
||||
throw bindingContext().makeMappingException(
|
||||
String.format(
|
||||
"Join columns come from more than one table: %s, %s ",
|
||||
table,
|
||||
column.getTable()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
private TableSpecification determineForeignKeyTargetTable(
|
||||
final EntityBinding entityBinding,
|
||||
final ForeignKeyContributingSource foreignKeyContributingSource) {
|
||||
|
||||
final JoinColumnResolutionDelegate fkColumnResolutionDelegate =
|
||||
foreignKeyContributingSource.getForeignKeyTargetColumnResolutionDelegate();
|
||||
if ( fkColumnResolutionDelegate == null ) {
|
||||
return entityBinding.getPrimaryTable();
|
||||
}
|
||||
else {
|
||||
final JoinColumnResolutionContext resolutionContext = new JoinColumnResolutionContextImpl( entityBinding );
|
||||
return fkColumnResolutionDelegate.getReferencedTable( resolutionContext );
|
||||
}
|
||||
return actualTable;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ simple instance helper methods
|
||||
|
@ -3274,19 +3168,23 @@ public class Binder {
|
|||
String logicalTableName,
|
||||
String logicalSchemaName,
|
||||
String logicalCatalogName) {
|
||||
if ( bindingContext().isGloballyQuotedIdentifiers() && !StringHelper.isQuoted( logicalColumnName ) ) {
|
||||
logicalColumnName = StringHelper.quote( logicalColumnName );
|
||||
}
|
||||
return resolveTable( logicalTableName, logicalSchemaName, logicalCatalogName ).locateOrCreateColumn(
|
||||
logicalColumnName
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification resolveTable(String logicalTableName, String logicalSchemaName, String logicalCatalogName) {
|
||||
Identifier tableIdentifier = createIdentifier( logicalTableName );
|
||||
if ( tableIdentifier == null ) {
|
||||
tableIdentifier = referencedEntityBinding.getPrimaryTable().getLogicalName();
|
||||
}
|
||||
|
||||
Schema schema = metadata.getDatabase().getSchema( logicalCatalogName, logicalSchemaName );
|
||||
Table table = schema.locateTable( tableIdentifier );
|
||||
|
||||
if ( bindingContext().isGloballyQuotedIdentifiers() && !StringHelper.isQuoted( logicalColumnName ) ) {
|
||||
logicalColumnName = StringHelper.quote( logicalColumnName );
|
||||
}
|
||||
|
||||
return table.locateColumn( logicalColumnName );
|
||||
return schema.locateTable( tableIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3298,12 +3196,35 @@ public class Binder {
|
|||
}
|
||||
return values;
|
||||
}
|
||||
List<RelationalValueBinding> valueBindings =
|
||||
resolveReferencedAttributeBinding( attributeName ).getRelationalValueBindings();
|
||||
List<Value> values = new ArrayList<Value>( valueBindings.size() );
|
||||
for ( RelationalValueBinding valueBinding : valueBindings ) {
|
||||
values.add( valueBinding.getValue() );
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification resolveTableForAttribute(String attributeName) {
|
||||
if ( attributeName == null ) {
|
||||
return referencedEntityBinding.getPrimaryTable();
|
||||
}
|
||||
else {
|
||||
return resolveReferencedAttributeBinding( attributeName ).getRelationalValueBindings().get( 0 ).getTable();
|
||||
}
|
||||
}
|
||||
|
||||
private SingularAttributeBinding resolveReferencedAttributeBinding(String attributeName) {
|
||||
if ( attributeName == null ) {
|
||||
return referencedEntityBinding.getHierarchyDetails().getEntityIdentifier().getAttributeBinding();
|
||||
}
|
||||
final AttributeBinding referencedAttributeBinding =
|
||||
referencedEntityBinding.locateAttributeBinding( attributeName );
|
||||
referencedEntityBinding.locateAttributeBindingByPath( attributeName, true );
|
||||
if ( referencedAttributeBinding == null ) {
|
||||
throw bindingContext().makeMappingException(
|
||||
String.format(
|
||||
"Could not resolve named property-ref [%s] against entity [%s]",
|
||||
"Could not resolve named referenced property [%s] against entity [%s]",
|
||||
attributeName,
|
||||
referencedEntityBinding.getEntity().getName()
|
||||
)
|
||||
|
@ -3312,19 +3233,13 @@ public class Binder {
|
|||
if ( !referencedAttributeBinding.getAttribute().isSingular() ) {
|
||||
throw bindingContext().makeMappingException(
|
||||
String.format(
|
||||
"Property-ref [%s] against entity [%s] is a plural attribute; it must be a singular attribute.",
|
||||
"Referenced property [%s] against entity [%s] is a plural attribute; it must be a singular attribute.",
|
||||
attributeName,
|
||||
referencedEntityBinding.getEntity().getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
List<Value> values = new ArrayList<Value>();
|
||||
SingularAttributeBinding referencedAttributeBindingAsSingular =
|
||||
(SingularAttributeBinding) referencedAttributeBinding;
|
||||
for ( RelationalValueBinding valueBinding : referencedAttributeBindingAsSingular.getRelationalValueBindings() ) {
|
||||
values.add( valueBinding.getValue() );
|
||||
}
|
||||
return values;
|
||||
return (SingularAttributeBinding) referencedAttributeBinding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,11 @@ import org.hibernate.annotations.OnDeleteAction;
|
|||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.internal.source.annotations.attribute.PrimaryKeyJoinColumn;
|
||||
import org.hibernate.metamodel.internal.source.annotations.entity.EntityClass;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.metamodel.spi.source.ColumnSource;
|
||||
import org.hibernate.metamodel.spi.source.EntitySource;
|
||||
import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource;
|
||||
import org.hibernate.metamodel.spi.source.JoinedSubclassEntitySource;
|
||||
|
||||
/**
|
||||
|
@ -102,6 +104,11 @@ public class JoinedSubclassEntitySourceImpl extends SubclassEntitySourceImpl imp
|
|||
return columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTable( null, null, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferencedAttributeName() {
|
||||
return null;
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssoc
|
|||
import org.hibernate.metamodel.internal.source.annotations.util.EnumConversionHelper;
|
||||
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
|
||||
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.metamodel.spi.source.FilterSource;
|
||||
import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource;
|
||||
|
@ -188,6 +189,11 @@ public class ManyToManyPluralAttributeElementSourceImpl implements ManyToManyPlu
|
|||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTable( logicalJoinTableName, null, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferencedAttributeName() {
|
||||
// HBM only
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.internal.util.StringHelper;
|
|||
import org.hibernate.metamodel.internal.source.annotations.attribute.Column;
|
||||
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
|
||||
import org.hibernate.metamodel.spi.relational.ForeignKey;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.metamodel.spi.source.PluralAttributeKeySource;
|
||||
import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
||||
|
@ -122,5 +123,10 @@ public class PluralAttributeKeySourceImpl implements PluralAttributeKeySource {
|
|||
public String getReferencedAttributeName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTableForAttribute( null );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,10 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.metamodel.internal.source.annotations.attribute.PrimaryKeyJoinColumn;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.metamodel.spi.source.ColumnSource;
|
||||
import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource;
|
||||
import org.hibernate.metamodel.spi.source.SecondaryTableSource;
|
||||
import org.hibernate.metamodel.spi.source.TableSpecificationSource;
|
||||
|
||||
|
@ -130,6 +132,11 @@ public class SecondaryTableSourceImpl implements SecondaryTableSource {
|
|||
return columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTable( null, null, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferencedAttributeName() {
|
||||
return null;
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
|
|||
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
|
||||
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.AttributeBinding;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource;
|
||||
import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
||||
|
@ -217,6 +218,15 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem
|
|||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTable(
|
||||
logicalJoinTableName,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferencedAttributeName() {
|
||||
// in annotations we are not referencing attribute but column names via @JoinColumn(s)
|
||||
|
|
|
@ -224,6 +224,11 @@ public abstract class AbstractToOneAttributeSourceImpl extends AbstractHbmSource
|
|||
public List<Value> getJoinColumns(JoinColumnResolutionContext context) {
|
||||
return context.resolveRelationalValuesForAttribute( propertyRef );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTableForAttribute( propertyRef );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.hibernate.jaxb.spi.hbm.JaxbColumnElement;
|
|||
import org.hibernate.jaxb.spi.hbm.JaxbJoinedSubclassElement;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbKeyElement;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbOnDeleteAttribute;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.metamodel.spi.source.ColumnSource;
|
||||
import org.hibernate.metamodel.spi.source.EntitySource;
|
||||
|
@ -103,6 +104,11 @@ public class JoinedSubclassEntitySourceImpl extends SubclassEntitySourceImpl imp
|
|||
return context.resolveRelationalValuesForAttribute( key.getPropertyRef() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTableForAttribute( key.getPropertyRef() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferencedAttributeName() {
|
||||
return key.getPropertyRef();
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.hibernate.jaxb.spi.hbm.JaxbClassElement;
|
|||
import org.hibernate.jaxb.spi.hbm.JaxbColumnElement;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbFilterElement;
|
||||
import org.hibernate.jaxb.spi.hbm.JaxbManyToManyElement;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.metamodel.spi.source.FilterSource;
|
||||
import org.hibernate.metamodel.spi.source.ManyToManyPluralAttributeElementSource;
|
||||
|
@ -223,6 +224,11 @@ public class ManyToManyPluralAttributeElementSourceImpl
|
|||
public List<Value> getJoinColumns(JoinColumnResolutionContext context) {
|
||||
return context.resolveRelationalValuesForAttribute( manyToManyElement.getPropertyRef() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTableForAttribute( manyToManyElement.getPropertyRef() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -102,6 +102,11 @@ public class PluralAttributeKeySourceImpl
|
|||
public String getReferencedAttributeName() {
|
||||
return keyElement.getPropertyRef();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTableForAttribute( keyElement.getPropertyRef() );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -168,5 +168,10 @@ class SecondaryTableSourceImpl extends AbstractHbmSourceNode implements Secondar
|
|||
public String getReferencedAttributeName() {
|
||||
return joinElement.getKey().getPropertyRef();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context) {
|
||||
return context.resolveTableForAttribute( joinElement.getKey().getPropertyRef() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,10 +36,46 @@ import java.util.List;
|
|||
* @author Brett Meyer
|
||||
*/
|
||||
public abstract class AbstractTableSpecification implements TableSpecification {
|
||||
|
||||
// A column an derived value can have the same text, so use the Value.ValueType to disambiguate.
|
||||
private class ValueKey {
|
||||
private final Value.ValueType valueType;
|
||||
private final Identifier identifier;
|
||||
|
||||
private ValueKey(Value.ValueType valueType, Identifier identifier) {
|
||||
this.valueType = valueType;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ValueKey valueKey = (ValueKey) o;
|
||||
|
||||
if ( identifier != null ? !identifier.equals( valueKey.identifier ) : valueKey.identifier != null ) {
|
||||
return false;
|
||||
}
|
||||
return valueType == valueKey.valueType;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = valueType != null ? valueType.hashCode() : 0;
|
||||
result = 31 * result + ( identifier != null ? identifier.hashCode() : 0 );
|
||||
return result;
|
||||
}
|
||||
}
|
||||
private int tableNumber;
|
||||
|
||||
private final List<Value> valueList = new ArrayList<Value>();
|
||||
private final LinkedHashMap<Identifier, Value> valueMap = new LinkedHashMap<Identifier, Value>();
|
||||
private final LinkedHashMap<ValueKey, Value> valueMap = new LinkedHashMap<ValueKey, Value>();
|
||||
|
||||
private final PrimaryKey primaryKey = new PrimaryKey( this );
|
||||
private final List<ForeignKey> foreignKeys = new ArrayList<ForeignKey>();
|
||||
|
@ -72,8 +108,9 @@ public abstract class AbstractTableSpecification implements TableSpecification {
|
|||
@Override
|
||||
public Column locateColumn(String name) {
|
||||
final Identifier identifier = Identifier.toIdentifier( name );
|
||||
if ( valueMap.containsKey( identifier ) ) {
|
||||
Value value = valueMap.get( identifier );
|
||||
final ValueKey valueKey = new ValueKey( Value.ValueType.COLUMN, identifier );
|
||||
if ( valueMap.containsKey( valueKey ) ) {
|
||||
Value value = valueMap.get( valueKey );
|
||||
return Column.class.isInstance( value ) ? Column.class.cast( value ) : null;
|
||||
}
|
||||
return null;
|
||||
|
@ -91,8 +128,8 @@ public abstract class AbstractTableSpecification implements TableSpecification {
|
|||
|
||||
@Override
|
||||
public Column createColumn(Identifier name) {
|
||||
final Column column = new Column( this, valueList.size(), name );
|
||||
valueMap.put( name, column );
|
||||
final Column column = new Column( valueList.size(), name );
|
||||
valueMap.put( new ValueKey( column.getValueType(), name ), column );
|
||||
valueList.add( column );
|
||||
return column;
|
||||
}
|
||||
|
@ -105,8 +142,9 @@ public abstract class AbstractTableSpecification implements TableSpecification {
|
|||
|
||||
protected DerivedValue locateDerivedValue(String fragment) {
|
||||
final Identifier identifier = Identifier.toIdentifier( fragment );
|
||||
if ( valueMap.containsKey( identifier ) ) {
|
||||
Value value = valueMap.get( identifier );
|
||||
final ValueKey valueKey = new ValueKey( Value.ValueType.DERIVED_VALUE, identifier );
|
||||
if ( valueMap.containsKey( valueKey ) ) {
|
||||
Value value = valueMap.get( valueKey );
|
||||
if ( DerivedValue.class.isInstance( value ) ) {
|
||||
return DerivedValue.class.cast( value );
|
||||
}
|
||||
|
@ -116,8 +154,8 @@ public abstract class AbstractTableSpecification implements TableSpecification {
|
|||
|
||||
protected DerivedValue createDerivedValue(String fragment) {
|
||||
final Identifier identifier = Identifier.toIdentifier( fragment );
|
||||
final DerivedValue value = new DerivedValue( this, valueList.size(), fragment );
|
||||
valueMap.put( identifier, value );
|
||||
final DerivedValue value = new DerivedValue( valueList.size(), fragment );
|
||||
valueMap.put( new ValueKey( value.getValueType(), identifier ), value );
|
||||
valueList.add( value );
|
||||
return value;
|
||||
}
|
||||
|
@ -180,9 +218,9 @@ public abstract class AbstractTableSpecification implements TableSpecification {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected void sameTableCheck(Column column) {
|
||||
if ( !this.equals( column.getTable() ) ) {
|
||||
private void sameTableCheck(Column column) {
|
||||
if ( ! hasValue( column ) ) {
|
||||
throw new IllegalArgumentException( "All columns must be from this table." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,20 +37,13 @@ public abstract class AbstractValue implements Value {
|
|||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, AbstractValue.class.getName());
|
||||
|
||||
private final TableSpecification table;
|
||||
private final int position;
|
||||
private JdbcDataType jdbcDataType;
|
||||
|
||||
protected AbstractValue(TableSpecification table, int position) {
|
||||
this.table = table;
|
||||
protected AbstractValue(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableSpecification getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
|
|
@ -54,12 +54,8 @@ public class Column extends AbstractValue {
|
|||
|
||||
private boolean isIdentity = false;
|
||||
|
||||
protected Column(TableSpecification table, int position, String name) {
|
||||
this( table, position, Identifier.toIdentifier( name ) );
|
||||
}
|
||||
|
||||
protected Column(TableSpecification table, int position, Identifier name) {
|
||||
super( table, position );
|
||||
protected Column(int position, Identifier name) {
|
||||
super( position );
|
||||
this.columnName = name;
|
||||
}
|
||||
|
||||
|
@ -174,9 +170,14 @@ public class Column extends AbstractValue {
|
|||
this.isIdentity = isIdentity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueType getValueType() {
|
||||
return ValueType.COLUMN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toLoggableString() {
|
||||
return getTable().getLoggableValueQualifier() + '.' + getColumnName();
|
||||
return getColumnName().getText();
|
||||
}
|
||||
|
||||
// TODO: this is fairly complicated logic. It would be more straightforward
|
||||
|
@ -232,20 +233,21 @@ public class Column extends AbstractValue {
|
|||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( ! ( o instanceof Column ) ) {
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Column that = (Column) o;
|
||||
Column column = (Column) o;
|
||||
|
||||
return EqualsHelper.equals( this.columnName, that.columnName )
|
||||
&& EqualsHelper.equals( this.getTable(), that.getTable() );
|
||||
if ( columnName != null ? !columnName.equals( column.columnName ) : column.columnName != null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = columnName != null ? columnName.hashCode() : 0;
|
||||
result = 31 * result + ( getTable() != null ? getTable().hashCode() : 0 );
|
||||
return result;
|
||||
return columnName != null ? columnName.hashCode() : 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,13 +125,4 @@ public class DenormalizedTable extends Table {
|
|||
public PrimaryKey getPrimaryKey() {
|
||||
return includedTable.getPrimaryKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sameTableCheck(Column column) {
|
||||
try{
|
||||
super.sameTableCheck( column );
|
||||
} catch ( IllegalArgumentException e ){
|
||||
includedTable.sameTableCheck( column );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,16 +33,21 @@ import org.hibernate.dialect.Dialect;
|
|||
public class DerivedValue extends AbstractValue {
|
||||
private final String expression;
|
||||
|
||||
public DerivedValue(TableSpecification table, int position, String expression) {
|
||||
super( table, position );
|
||||
public DerivedValue(int position, String expression) {
|
||||
super( position );
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueType getValueType() {
|
||||
return ValueType.DERIVED_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String toLoggableString() {
|
||||
return getTable().toLoggableString() + ".{derived-column}";
|
||||
return "{derived-column}";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,12 +32,18 @@ import org.hibernate.dialect.Dialect;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Value {
|
||||
|
||||
public enum ValueType {
|
||||
COLUMN,
|
||||
DERIVED_VALUE
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the table that owns this value.
|
||||
* Return the value type.
|
||||
*
|
||||
* @return The owning table.
|
||||
* @return The value type
|
||||
*/
|
||||
public TableSpecification getTable();
|
||||
public ValueType getValueType();
|
||||
|
||||
/**
|
||||
* Retrieve the JDBC data type of this value.
|
||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate.metamodel.spi.source;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Column;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
|
||||
/**
|
||||
|
@ -67,6 +68,8 @@ public interface ForeignKeyContributingSource {
|
|||
*/
|
||||
public List<Value> getJoinColumns(JoinColumnResolutionContext context);
|
||||
|
||||
public TableSpecification getReferencedTable(JoinColumnResolutionContext context);
|
||||
|
||||
/**
|
||||
* Retrieves the explicitly named attribute that maps to the non-PK foreign-key target columns.
|
||||
*
|
||||
|
@ -89,6 +92,8 @@ public interface ForeignKeyContributingSource {
|
|||
*/
|
||||
public List<Value> resolveRelationalValuesForAttribute(String attributeName);
|
||||
|
||||
public TableSpecification resolveTableForAttribute(String attributeName);
|
||||
|
||||
/**
|
||||
* Resolve a column reference given the logical names of both the table and the column. Used in the
|
||||
* {@link javax.persistence.JoinColumn} case
|
||||
|
@ -101,5 +106,17 @@ public interface ForeignKeyContributingSource {
|
|||
* @return The column.
|
||||
*/
|
||||
public Column resolveColumn(String logicalColumnName, String logicalTableName, String logicalSchemaName, String logicalCatalogName);
|
||||
|
||||
/**
|
||||
* Resolve a table reference given the logical names of the table and the column. Used in the
|
||||
* {@link javax.persistence.JoinColumn} case
|
||||
*
|
||||
* @param logicalTableName The logical table name.
|
||||
* @param logicalSchemaName The logical schema name.
|
||||
* @param logicalCatalogName The logical catalog name.
|
||||
*
|
||||
* @return The column.
|
||||
*/
|
||||
public TableSpecification resolveTable(String logicalTableName, String logicalSchemaName, String logicalCatalogName);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue