HHH-18187 finally remove @Index (yay!)

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-06-15 12:13:58 +02:00 committed by Steve Ebersole
parent cc4656d8f1
commit 3d686a3b97
14 changed files with 120 additions and 312 deletions

View File

@ -1,35 +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.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Defines an index of a database table.
*
* @author Emmanuel Bernard
*
* @deprecated Use {@link jakarta.persistence.Index} instead.
*/
@Target({FIELD, METHOD})
@Retention(RUNTIME)
@Deprecated
public @interface Index {
/**
* The index name.
*/
String name();
/**
* The column(s) that are indexed.
*/
String[] columnNames() default {};
}

View File

@ -18,7 +18,6 @@ import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.ColumnTransformer;
import org.hibernate.annotations.FractionalSeconds;
import org.hibernate.annotations.GeneratedColumn;
import org.hibernate.annotations.Index;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitBasicColumnNameSource;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
@ -1012,26 +1011,9 @@ public class AnnotatedColumn {
return columns;
}
public void addIndex(Index index, boolean inSecondPass) {
if ( index != null ) {
addIndex( index.name(), inSecondPass );
}
}
void addIndex(String indexName, boolean inSecondPass) {
final IndexOrUniqueKeySecondPass secondPass =
new IndexOrUniqueKeySecondPass( indexName, this, getBuildingContext(), false );
if ( inSecondPass ) {
secondPass.doSecondPass( getBuildingContext().getMetadataCollector().getEntityBindingMap() );
}
else {
getBuildingContext().getMetadataCollector().addSecondPass( secondPass );
}
}
void addUniqueKey(String uniqueKeyName, boolean inSecondPass) {
final IndexOrUniqueKeySecondPass secondPass =
new IndexOrUniqueKeySecondPass( uniqueKeyName, this, getBuildingContext(), true );
final UniqueKeySecondPass secondPass =
new UniqueKeySecondPass( uniqueKeyName, this, getBuildingContext() );
if ( inSecondPass ) {
secondPass.doSecondPass( getBuildingContext().getMetadataCollector().getEntityBindingMap() );
}

View File

@ -1,124 +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.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.hibernate.AnnotationException;
import org.hibernate.MappingException;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.SecondPass;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.Index;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey;
/**
* @author Emmanuel Bernard
*/
public class IndexOrUniqueKeySecondPass implements SecondPass {
private Table table;
private final String indexName;
private final String[] columns;
private final MetadataBuildingContext buildingContext;
private final AnnotatedColumn column;
private final boolean unique;
/**
* Build an index
*/
public IndexOrUniqueKeySecondPass(Table table, String indexName, String[] columns, MetadataBuildingContext buildingContext) {
this.table = table;
this.indexName = indexName;
this.columns = columns;
this.buildingContext = buildingContext;
this.column = null;
this.unique = false;
}
/**
* Build an index if unique is false or a Unique Key if unique is true
*/
public IndexOrUniqueKeySecondPass(String indexName, AnnotatedColumn column, MetadataBuildingContext buildingContext, boolean unique) {
this.indexName = indexName;
this.column = column;
this.columns = null;
this.buildingContext = buildingContext;
this.unique = unique;
}
@Override
public void doSecondPass(Map<String, PersistentClass> persistentClasses) throws MappingException {
if ( columns != null ) {
for ( String columnName : columns ) {
addConstraintToColumn( columnName );
}
}
if ( column != null ) {
table = column.getParent().getTable();
final PropertyHolder propertyHolder = column.getParent().getPropertyHolder();
final String entityName = propertyHolder.isComponent()
? propertyHolder.getPersistentClass().getEntityName()
: propertyHolder.getEntityName();
final PersistentClass persistentClass = persistentClasses.get( entityName );
final Property property = persistentClass.getProperty( column.getParent().getPropertyName() );
if ( property.getValue() instanceof Component ) {
final Component component = (Component) property.getValue();
final List<Column> columns = new ArrayList<>();
for ( Selectable selectable: component.getSelectables() ) {
if ( selectable instanceof Column ) {
columns.add( (Column) selectable );
}
}
addConstraintToColumns( columns );
}
else {
addConstraintToColumn(
buildingContext.getMetadataCollector()
.getLogicalColumnName( table, column.getMappingColumn().getQuotedName() )
);
}
}
}
private void addConstraintToColumn(final String columnName ) {
Column column = table.getColumn( buildingContext.getMetadataCollector(), columnName );
if ( column == null ) {
throw new AnnotationException(
"Table '" + table.getName() + "' has no column named '" + columnName
+ "' matching the column specified in '@Index'"
);
}
if ( unique ) {
table.getOrCreateUniqueKey( indexName ).addColumn( column );
}
else {
table.getOrCreateIndex( indexName ).addColumn( column );
}
}
private void addConstraintToColumns(List<Column> columns) {
if ( unique ) {
final UniqueKey uniqueKey = table.getOrCreateUniqueKey( indexName );
for ( Column column : columns ) {
uniqueKey.addColumn( column );
}
}
else {
final Index index = table.getOrCreateIndex( indexName );
for ( Column column : columns ) {
index.addColumn( column );
}
}
}
}

View File

@ -18,7 +18,6 @@ import org.hibernate.annotations.Any;
import org.hibernate.annotations.AttributeBinderType;
import org.hibernate.annotations.CompositeType;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.LazyGroup;
import org.hibernate.annotations.ManyToAny;
import org.hibernate.annotations.NaturalId;
@ -817,7 +816,6 @@ public class PropertyBinder {
columnsBuilder,
propertyBinder
);
addIndexes( inSecondPass, property, columns, joinColumns );
addNaturalIds( inSecondPass, property, columns, joinColumns, context );
}
@ -1306,31 +1304,6 @@ public class PropertyBinder {
return annotationUsage != null && annotationUsage.fetch() == LAZY;
}
private static void addIndexes(
boolean inSecondPass,
MemberDetails property,
AnnotatedColumns columns,
AnnotatedJoinColumns joinColumns) {
//process indexes after everything: in second pass, many to one has to be done before indexes
final Index index = property.getDirectAnnotationUsage( Index.class );
if ( index == null ) {
return;
}
if ( joinColumns != null ) {
for ( AnnotatedColumn column : joinColumns.getColumns() ) {
column.addIndex( index, inSecondPass );
}
}
else {
if ( columns != null ) {
for ( AnnotatedColumn column : columns.getColumns() ) {
column.addIndex( index, inSecondPass );
}
}
}
}
private static void addNaturalIds(
boolean inSecondPass,
MemberDetails property,
@ -1340,7 +1313,7 @@ public class PropertyBinder {
// Natural ID columns must reside in one single UniqueKey within the Table.
// For now, simply ensure consistent naming.
// TODO: AFAIK, there really isn't a reason for these UKs to be created
// on the SecondPass. This whole area should go away...
// on the SecondPass. This whole area should go away...
final NaturalId naturalId = property.getDirectAnnotationUsage( NaturalId.class );
if ( naturalId != null ) {
final Database database = context.getMetadataCollector().getDatabase();

View File

@ -705,7 +705,7 @@ public class TableBinder {
catch (MappingException ignore) {
}
}
if ( referencedColumn == null ) {
if ( referencedColumn == null || columns == null ) {
throw me;
}
}
@ -862,25 +862,7 @@ public class TableBinder {
}
}
static void addIndexes(Table table, org.hibernate.annotations.Index[] indexes, MetadataBuildingContext context) {
for ( org.hibernate.annotations.Index indexUsage : indexes ) {
final String name = indexUsage.name();
final String[] columnNames = indexUsage.columnNames();
//no need to handle inSecondPass here since it is only called from EntityBinder
context.getMetadataCollector().addSecondPass( new IndexOrUniqueKeySecondPass(
table,
name,
columnNames,
context
) );
}
}
static void addJpaIndexes(
Table table,
jakarta.persistence.Index[] indexes,
MetadataBuildingContext context) {
static void addJpaIndexes(Table table, Index[] indexes, MetadataBuildingContext context) {
new IndexBinder( context ).bindIndexes( table, indexes );
}

View File

@ -0,0 +1,94 @@
/*
* 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.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.hibernate.AnnotationException;
import org.hibernate.MappingException;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.SecondPass;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey;
/**
* @author Emmanuel Bernard
*/
public class UniqueKeySecondPass implements SecondPass {
private final String indexName;
private final MetadataBuildingContext buildingContext;
private final AnnotatedColumn column;
/**
* Build an index if unique is false or a Unique Key if unique is true
*/
public UniqueKeySecondPass(String indexName, AnnotatedColumn column, MetadataBuildingContext buildingContext) {
this.indexName = indexName;
this.column = column;
this.buildingContext = buildingContext;
}
@Override
public void doSecondPass(Map<String, PersistentClass> persistentClasses) throws MappingException {
if ( column != null ) {
final AnnotatedColumns annotatedColumns = column.getParent();
final Table table = annotatedColumns.getTable();
final PropertyHolder propertyHolder = annotatedColumns.getPropertyHolder();
final String entityName =
propertyHolder.isComponent()
? propertyHolder.getPersistentClass().getEntityName()
: propertyHolder.getEntityName();
final String propertyName = annotatedColumns.getPropertyName();
final Property property = persistentClasses.get( entityName ).getProperty( propertyName );
addConstraintToProperty( property, table );
}
}
private void addConstraintToProperty(Property property, Table table) {
if ( property.getValue() instanceof Component ) {
final Component component = (Component) property.getValue();
final List<Column> columns = new ArrayList<>();
for ( Selectable selectable: component.getSelectables() ) {
if ( selectable instanceof Column ) {
columns.add( (Column) selectable );
}
}
addConstraintToColumns( columns, table );
}
else {
addConstraintToColumn( column.getMappingColumn(), table );
}
}
private void addConstraintToColumn(Column mappingColumn, Table table) {
final String columnName =
buildingContext.getMetadataCollector()
.getLogicalColumnName( table, mappingColumn.getQuotedName() );
final Column column = table.getColumn( buildingContext.getMetadataCollector(), columnName );
if ( column == null ) {
throw new AnnotationException(
"Table '" + table.getName() + "' has no column named '" + columnName
+ "' matching the column specified in '@Index'"
);
}
table.getOrCreateUniqueKey( indexName ).addColumn( column );
}
private void addConstraintToColumns(List<Column> columns, Table table) {
final UniqueKey uniqueKey = table.getOrCreateUniqueKey( indexName );
for ( Column column : columns ) {
uniqueKey.addColumn( column );
}
}
}

View File

@ -323,10 +323,6 @@ public interface HibernateAnnotations {
Imported.class,
ImportedAnnotation.class
);
OrmAnnotationDescriptor<Index, IndexAnnotation> INDEX = new OrmAnnotationDescriptor<>(
Index.class,
IndexAnnotation.class
);
OrmAnnotationDescriptor<IndexColumn,IndexColumnAnnotation> INDEX_COLUMN = new OrmAnnotationDescriptor<>(
IndexColumn.class,
IndexColumnAnnotation.class

View File

@ -1,65 +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.models.annotations.internal;
import java.lang.annotation.Annotation;
import org.hibernate.boot.models.HibernateAnnotations;
import org.hibernate.models.spi.SourceModelBuildingContext;
import org.jboss.jandex.AnnotationInstance;
import org.hibernate.annotations.Index;
import static org.hibernate.boot.models.internal.OrmAnnotationHelper.extractJandexValue;
@SuppressWarnings({ "ClassExplicitlyAnnotation", "unused" })
@jakarta.annotation.Generated("org.hibernate.orm.build.annotations.ClassGeneratorProcessor")
public class IndexAnnotation implements Index {
private String name;
private String[] columnNames;
public IndexAnnotation(SourceModelBuildingContext modelContext) {
this.name = "";
this.columnNames = new String[0];
}
public IndexAnnotation(Index annotation, SourceModelBuildingContext modelContext) {
name( annotation.name() );
columnNames( annotation.columnNames() );
}
public IndexAnnotation(AnnotationInstance annotation, SourceModelBuildingContext modelContext) {
name( extractJandexValue( annotation, HibernateAnnotations.INDEX, "name", modelContext ) );
columnNames( extractJandexValue( annotation, HibernateAnnotations.INDEX, "columnNames", modelContext ) );
}
@Override
public Class<? extends Annotation> annotationType() {
return Index.class;
}
@Override
public String name() {
return name;
}
public void name(String value) {
this.name = value;
}
@Override
public String[] columnNames() {
return columnNames;
}
public void columnNames(String[] value) {
this.columnNames = value;
}
}

View File

@ -11,12 +11,14 @@ import java.util.List;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import org.hibernate.annotations.Index;
import jakarta.persistence.Table;
@Entity
@Table(indexes = @Index(name="`titleindex`", columnList = "`title`"))
public class Bug
{
@Id
@ -24,7 +26,7 @@ public class Bug
private int id;
@Column(name="`title`")
@Index(name="`titleindex`")
private String title;
@ManyToMany

View File

@ -12,16 +12,16 @@ import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import org.hibernate.annotations.Index;
/**
* @author Emmanuel Bernard
*/
@Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"start_country", "start_city"})})
@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"start_country", "start_city"}),
indexes = @Index(name="storm_name_idx", columnList = "stormName"))
public class Storm {
private Integer id;
private Location start;
@ -56,7 +56,6 @@ public class Storm {
this.end = end;
}
@Index(name="storm_name_idx")
@Column(unique = true)
public String getStormName() {
return stormName;

View File

@ -11,16 +11,17 @@ package org.hibernate.orm.test.annotations.tableperclass;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import org.hibernate.annotations.Index;
import jakarta.persistence.Table;
/**
* @author Emmanuel Bernard
*/
@Entity(name = "xpmComponent")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(indexes = @Index(name = "manufacturerPartNumber", columnList = "manufacturerPartNumber"))
public abstract class Component {
private String manufacturerPartNumber;
private Long manufacturerId;
@ -36,7 +37,6 @@ public abstract class Component {
}
@Column(nullable = false)
@Index(name = "manufacturerPartNumber")
public String getManufacturerPartNumber() {
return manufacturerPartNumber;
}

View File

@ -11,22 +11,23 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.OptimisticLock;
/**
* @author Emmanuel Bernard
*/
@Entity
@Table(indexes = @Index(name = "cond_name", columnList = "cond_name"))
public class Conductor {
@Id
@GeneratedValue
private Integer id;
@Column(name = "cond_name")
@Index(name = "cond_name")
@OptimisticLock(excluded = true)
private String name;

View File

@ -8,22 +8,24 @@
//$Id$
package org.hibernate.orm.test.annotations.various;
import jakarta.persistence.Entity;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import org.hibernate.annotations.Index;
import jakarta.persistence.Table;
/**
* @author Emmanuel Bernard
*/
@Entity
@Table(indexes = {@Index(name = "weigth_idx", columnList = "weight"),
@Index(name = "agreement_idx", columnList = "agreement_id")})
public class Truck extends Vehicule {
@Index(name = "weigth_idx")
private int weight;
@ManyToOne
@JoinColumn(name = "agreement_id")
@Index(name = "agreement_idx")
private ProfessionalAgreement agreement;
public int getWeight() {

View File

@ -12,7 +12,8 @@ import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import org.hibernate.annotations.Index;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
@ -72,6 +73,7 @@ public class ComponentIndexTest {
}
@Entity(name = "user")
@Table(indexes = @Index(name = "city_index", columnList = "city"))
public class User {
@Id
private Long id;
@ -81,7 +83,6 @@ public class ComponentIndexTest {
@Embeddable
public class Address {
@Index( name = "city_index")
private String city;
private String street;
private String postalCode;