HHH-10208 - Index and unique-key constraints not properly handled with implicit columns in hbm.xml binding

This commit is contained in:
Steve Ebersole 2015-11-04 23:31:47 -06:00
parent 9128b84b54
commit ec8794bbd0
29 changed files with 177 additions and 834 deletions

View File

@ -19,7 +19,6 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.MapsId;
@ -45,11 +44,9 @@ import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.ExportableProducer;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.source.internal.ConstraintSecondPass;
import org.hibernate.boot.model.source.internal.ImplicitColumnNamingSecondPass;
import org.hibernate.boot.model.source.spi.LocalMetadataBuildingContext;
import org.hibernate.boot.spi.AttributeConverterAutoApplyHandler;
import org.hibernate.boot.spi.AttributeConverterDescriptor;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.MetadataBuildingOptions;
@ -1452,7 +1449,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
private ArrayList<CreateKeySecondPass> createKeySecondPasList;
private ArrayList<SecondaryTableSecondPass> secondaryTableSecondPassList;
private ArrayList<QuerySecondPass> querySecondPassList;
private ArrayList<ConstraintSecondPass> constraintSecondPassList;
private ArrayList<ImplicitColumnNamingSecondPass> implicitColumnNamingSecondPassList;
private ArrayList<SecondPass> generalSecondPassList;
@ -1485,9 +1481,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
else if ( secondPass instanceof QuerySecondPass ) {
addQuerySecondPass( (QuerySecondPass) secondPass, onTopOfTheQueue );
}
else if ( secondPass instanceof ConstraintSecondPass ) {
addConstraintSecondPass( ( ConstraintSecondPass) secondPass, onTopOfTheQueue );
}
else if ( secondPass instanceof ImplicitColumnNamingSecondPass ) {
addImplicitColumnNamingSecondPass( (ImplicitColumnNamingSecondPass) secondPass );
}
@ -1562,13 +1555,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
addSecondPass( secondPass, querySecondPassList, onTopOfTheQueue );
}
private void addConstraintSecondPass(ConstraintSecondPass secondPass, boolean onTopOfTheQueue) {
if ( constraintSecondPassList == null ) {
constraintSecondPassList = new ArrayList<ConstraintSecondPass>();
}
addSecondPass( secondPass, constraintSecondPassList, onTopOfTheQueue );
}
private void addImplicitColumnNamingSecondPass(ImplicitColumnNamingSecondPass secondPass) {
if ( implicitColumnNamingSecondPassList == null ) {
implicitColumnNamingSecondPassList = new ArrayList<ImplicitColumnNamingSecondPass>();
@ -1605,7 +1591,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
secondPassCompileForeignKeys( buildingContext );
processSecondPasses( constraintSecondPassList );
processUniqueConstraintHolders( buildingContext );
processJPAIndexHolders( buildingContext );

View File

@ -1,73 +0,0 @@
/*
* 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.boot.model.source.internal;
import java.util.Map;
import org.hibernate.MappingException;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.source.internal.hbm.MappingDocument;
import org.hibernate.boot.model.source.spi.ConstraintSource;
import org.hibernate.boot.model.source.spi.IndexConstraintSource;
import org.hibernate.boot.model.source.spi.UniqueKeyConstraintSource;
import org.hibernate.cfg.SecondPass;
import org.hibernate.mapping.Index;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey;
/**
* @author Steve Ebersole
*/
public class ConstraintSecondPass implements SecondPass {
private final MappingDocument sourceDocument;
private final Table table;
private final ConstraintSource constraintSource;
public ConstraintSecondPass(
MappingDocument sourceDocument,
Table table,
ConstraintSource constraintSource) {
this.sourceDocument = sourceDocument;
this.table = table;
this.constraintSource = constraintSource;
}
@Override
public void doSecondPass(Map persistentClasses) throws MappingException {
if ( IndexConstraintSource.class.isInstance( constraintSource ) ) {
bindIndexConstraint();
}
else if ( UniqueKeyConstraintSource.class.isInstance( constraintSource ) ) {
bindUniqueKeyConstraint();
}
}
private void bindIndexConstraint() {
// todo : implicit naming via strategy
final Index index = table.getOrCreateIndex( constraintSource.name() );
for ( String columnName : constraintSource.columnNames() ) {
final Identifier physicalName = sourceDocument.getMetadataCollector().getDatabase().toIdentifier(
sourceDocument.getMetadataCollector().getPhysicalColumnName( table, columnName )
);
index.addColumn( table.getColumn( physicalName ) );
}
}
private void bindUniqueKeyConstraint() {
// todo : implicit naming via strategy
final UniqueKey index = table.getOrCreateUniqueKey( constraintSource.name() );
for ( String columnName : constraintSource.columnNames() ) {
final Identifier physicalName = sourceDocument.getMetadataCollector().getDatabase().toIdentifier(
sourceDocument.getMetadataCollector().getPhysicalColumnName( table, columnName )
);
index.addColumn( table.getColumn( physicalName ) );
}
}
}

View File

@ -1,74 +0,0 @@
/*
* 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.boot.model.source.internal.hbm;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.boot.model.source.spi.ConstraintSource;
import org.hibernate.internal.util.compare.EqualsHelper;
/**
* Support for index and unique-key constraint sources.
*
* @author Hardy Ferentschik
* @author Steve Ebersole
*/
class AbstractConstraintSource implements ConstraintSource {
protected final String name;
protected final String tableName;
protected final ArrayList<String> columnNames = new ArrayList<String>();
protected AbstractConstraintSource(String name, String tableName) {
assert name != null : "Constraint name was null";
this.name = name;
this.tableName = tableName;
}
@Override
public String name() {
return name;
}
@Override
public String getTableName() {
return tableName;
}
@Override
public List<String> columnNames() {
return columnNames;
}
public void addColumnName( String columnName ) {
columnNames.add( columnName );
}
@Override
@SuppressWarnings("RedundantIfStatement")
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
AbstractConstraintSource that = (AbstractConstraintSource) o;
return EqualsHelper.equals( name, that.name )
&& EqualsHelper.equals( tableName, that.tableName )
&& columnNames.equals( that.columnNames );
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + ( tableName == null ? 0 : tableName.hashCode() );
result = 31 * result + ( columnNames.hashCode() );
return result;
}
}

View File

@ -33,7 +33,6 @@ import org.hibernate.boot.model.source.spi.AttributePath;
import org.hibernate.boot.model.source.spi.AttributeRole;
import org.hibernate.boot.model.source.spi.AttributeSource;
import org.hibernate.boot.model.source.spi.AttributeSourceContainer;
import org.hibernate.boot.model.source.spi.ConstraintSource;
import org.hibernate.boot.model.source.spi.EntityHierarchySource;
import org.hibernate.boot.model.source.spi.EntityNamingSource;
import org.hibernate.boot.model.source.spi.EntitySource;
@ -79,9 +78,6 @@ public abstract class AbstractEntitySourceImpl
private final ToolingHintContext toolingHintContext;
private Map<String, ConstraintSource> constraintMap = new HashMap<String, ConstraintSource>();
protected AbstractEntitySourceImpl(MappingDocument sourceMappingDocument, JaxbHbmEntityBaseDefinition jaxbEntityMapping) {
super( sourceMappingDocument );
this.jaxbEntityMapping = jaxbEntityMapping;
@ -223,86 +219,12 @@ public abstract class AbstractEntitySourceImpl
public void addAttributeSource(AttributeSource attributeSource) {
attributeSources.add( attributeSource );
}
@Override
public void registerIndexColumn(String constraintName, String logicalTableName, String columnName) {
registerIndexConstraintColumn( constraintName, logicalTableName, columnName );
}
@Override
public void registerUniqueKeyColumn(String constraintName, String logicalTableName, String columnName) {
registerUniqueKeyConstraintColumn( constraintName, logicalTableName, columnName );
}
};
buildAttributeSources( attributeBuildingCallback );
return attributeSources;
}
private void registerIndexConstraintColumn(String constraintName, String logicalTableName, String columnName) {
getOrCreateIndexConstraintSource( constraintName, logicalTableName ).addColumnName( columnName );
}
private IndexConstraintSourceImpl getOrCreateIndexConstraintSource(String constraintName, String logicalTableName) {
IndexConstraintSourceImpl constraintSource = (IndexConstraintSourceImpl) constraintMap.get( constraintName );
if ( constraintSource == null ) {
constraintSource = new IndexConstraintSourceImpl( constraintName, logicalTableName );
constraintMap.put( constraintName, constraintSource );
}
else {
// make sure we have the same table name...
if ( !EqualsHelper.equals( constraintSource.getTableName(), logicalTableName ) ) {
throw new MappingException(
String.format(
Locale.ENGLISH,
"Named relational index [%s] referenced more than one table [%s, %s]",
constraintName,
constraintSource.getTableName() == null
? "null(implicit)"
: constraintSource.getTableName(),
logicalTableName == null
? "null(implicit)"
: logicalTableName
),
origin()
);
}
}
return constraintSource;
}
private void registerUniqueKeyConstraintColumn(String constraintName, String logicalTableName, String columnName) {
getOrCreateUniqueKeyConstraintSource( constraintName, logicalTableName ).addColumnName( columnName );
}
private UniqueKeyConstraintSourceImpl getOrCreateUniqueKeyConstraintSource(String constraintName, String logicalTableName) {
UniqueKeyConstraintSourceImpl constraintSource = (UniqueKeyConstraintSourceImpl) constraintMap.get( constraintName );
if ( constraintSource == null ) {
constraintSource = new UniqueKeyConstraintSourceImpl( constraintName, logicalTableName );
constraintMap.put( constraintName, constraintSource );
}
else {
// make sure we have the same table name...
if ( !EqualsHelper.equals( constraintSource.getTableName(), logicalTableName ) ) {
throw new MappingException(
String.format(
Locale.ENGLISH,
"Named relational unique-key [%s] referenced more than one table [%s, %s]",
constraintName,
constraintSource.getTableName() == null
? "null(implicit)"
: constraintSource.getTableName(),
logicalTableName == null
? "null(implicit)"
: logicalTableName
),
origin()
);
}
}
return constraintSource;
}
protected void buildAttributeSources(AttributesHelper.Callback attributeBuildingCallback) {
AttributesHelper.processAttributes(
sourceMappingDocument(),
@ -344,22 +266,6 @@ public abstract class AbstractEntitySourceImpl
public void addAttributeSource(AttributeSource attributeSource) {
attributeSources.add( attributeSource );
}
@Override
public void registerIndexColumn(
String constraintName,
String logicalTableName,
String columnName) {
registerIndexConstraintColumn( constraintName, logicalTableName, columnName );
}
@Override
public void registerUniqueKeyColumn(
String constraintName,
String logicalTableName,
String columnName) {
registerUniqueKeyConstraintColumn( constraintName, logicalTableName, columnName );
}
},
joinElement.getAttributes(),
logicalTableName,
@ -501,11 +407,6 @@ public abstract class AbstractEntitySourceImpl
subclassEntitySources.add( subclassEntitySource );
}
@Override
public Collection<ConstraintSource> getConstraints() {
return constraintMap.values();
}
@Override
public Map<String,SecondaryTableSource> getSecondaryTableMap() {
return secondaryTableMap;

View File

@ -72,20 +72,6 @@ public abstract class AbstractSingularAttributeSourceEmbeddedImpl
public ToolingHintContext getToolingHintContextBaselineForEmbeddable() {
return toolingHintContext;
}
@Override
public void registerIndexConstraintColumn(
String constraintName,
String logicalTableName,
String columnName) {
}
@Override
public void registerUniqueKeyConstraintColumn(
String constraintName, String logicalTableName, String columnName) {
}
},
embeddedAttributeMapping.getEmbeddableMapping(),
nestedAttributeMappings,

View File

@ -7,10 +7,7 @@
package org.hibernate.boot.model.source.internal.hbm;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import javax.xml.bind.JAXBElement;
import org.hibernate.boot.MappingException;
@ -18,7 +15,6 @@ import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmAnyAssociationType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmArrayType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmBagCollectionType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmBasicAttributeType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmColumnType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmCompositeAttributeType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmCompositeKeyBasicAttributeType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmCompositeKeyManyToOneType;
@ -43,20 +39,14 @@ import org.hibernate.boot.model.source.spi.EmbeddedAttributeMapping;
import org.hibernate.boot.model.source.spi.NaturalIdMutability;
import org.hibernate.boot.model.source.spi.SingularAttributeSourceEmbedded;
import org.hibernate.boot.model.source.spi.ToolingHintContext;
import org.hibernate.internal.util.StringHelper;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
/**
* @author Steve Ebersole
*/
public class AttributesHelper {
public static interface Callback {
public interface Callback {
AttributeSourceContainer getAttributeSourceContainer();
void addAttributeSource(AttributeSource attributeSource);
void registerIndexColumn(String constraintName, String logicalTableName, String columnName);
void registerUniqueKeyColumn(String constraintName, String logicalTableName, String columnName);
}
public static void processAttributes(
@ -303,22 +293,6 @@ public class AttributesHelper {
public ToolingHintContext getToolingHintContextBaselineForEmbeddable() {
return callback.getAttributeSourceContainer().getToolingHintContext();
}
@Override
public void registerIndexConstraintColumn(
String constraintName,
String logicalTableName,
String columnName) {
callback.registerIndexColumn( constraintName, logicalTableName, columnName );
}
@Override
public void registerUniqueKeyConstraintColumn(
String constraintName,
String logicalTableName,
String columnName) {
callback.registerUniqueKeyColumn( constraintName, logicalTableName, columnName );
}
},
propertiesGroupJaxbMapping.getAttributes(),
logicalTableName,
@ -447,89 +421,6 @@ public class AttributesHelper {
naturalIdMutability
)
);
processConstraints(
mappingDocument,
callback,
logicalTableName,
basicAttributeJaxbMapping.getColumnAttribute(),
basicAttributeJaxbMapping.getColumnOrFormula(),
basicAttributeJaxbMapping.getIndex(),
basicAttributeJaxbMapping.getUniqueKey()
);
}
private static void processConstraints(
MappingDocument mappingDocument,
Callback callback,
String logicalTableName,
String columnAttribute,
List columns,
String groupedIndexNames,
String groupedUniqueKeyNames) {
final Set<String> groupedIndexNameSet = splitNames( groupedIndexNames );
final boolean hasGroupedIndexes = !groupedIndexNameSet.isEmpty();
final Set<String> groupedUniqueKeyNameSet = splitNames( groupedUniqueKeyNames );
final boolean hasGroupedUniqueKeys = !groupedUniqueKeyNameSet.isEmpty();
if ( hasGroupedIndexes ) {
if ( isNotEmpty( columnAttribute ) ) {
for ( String name : groupedIndexNameSet ) {
callback.registerIndexColumn( name, logicalTableName, columnAttribute );
}
}
}
if ( hasGroupedIndexes && isNotEmpty( columnAttribute ) ) {
for ( String name : groupedIndexNameSet ) {
callback.registerIndexColumn( name, logicalTableName, columnAttribute );
}
}
if ( hasGroupedUniqueKeys && isNotEmpty( columnAttribute ) ) {
for ( String name : groupedUniqueKeyNameSet ) {
callback.registerUniqueKeyColumn( name, logicalTableName, columnAttribute );
}
}
for ( Object oColumn : columns ) {
if ( !JaxbHbmColumnType.class.isInstance( oColumn ) ) {
continue;
}
final JaxbHbmColumnType column = (JaxbHbmColumnType) oColumn;
if ( isNotEmpty( column.getIndex() ) ) {
callback.registerIndexColumn( column.getIndex(), logicalTableName, column.getName() );
}
if ( hasGroupedIndexes ) {
for ( String name : groupedIndexNameSet ) {
callback.registerIndexColumn( name, logicalTableName, column.getName() );
}
}
if ( isNotEmpty( column.getUniqueKey() ) ) {
callback.registerUniqueKeyColumn( column.getUniqueKey(), logicalTableName, column.getName() );
}
if ( hasGroupedUniqueKeys ) {
for ( String name : groupedUniqueKeyNameSet ) {
callback.registerUniqueKeyColumn( name, logicalTableName, column.getName() );
}
}
}
}
private static Set<String> splitNames(String groupedNames) {
if ( StringHelper.isEmpty( groupedNames ) ) {
return Collections.emptySet();
}
final HashSet<String> splitNames = new HashSet<String>();
final StringTokenizer tokens = new StringTokenizer( groupedNames, ", " );
while ( tokens.hasMoreTokens() ) {
splitNames.add( tokens.nextToken() );
}
return splitNames;
}
public static void processEmbeddedAttribute(
@ -598,16 +489,6 @@ public class AttributesHelper {
naturalIdMutability
)
);
processConstraints(
mappingDocument,
callback,
logicalTableName,
manyToOneAttributeJaxbMapping.getColumnAttribute(),
manyToOneAttributeJaxbMapping.getColumnOrFormula(),
manyToOneAttributeJaxbMapping.getIndex(),
manyToOneAttributeJaxbMapping.getUniqueKey()
);
}
public static void processOneToOneAttribute(
@ -642,17 +523,6 @@ public class AttributesHelper {
naturalIdMutability
)
);
processConstraints(
mappingDocument,
callback,
logicalTableName,
null,
// todo : should we skip the discriminator column?
anyAttributeJaxbMapping.getColumn(),
anyAttributeJaxbMapping.getIndex(),
null
);
}
public static void processMapAttribute(

View File

@ -7,6 +7,7 @@
package org.hibernate.boot.model.source.internal.hbm;
import java.util.List;
import java.util.Set;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmBasicAttributeType;
import org.hibernate.boot.model.source.spi.SizeSource;
@ -67,8 +68,8 @@ public class BasicAttributeColumnsAndFormulasSource
}
@Override
public String getIndex() {
return basicAttributeMapping.getIndex();
public Set<String> getIndexConstraintNames() {
return CommaSeparatedStringHelper.split( basicAttributeMapping.getIndex() );
}
@Override
@ -77,7 +78,7 @@ public class BasicAttributeColumnsAndFormulasSource
}
@Override
public String getUniqueKey() {
return basicAttributeMapping.getUniqueKey();
public Set<String> getUniqueKeyConstraintNames() {
return CommaSeparatedStringHelper.split( basicAttributeMapping.getUniqueKey() );
}
}

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.boot.model.source.internal.hbm;
import java.util.Set;
import org.hibernate.boot.model.TruthValue;
import org.hibernate.boot.model.source.spi.ColumnSource;
import org.hibernate.boot.model.source.spi.JdbcDataType;
@ -26,6 +28,8 @@ class ColumnAttributeSourceImpl
private final SizeSource sizeSource;
private final TruthValue nullable;
private final TruthValue unique;
private final Set<String> indexConstraintNames;
private final Set<String> ukConstraintNames;
ColumnAttributeSourceImpl(
MappingDocument mappingDocument,
@ -33,13 +37,17 @@ class ColumnAttributeSourceImpl
String columnName,
SizeSource sizeSource,
TruthValue nullable,
TruthValue unique) {
TruthValue unique,
Set<String> indexConstraintNames,
Set<String> ukConstraintNames) {
super( mappingDocument );
this.tableName = tableName;
this.columnName = columnName;
this.sizeSource = sizeSource;
this.nullable = nullable;
this.unique = unique;
this.indexConstraintNames = indexConstraintNames;
this.ukConstraintNames = ukConstraintNames;
}
@Override
@ -106,4 +114,14 @@ class ColumnAttributeSourceImpl
public String getComment() {
return null;
}
@Override
public Set<String> getIndexConstraintNames() {
return indexConstraintNames;
}
@Override
public Set<String> getUniqueKeyConstraintNames() {
return ukConstraintNames;
}
}

View File

@ -7,6 +7,8 @@
package org.hibernate.boot.model.source.internal.hbm;
import java.util.Set;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmColumnType;
import org.hibernate.boot.model.TruthValue;
import org.hibernate.boot.model.source.spi.ColumnSource;
@ -22,16 +24,22 @@ class ColumnSourceImpl
private final String tableName;
private final JaxbHbmColumnType columnElement;
private final TruthValue nullable;
private final Set<String> indexConstraintNames;
private final Set<String> ukConstraintNames;
ColumnSourceImpl(
MappingDocument mappingDocument,
String tableName,
JaxbHbmColumnType columnElement) {
JaxbHbmColumnType columnElement,
Set<String> indexConstraintNames,
Set<String> ukConstraintNames) {
this(
mappingDocument,
tableName,
columnElement,
interpretNotNullToNullability( columnElement.isNotNull() )
interpretNotNullToNullability( columnElement.isNotNull() ),
indexConstraintNames,
ukConstraintNames
);
}
@ -49,11 +57,22 @@ class ColumnSourceImpl
MappingDocument mappingDocument,
String tableName,
JaxbHbmColumnType columnElement,
TruthValue nullable) {
TruthValue nullable,
Set<String> indexConstraintNames,
Set<String> ukConstraintNames) {
super( mappingDocument );
this.tableName = tableName;
this.columnElement = columnElement;
this.nullable = nullable;
this.indexConstraintNames = CommaSeparatedStringHelper.splitAndCombine(
indexConstraintNames,
columnElement.getIndex()
);
this.ukConstraintNames = CommaSeparatedStringHelper.splitAndCombine(
ukConstraintNames,
columnElement.getUniqueKey()
);
}
@Override
@ -125,4 +144,14 @@ class ColumnSourceImpl
public String getContainingTableName() {
return tableName;
}
@Override
public Set<String> getIndexConstraintNames() {
return indexConstraintNames;
}
@Override
public Set<String> getUniqueKeyConstraintNames() {
return ukConstraintNames;
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.boot.model.source.internal.hbm;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* @author Steve Ebersole
*/
public class CommaSeparatedStringHelper {
private CommaSeparatedStringHelper() {
}
public static Set<String> split(String values) {
if ( values == null || values.isEmpty() ) {
return Collections.emptySet();
}
HashSet<String> set = new HashSet<String>();
Collections.addAll( set, values.split( "\\s*,\\s*" ) );
return set;
}
public static Set<String> splitAndCombine(Set<String> x, String values) {
if ( x.isEmpty() && (values == null || values.isEmpty()) ) {
return Collections.emptySet();
}
HashSet<String> set = new HashSet<String>();
set.addAll( x );
if ( values != null && !values.isEmpty() ) {
Collections.addAll( set, values.split( "\\s*,\\s*" ) );
}
return set;
}
}

View File

@ -17,10 +17,7 @@ import org.hibernate.boot.model.source.spi.ToolingHintContext;
* @author Steve Ebersole
*/
public interface EmbeddableSourceContainer {
public AttributeRole getAttributeRoleBase();
public AttributePath getAttributePathBase();
public ToolingHintContext getToolingHintContextBaselineForEmbeddable();
public void registerIndexConstraintColumn(String constraintName, String logicalTableName, String columnName);
public void registerUniqueKeyConstraintColumn(String constraintName, String logicalTableName, String columnName);
AttributeRole getAttributeRoleBase();
AttributePath getAttributePathBase();
ToolingHintContext getToolingHintContextBaselineForEmbeddable();
}

View File

@ -111,19 +111,6 @@ public class EmbeddableSourceImpl extends AbstractHbmSourceNode implements Embed
public void addAttributeSource(AttributeSource attributeSource) {
attributeSources.add( attributeSource );
}
@Override
public void registerIndexColumn(String constraintName, String logicalTableName, String columnName) {
}
@Override
public void registerUniqueKeyColumn(
String constraintName,
String logicalTableName,
String columnName) {
}
},
attributeMappings,
logicalTableName,

View File

@ -70,22 +70,6 @@ public class EmbeddableSourceVirtualImpl extends AbstractHbmSourceNode implement
public void addAttributeSource(AttributeSource attributeSource) {
attributeSources.add( attributeSource );
}
@Override
public void registerIndexColumn(
String constraintName,
String logicalTableName,
String columnName) {
containingCallback.registerIndexColumn( constraintName, logicalTableName, columnName );
}
@Override
public void registerUniqueKeyColumn(
String constraintName,
String logicalTableName,
String columnName) {
containingCallback.registerUniqueKeyColumn( constraintName, logicalTableName, columnName );
}
},
attributeJaxbMappings,
logicalTableName,

View File

@ -231,24 +231,6 @@ class IdentifierSourceAggregatedCompositeImpl implements IdentifierSourceAggrega
return toolingHintContext;
}
@Override
public void registerIndexConstraintColumn(
String constraintName,
String logicalTableName,
String columnName) {
// todo : determine the best option here...
// probably (here) delegate back to root entity, but need a general strategy
}
@Override
public void registerUniqueKeyConstraintColumn(
String constraintName,
String logicalTableName,
String columnName) {
// todo : determine the best option here...
// probably (here) delegate back to root entity, but need a general strategy
}
public List getAttributes() {
return jaxbCompositeIdMapping.getKeyPropertyOrKeyManyToOne();
}

View File

@ -72,24 +72,6 @@ class IdentifierSourceNonAggregatedCompositeImpl implements IdentifierSourceNonA
public void addAttributeSource(AttributeSource attributeSource) {
attributeSources.add( attributeSource );
}
@Override
public void registerIndexColumn(
String constraintName,
String logicalTableName,
String columnName) {
// todo : determine the best option here...
// probably (here) delegate back to root entity, but need a general strategy
}
@Override
public void registerUniqueKeyColumn(
String constraintName,
String logicalTableName,
String columnName) {
// todo : determine the best option here...
// probably (here) delegate back to root entity, but need a general strategy
}
},
rootEntitySource.jaxbEntityMapping().getCompositeId().getKeyPropertyOrKeyManyToOne()
);

View File

@ -1,38 +0,0 @@
/*
* 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.boot.model.source.internal.hbm;
import java.util.Locale;
import org.hibernate.boot.model.source.spi.IndexConstraintSource;
/**
* @author Brett Meyer
*/
class IndexConstraintSourceImpl extends AbstractConstraintSource implements IndexConstraintSource {
public IndexConstraintSourceImpl(String name, String tableName) {
super( name, tableName );
}
@Override
public String toString() {
return String.format(
Locale.ENGLISH,
"IndexConstraintSource{name='%s', tableName='%s', columnNames='%s', orderings=<not-implemented>}",
name,
tableName,
columnNames
);
}
@Override
public boolean isUnique() {
// TODO: Is it possible to have a unique index in HBM?
return false;
}
}

View File

@ -7,6 +7,7 @@
package org.hibernate.boot.model.source.internal.hbm;
import java.util.List;
import java.util.Set;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmManyToOneType;
@ -55,8 +56,8 @@ public class ManyToOneAttributeColumnsAndFormulasSource extends RelationalValueS
}
@Override
public String getIndex() {
return manyToOneMapping.getIndex();
public Set<String> getIndexConstraintNames() {
return CommaSeparatedStringHelper.split( manyToOneMapping.getIndex() );
}
@Override
@ -65,7 +66,7 @@ public class ManyToOneAttributeColumnsAndFormulasSource extends RelationalValueS
}
@Override
public String getUniqueKey() {
return manyToOneMapping.getUniqueKey();
public Set<String> getUniqueKeyConstraintNames() {
return CommaSeparatedStringHelper.split( manyToOneMapping.getUniqueKey() );
}
}

View File

@ -39,7 +39,6 @@ import org.hibernate.boot.model.naming.ImplicitUniqueKeyNameSource;
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.source.internal.ConstraintSecondPass;
import org.hibernate.boot.model.source.internal.ImplicitColumnNamingSecondPass;
import org.hibernate.boot.model.source.spi.AnyMappingSource;
import org.hibernate.boot.model.source.spi.AttributePath;
@ -49,7 +48,6 @@ import org.hibernate.boot.model.source.spi.CascadeStyleSource;
import org.hibernate.boot.model.source.spi.CollectionIdSource;
import org.hibernate.boot.model.source.spi.ColumnSource;
import org.hibernate.boot.model.source.spi.CompositeIdentifierSource;
import org.hibernate.boot.model.source.spi.ConstraintSource;
import org.hibernate.boot.model.source.spi.EmbeddableSource;
import org.hibernate.boot.model.source.spi.EntitySource;
import org.hibernate.boot.model.source.spi.FilterSource;
@ -1291,8 +1289,6 @@ public class ModelBinder {
}
}
}
registerConstraintSecondPasses( mappingDocument, entitySource, entityTableXref );
}
private void handleNaturalIdBinding(
@ -1325,28 +1321,6 @@ public class ModelBinder {
ukBinder.addAttributeBinding( attributeBinding );
}
private void registerConstraintSecondPasses(
MappingDocument mappingDocument,
EntitySource entitySource,
final EntityTableXref entityTableXref) {
if ( entitySource.getConstraints() == null ) {
return;
}
for ( ConstraintSource constraintSource : entitySource.getConstraints() ) {
final String logicalTableName = constraintSource.getTableName();
final Table table = entityTableXref.resolveTable( database.toIdentifier( logicalTableName ) );
mappingDocument.getMetadataCollector().addSecondPass(
new ConstraintSecondPass(
mappingDocument,
table,
constraintSource
)
);
}
}
private Property createPluralAttribute(
MappingDocument sourceDocument,
PluralAttributeSource attributeSource,

View File

@ -58,22 +58,6 @@ public class PluralAttributeElementSourceEmbeddedImpl
public ToolingHintContext getToolingHintContextBaselineForEmbeddable() {
return toolingHintContext;
}
@Override
public void registerIndexConstraintColumn(
String constraintName,
String logicalTableName,
String columnName) {
// todo : how should this be handled?
}
@Override
public void registerUniqueKeyConstraintColumn(
String constraintName,
String logicalTableName,
String columnName) {
// todo : how should this be handled?
}
},
new EmbeddableMapping() {
@Override

View File

@ -108,22 +108,6 @@ public class PluralAttributeMapKeySourceEmbeddedImpl
public ToolingHintContext getToolingHintContextBaselineForEmbeddable() {
return pluralAttributeSource.getToolingHintContext();
}
@Override
public void registerIndexConstraintColumn(
String constraintName,
String logicalTableName,
String columnName) {
// todo : how should this be handled?
}
@Override
public void registerUniqueKeyConstraintColumn(
String constraintName,
String logicalTableName,
String columnName) {
// todo : how should this be handled?
}
},
jaxbEmbeddable,
attributeMappings,

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.boot.model.source.internal.hbm;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -15,22 +14,16 @@ import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.source.spi.ColumnSource;
import org.hibernate.boot.model.source.spi.ConstraintSource;
import org.hibernate.boot.model.source.spi.DerivedValueSource;
import org.hibernate.boot.model.source.spi.IndexConstraintSource;
import org.hibernate.boot.model.source.spi.LocalMetadataBuildingContext;
import org.hibernate.boot.model.source.spi.RelationalValueSource;
import org.hibernate.boot.model.source.spi.UniqueKeyConstraintSource;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Formula;
import org.hibernate.mapping.Index;
import org.hibernate.mapping.OneToOne;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey;
/**
* Centralized binding of columns and formulas.
@ -41,10 +34,8 @@ public class RelationalObjectBinder {
private final Database database;
private final PhysicalNamingStrategy physicalNamingStrategy;
public static interface ColumnNamingDelegate {
// todo : use ImplicitNamingStrategy / PhysicalNamingStrategy
// todo : leverage Identifier class
public Identifier determineImplicitName(LocalMetadataBuildingContext context);
public interface ColumnNamingDelegate {
Identifier determineImplicitName(LocalMetadataBuildingContext context);
}
public RelationalObjectBinder(MetadataBuildingContext buildingContext) {
@ -185,6 +176,16 @@ public class RelationalObjectBinder {
column.setCustomWrite( columnSource.getWriteFragment() );
simpleValue.addColumn( column );
if ( table != null ) {
for ( String name : columnSource.getIndexConstraintNames() ) {
table.getOrCreateIndex( name ).addColumn( column );
}
for ( String name : columnSource.getUniqueKeyConstraintNames() ) {
table.getOrCreateUniqueKey( name ).addColumn( column );
}
}
}
private static boolean interpretNullability(TruthValue nullable, boolean areColumnsNullableByDefault) {
@ -204,95 +205,4 @@ public class RelationalObjectBinder {
oneToOneBinding.addFormula( new Formula( formulaSource.getExpression() ) );
}
}
public static interface RelationalObjectResolutionContext {
/**
* Resolve a Table, given its logical name.
* <p/>
* NOTE : not sure yet how to best implement this. One option is to simply
* construct the proper key needed to resolve the reference from the
* "metadataCollector". Another option is to have this context provide a
* "scoped table resolution", local to the point where the table reference
* occurred; for example, an entity might act as such a scope and resolution of
* table references would occur locally scoped to just tables defined for the
* entity.
* <p/>
* todo : does "logical name" include catalog/schema?
*
* @param metadataCollector
* @param logicalName
*
* @return
*/
Table resolveTable(InFlightMetadataCollector metadataCollector, String logicalName);
Column resolveColumn(InFlightMetadataCollector metadataCollector, Table table, String logicalName);
}
public static void bindConstraints(
MappingDocument mappingDocument,
RelationalObjectResolutionContext resolutionContext,
Collection<ConstraintSource> constraintSources) {
for ( ConstraintSource constraintSource : constraintSources ) {
if ( IndexConstraintSource.class.isInstance( constraintSource ) ) {
bindIndexConstraint(
mappingDocument,
resolutionContext,
(IndexConstraintSource) constraintSource
);
}
else if ( UniqueKeyConstraintSource.class.isInstance( constraintSource )) {
bindUniqueKeyConstraint(
mappingDocument,
resolutionContext,
(UniqueKeyConstraintSource) constraintSource
);
}
}
}
private static void bindIndexConstraint(
MappingDocument mappingDocument,
RelationalObjectResolutionContext resolutionContext,
IndexConstraintSource constraintSource) {
// 1) resolve table
final Table table = resolutionContext.resolveTable(
mappingDocument.getMetadataCollector(),
constraintSource.getTableName()
);
// 2) resolve Index
final Index index = table.getOrCreateIndex( constraintSource.name() );
// 3) add columns
for ( String columnName : constraintSource.columnNames() ) {
// 3.a) resolve Column reference
final Column column = resolutionContext.resolveColumn( mappingDocument.getMetadataCollector(), table, columnName );
// 3.b) add it to the Index
index.addColumn( column );
}
}
private static void bindUniqueKeyConstraint(
MappingDocument mappingDocument,
RelationalObjectResolutionContext resolutionContext,
UniqueKeyConstraintSource constraintSource) {
// 1) resolve table
final Table table = resolutionContext.resolveTable(
mappingDocument.getMetadataCollector(),
constraintSource.getTableName()
);
// 2) resolve UniqueKey
final UniqueKey uniqueKey = table.getOrCreateUniqueKey( constraintSource.name() );
// 3) add columns
for ( String columnName : constraintSource.columnNames() ) {
// 3.a) resolve Column reference
final Column column = resolutionContext.resolveColumn( mappingDocument.getMetadataCollector(), table, columnName );
// 3.b) add it to the UniqueKey
uniqueKey.addColumn( column );
}
}
}

View File

@ -10,6 +10,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.hibernate.boot.MappingException;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmColumnType;
@ -40,7 +41,7 @@ public class RelationalValueSourceHelper {
* <li>a {@code column} XML attribute</li>
* </ul>
*/
public static interface ColumnsAndFormulasSource {
public interface ColumnsAndFormulasSource {
/**
* What kind of XML element does this information come from?
*
@ -83,14 +84,11 @@ public class RelationalValueSourceHelper {
Boolean isNullable();
boolean isUnique();
String getIndex();
Set<String> getIndexConstraintNames();
String getUniqueKey();
Set<String> getUniqueKeyConstraintNames();
}
/**
* @author Steve Ebersole
*/
public abstract static class AbstractColumnsAndFormulasSource implements ColumnsAndFormulasSource {
@Override
public String getFormulaAttribute() {
@ -118,8 +116,8 @@ public class RelationalValueSourceHelper {
}
@Override
public String getIndex() {
return null;
public Set<String> getIndexConstraintNames() {
return Collections.emptySet();
}
@Override
@ -128,8 +126,8 @@ public class RelationalValueSourceHelper {
}
@Override
public String getUniqueKey() {
return null;
public Set<String> getUniqueKeyConstraintNames() {
return Collections.emptySet();
}
}
@ -333,7 +331,9 @@ public class RelationalValueSourceHelper {
new ColumnSourceImpl(
mappingDocument,
containingTableName,
columnElement
columnElement,
columnsAndFormulasSource.getIndexConstraintNames(),
columnsAndFormulasSource.getUniqueKeyConstraintNames()
)
);
}
@ -362,7 +362,9 @@ public class RelationalValueSourceHelper {
columnsAndFormulasSource.getColumnAttribute(),
columnsAndFormulasSource.getSizeSource(),
interpretNullabilityToTruthValue( columnsAndFormulasSource.isNullable() ),
columnsAndFormulasSource.isUnique() ? TruthValue.TRUE : TruthValue.FALSE
columnsAndFormulasSource.isUnique() ? TruthValue.TRUE : TruthValue.FALSE,
columnsAndFormulasSource.getIndexConstraintNames(),
columnsAndFormulasSource.getUniqueKeyConstraintNames()
)
);
}

View File

@ -1,32 +0,0 @@
/*
* 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.boot.model.source.internal.hbm;
import java.util.Locale;
import org.hibernate.boot.model.source.spi.UniqueKeyConstraintSource;
/**
* @author Steve Ebersole
*/
class UniqueKeyConstraintSourceImpl extends AbstractConstraintSource implements UniqueKeyConstraintSource {
UniqueKeyConstraintSourceImpl(String name, String tableName) {
super( name, tableName );
}
@Override
public String toString() {
return String.format(
Locale.ENGLISH,
"UniqueKeyConstraintSource{name='%s', tableName='%s', columnNames='%s', orderings=<not-implemented>}",
name,
tableName,
columnNames
);
}
}

View File

@ -6,15 +6,16 @@
*/
package org.hibernate.boot.model.source.spi;
import java.util.Set;
import org.hibernate.boot.model.TruthValue;
/**
* Contract for source information pertaining to a physical column definition specific to a particular attribute
* context.
* <p/>
* Conceptual note: this really describes a column from the perspective of its binding to an attribute.
* This is especially important for {@link #isIncludedInInsert} and {@link #isIncludedInUpdate}. There it is
* not the column itself being described.
* Conceptual note: this really describes a column from the perspective of its binding to an attribute, not
* necessarily the column itself.
*
* @author Steve Ebersole
*/
@ -24,75 +25,79 @@ public interface ColumnSource extends RelationalValueSource {
*
* @return The name of the column. Can be {@code null}, in which case a naming strategy is applied.
*/
public String getName();
String getName();
/**
* A SQL fragment to apply to the column value on read.
*
* @return The SQL read fragment
*/
public String getReadFragment();
String getReadFragment();
/**
* A SQL fragment to apply to the column value on write.
*
* @return The SQL write fragment
*/
public String getWriteFragment();
String getWriteFragment();
/**
* Is this column nullable?
*
* @return {@code true} indicates it is nullable; {@code false} non-nullable.
*/
public TruthValue isNullable();
TruthValue isNullable();
/**
* Obtain a specified default value for the column
*
* @return THe column default
*/
public String getDefaultValue();
String getDefaultValue();
/**
* Obtain the free-hand definition of the column's type.
*
* @return The free-hand column type
*/
public String getSqlType();
String getSqlType();
/**
* The deduced (and dialect convertible) type for this column
*
* @return The column's SQL data type.
*/
public JdbcDataType getDatatype();
JdbcDataType getDatatype();
/**
* Obtain the source for the specified column size.
*
* @return The source for the column size.
*/
public SizeSource getSizeSource();
SizeSource getSizeSource();
/**
* Is this column unique?
*
* @return {@code true} indicates it is unique; {@code false} non-unique.
*/
public boolean isUnique();
boolean isUnique();
/**
* Obtain the specified check constraint condition
*
* @return Check constraint condition
*/
public String getCheckCondition();
String getCheckCondition();
/**
* Obtain the specified SQL comment
*
* @return SQL comment
*/
public String getComment();
String getComment();
Set<String> getIndexConstraintNames();
Set<String> getUniqueKeyConstraintNames();
}

View File

@ -1,31 +0,0 @@
/*
* 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.boot.model.source.spi;
import java.util.List;
/**
* Contract describing source of table constraints
*
* @author Hardy Ferentschik
* @author Steve Ebersole
*/
public interface ConstraintSource {
/**
* @return returns the name of the constraint or {@code null} in case a generated name should be used
*/
public String name();
/**
* Obtain the logical name of the table for this constraint.
*
* @return The logical table name. Can be {@code null} in the case of the "primary table".
*/
public String getTableName();
public List<String> columnNames();
}

View File

@ -27,51 +27,51 @@ public interface EntitySource extends IdentifiableTypeSource, ToolingHintContext
*
* @return The primary table.
*/
public TableSpecificationSource getPrimaryTable();
TableSpecificationSource getPrimaryTable();
/**
* Obtain the secondary tables for this entity
*
* @return returns an iterator over the secondary tables for this entity
*/
public Map<String,SecondaryTableSource> getSecondaryTableMap();
Map<String,SecondaryTableSource> getSecondaryTableMap();
public String getXmlNodeName();
String getXmlNodeName();
/**
* Obtain the named custom tuplizer classes to be used.
*
* @return The custom tuplizer class names
*/
public Map<EntityMode,String> getTuplizerClassMap();
Map<EntityMode,String> getTuplizerClassMap();
/**
* Obtain the name of a custom persister class to be used.
*
* @return The custom persister class name
*/
public String getCustomPersisterClassName();
String getCustomPersisterClassName();
/**
* Is this entity lazy (proxyable)?
*
* @return {@code true} indicates the entity is lazy; {@code false} non-lazy.
*/
public boolean isLazy();
boolean isLazy();
/**
* For {@link #isLazy() lazy} entities, obtain the interface to use in constructing its proxies.
*
* @return The proxy interface name
*/
public String getProxy();
String getProxy();
/**
* Obtain the batch-size to be applied when initializing proxies of this entity.
*
* @return returns the the batch-size.
*/
public int getBatchSize();
int getBatchSize();
/**
* Is the entity abstract?
@ -81,63 +81,63 @@ public interface EntitySource extends IdentifiableTypeSource, ToolingHintContext
* @return {@code true} indicates the entity is abstract; {@code false} non-abstract; {@code null}
* indicates that a reflection check should be done when building the persister.
*/
public Boolean isAbstract();
Boolean isAbstract();
/**
* Did the source specify dynamic inserts?
*
* @return {@code true} indicates dynamic inserts will be used; {@code false} otherwise.
*/
public boolean isDynamicInsert();
boolean isDynamicInsert();
/**
* Did the source specify dynamic updates?
*
* @return {@code true} indicates dynamic updates will be used; {@code false} otherwise.
*/
public boolean isDynamicUpdate();
boolean isDynamicUpdate();
/**
* Did the source specify to perform selects to decide whether to perform (detached) updates?
*
* @return {@code true} indicates selects will be done; {@code false} otherwise.
*/
public boolean isSelectBeforeUpdate();
boolean isSelectBeforeUpdate();
/**
* Obtain the name of a named-query that will be used for loading this entity
*
* @return THe custom loader query name
*/
public String getCustomLoaderName();
String getCustomLoaderName();
/**
* Obtain the custom SQL to be used for inserts for this entity
*
* @return The custom insert SQL
*/
public CustomSql getCustomSqlInsert();
CustomSql getCustomSqlInsert();
/**
* Obtain the custom SQL to be used for updates for this entity
*
* @return The custom update SQL
*/
public CustomSql getCustomSqlUpdate();
CustomSql getCustomSqlUpdate();
/**
* Obtain the custom SQL to be used for deletes for this entity
*
* @return The custom delete SQL
*/
public CustomSql getCustomSqlDelete();
CustomSql getCustomSqlDelete();
/**
* Obtain any additional table names on which to synchronize (auto flushing) this entity.
*
* @return Additional synchronized table names or 0 sized String array, never return null.
*/
public String[] getSynchronizedTableNames();
String[] getSynchronizedTableNames();
/**
* Get the actual discriminator value in case of a single table inheritance
@ -145,24 +145,19 @@ public interface EntitySource extends IdentifiableTypeSource, ToolingHintContext
* @return the actual discriminator value in case of a single table inheritance or {@code null} in case there is no
* explicit value or a different inheritance scheme
*/
public String getDiscriminatorMatchValue();
/**
* @return returns the source information for constraints defined on the table
*/
public Collection<ConstraintSource> getConstraints();
String getDiscriminatorMatchValue();
/**
* Obtain the filters for this entity.
*
* @return returns an array of the filters for this entity.
*/
public FilterSource[] getFilterSources();
FilterSource[] getFilterSources();
public List<JaxbHbmNamedQueryType> getNamedQueries();
List<JaxbHbmNamedQueryType> getNamedQueries();
public List<JaxbHbmNamedNativeQueryType> getNamedNativeQueries();
List<JaxbHbmNamedNativeQueryType> getNamedNativeQueries();
public TruthValue quoteIdentifiersLocalToEntity();
TruthValue quoteIdentifiersLocalToEntity();
}

View File

@ -1,16 +0,0 @@
/*
* 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.boot.model.source.spi;
/**
* Defining a index constraint source
*
* @author Brett Meyer
*/
public interface IndexConstraintSource extends ConstraintSource {
public boolean isUnique();
}

View File

@ -1,13 +0,0 @@
/*
* 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.boot.model.source.spi;
/**
* @author Steve Ebersole
*/
public interface UniqueKeyConstraintSource extends ConstraintSource {
}

View File

@ -44,7 +44,7 @@ public class IndexTest extends BaseUnitTestCase {
}
@Test
@FailureExpected( jiraKey = "HHH-10208" )
// @FailureExpected( jiraKey = "HHH-10208" )
public void testOneToMany() throws Exception {
verifyIndexCreated(
"org/hibernate/test/hbm/index/person_manytoone.hbm.xml",
@ -68,7 +68,7 @@ public class IndexTest extends BaseUnitTestCase {
}
@Test
@FailureExpected( jiraKey = "HHH-10208" )
// @FailureExpected( jiraKey = "HHH-10208" )
public void testProperty() throws Exception {
verifyIndexCreated(
"org/hibernate/test/hbm/index/person_property.hbm.xml",