second round of binder cleanup: CollectionBinder, more AnnotationBinder

This commit is contained in:
Gavin King 2022-01-27 17:09:17 +01:00
parent 13b00f8907
commit 0a251e9a0e
9 changed files with 1659 additions and 1218 deletions

View File

@ -10,6 +10,7 @@ import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
@ -86,18 +87,9 @@ public class IdentifierGeneratorDefinition implements Serializable {
} }
IdentifierGeneratorDefinition that = (IdentifierGeneratorDefinition) o; IdentifierGeneratorDefinition that = (IdentifierGeneratorDefinition) o;
return Objects.equals(name, that.name)
if ( name != null ? !name.equals( that.name ) : that.name != null ) { && Objects.equals(strategy, that.strategy)
return false; && Objects.equals(parameters, that.parameters);
}
if ( parameters != null ? !parameters.equals( that.parameters ) : that.parameters != null ) {
return false;
}
if ( strategy != null ? !strategy.equals( that.strategy ) : that.strategy != null ) {
return false;
}
return true;
} }
@Override @Override

View File

@ -236,7 +236,15 @@ public class AnnotatedColumn {
} }
else { else {
initMappingColumn( initMappingColumn(
logicalColumnName, propertyName, length, precision, scale, nullable, sqlType, unique, true logicalColumnName,
propertyName,
length,
precision,
scale,
nullable,
sqlType,
unique,
true
); );
if ( defaultValue != null ) { if ( defaultValue != null ) {
mappingColumn.setDefaultValue( defaultValue ); mappingColumn.setDefaultValue( defaultValue );
@ -518,8 +526,7 @@ public class AnnotatedColumn {
mappingColumn.setNullable( false ); mappingColumn.setNullable( false );
} }
public static AnnotatedColumn[] buildColumnFromAnnotation( public static AnnotatedColumn[] buildFormulaFromAnnotation(
jakarta.persistence.Column[] anns,
org.hibernate.annotations.Formula formulaAnn, org.hibernate.annotations.Formula formulaAnn,
Comment commentAnn, Comment commentAnn,
Nullability nullability, Nullability nullability,
@ -527,8 +534,110 @@ public class AnnotatedColumn {
PropertyData inferredData, PropertyData inferredData,
Map<String, Join> secondaryTables, Map<String, Join> secondaryTables,
MetadataBuildingContext context) { MetadataBuildingContext context) {
return buildColumnFromAnnotation( return buildColumnOrFormulaFromAnnotation(
anns, null,
formulaAnn,
commentAnn,
nullability,
propertyHolder,
inferredData,
secondaryTables,
context
);
}
public static AnnotatedColumn[] buildColumnFromNoAnnotation(
Comment commentAnn,
Nullability nullability,
PropertyHolder propertyHolder,
PropertyData inferredData,
Map<String, Join> secondaryTables,
MetadataBuildingContext context) {
return buildColumnsFromAnnotations(
null,
commentAnn,
nullability,
propertyHolder,
inferredData,
secondaryTables,
context
);
}
public static AnnotatedColumn[] buildColumnFromAnnotation(
jakarta.persistence.Column column,
Comment commentAnn,
Nullability nullability,
PropertyHolder propertyHolder,
PropertyData inferredData,
Map<String, Join> secondaryTables,
MetadataBuildingContext context) {
return buildColumnOrFormulaFromAnnotation(
column,
null,
commentAnn,
nullability,
propertyHolder,
inferredData,
secondaryTables,
context
);
}
public static AnnotatedColumn[] buildColumnsFromAnnotations(
jakarta.persistence.Column[] columns,
Comment commentAnn,
Nullability nullability,
PropertyHolder propertyHolder,
PropertyData inferredData,
Map<String, Join> secondaryTables,
MetadataBuildingContext context) {
return buildColumnsOrFormulaFromAnnotation(
columns,
null,
commentAnn,
nullability,
propertyHolder,
inferredData,
null,
secondaryTables,
context
);
}
public static AnnotatedColumn[] buildColumnsFromAnnotations(
jakarta.persistence.Column[] columns,
Comment commentAnn,
Nullability nullability,
PropertyHolder propertyHolder,
PropertyData inferredData,
String suffixForDefaultColumnName,
Map<String, Join> secondaryTables,
MetadataBuildingContext context) {
return buildColumnsOrFormulaFromAnnotation(
columns,
null,
commentAnn,
nullability,
propertyHolder,
inferredData,
suffixForDefaultColumnName,
secondaryTables,
context
);
}
public static AnnotatedColumn[] buildColumnOrFormulaFromAnnotation(
jakarta.persistence.Column column,
org.hibernate.annotations.Formula formulaAnn,
Comment commentAnn,
Nullability nullability,
PropertyHolder propertyHolder,
PropertyData inferredData,
Map<String, Join> secondaryTables,
MetadataBuildingContext context) {
return buildColumnsOrFormulaFromAnnotation(
new jakarta.persistence.Column[] { column },
formulaAnn, formulaAnn,
commentAnn, commentAnn,
nullability, nullability,
@ -539,8 +648,9 @@ public class AnnotatedColumn {
context context
); );
} }
public static AnnotatedColumn[] buildColumnFromAnnotation(
jakarta.persistence.Column[] anns, public static AnnotatedColumn[] buildColumnsOrFormulaFromAnnotation(
jakarta.persistence.Column[] columnAnns,
org.hibernate.annotations.Formula formulaAnn, org.hibernate.annotations.Formula formulaAnn,
Comment commentAnn, Comment commentAnn,
Nullability nullability, Nullability nullability,
@ -549,7 +659,7 @@ public class AnnotatedColumn {
String suffixForDefaultColumnName, String suffixForDefaultColumnName,
Map<String, Join> secondaryTables, Map<String, Join> secondaryTables,
MetadataBuildingContext context) { MetadataBuildingContext context) {
AnnotatedColumn[] columns;
if ( formulaAnn != null ) { if ( formulaAnn != null ) {
AnnotatedColumn formulaColumn = new AnnotatedColumn(); AnnotatedColumn formulaColumn = new AnnotatedColumn();
formulaColumn.setFormula( formulaAnn.value() ); formulaColumn.setFormula( formulaAnn.value() );
@ -557,21 +667,23 @@ public class AnnotatedColumn {
formulaColumn.setBuildingContext( context ); formulaColumn.setBuildingContext( context );
formulaColumn.setPropertyHolder( propertyHolder ); formulaColumn.setPropertyHolder( propertyHolder );
formulaColumn.bind(); formulaColumn.bind();
columns = new AnnotatedColumn[] { formulaColumn }; return new AnnotatedColumn[] { formulaColumn };
} }
else { else {
jakarta.persistence.Column[] actualCols = anns; jakarta.persistence.Column[] actualCols = columnAnns;
jakarta.persistence.Column[] overriddenCols = propertyHolder.getOverriddenColumn( jakarta.persistence.Column[] overriddenCols = propertyHolder.getOverriddenColumn(
StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() ) StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() )
); );
if ( overriddenCols != null ) { if ( overriddenCols != null ) {
//check for overridden first //check for overridden first
if ( anns != null && overriddenCols.length != anns.length ) { if ( columnAnns != null && overriddenCols.length != columnAnns.length ) {
throw new AnnotationException( "AttributeOverride.column() should override all columns for now" ); throw new AnnotationException( "AttributeOverride.column() should override all columns for now" );
} }
actualCols = overriddenCols.length == 0 ? null : overriddenCols; actualCols = overriddenCols.length == 0 ? null : overriddenCols;
LOG.debugf( "Column(s) overridden for property %s", inferredData.getPropertyName() ); LOG.debugf( "Column(s) overridden for property %s", inferredData.getPropertyName() );
} }
AnnotatedColumn[] columns;
if ( actualCols == null ) { if ( actualCols == null ) {
columns = buildImplicitColumn( columns = buildImplicitColumn(
inferredData, inferredData,
@ -667,9 +779,10 @@ public class AnnotatedColumn {
columns[index] = column; columns[index] = column;
} }
} }
}
return columns; return columns;
} }
}
private void applyColumnDefault(PropertyData inferredData, int length) { private void applyColumnDefault(PropertyData inferredData, int length) {
final XProperty xProperty = inferredData.getProperty(); final XProperty xProperty = inferredData.getProperty();

View File

@ -65,6 +65,8 @@ import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.TableGenerator; import jakarta.persistence.TableGenerator;
import jakarta.persistence.UniqueConstraint; import jakarta.persistence.UniqueConstraint;
import static org.hibernate.cfg.AnnotatedColumn.buildColumnOrFormulaFromAnnotation;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
*/ */
@ -817,8 +819,8 @@ public class BinderHelper {
final BasicValueBinder<?> discriminatorValueBinder = final BasicValueBinder<?> discriminatorValueBinder =
new BasicValueBinder<>( BasicValueBinder.Kind.ANY_DISCRIMINATOR, context ); new BasicValueBinder<>( BasicValueBinder.Kind.ANY_DISCRIMINATOR, context );
final AnnotatedColumn[] discriminatorColumns = AnnotatedColumn.buildColumnFromAnnotation( final AnnotatedColumn[] discriminatorColumns = buildColumnOrFormulaFromAnnotation(
new jakarta.persistence.Column[] { discriminatorColumn }, discriminatorColumn,
discriminatorFormula, discriminatorFormula,
null, null,
nullability, nullability,
@ -947,8 +949,8 @@ public class BinderHelper {
} }
return pd; return pd;
} }
String propertyPath = isId ? "" : propertyName; return buildingContext.getMetadataCollector()
return buildingContext.getMetadataCollector().getPropertyAnnotatedWithMapsId( persistentXClass, propertyPath ); .getPropertyAnnotatedWithMapsId( persistentXClass, isId ? "" : propertyName);
} }
public static Map<String,String> toAliasTableMap(SqlFragmentAlias[] aliases){ public static Map<String,String> toAliasTableMap(SqlFragmentAlias[] aliases){

View File

@ -28,6 +28,10 @@ import org.hibernate.cfg.annotations.EntityBinder;
import org.hibernate.cfg.annotations.Nullability; import org.hibernate.cfg.annotations.Nullability;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import static org.hibernate.cfg.AnnotatedColumn.buildColumnFromAnnotation;
import static org.hibernate.cfg.AnnotatedColumn.buildColumnFromNoAnnotation;
import static org.hibernate.cfg.AnnotatedColumn.buildColumnsFromAnnotations;
import static org.hibernate.cfg.AnnotatedColumn.buildFormulaFromAnnotation;
import static org.hibernate.cfg.AnnotationBinder.getOverridableAnnotation; import static org.hibernate.cfg.AnnotationBinder.getOverridableAnnotation;
/** /**
@ -77,12 +81,20 @@ class ColumnsBuilder {
Comment comment = property.getAnnotation(Comment.class); Comment comment = property.getAnnotation(Comment.class);
if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent( Formula.class ) ) { if ( property.isAnnotationPresent( Column.class ) ) {
Column ann = property.getAnnotation( Column.class ); columns = buildColumnFromAnnotation(
Formula formulaAnn = getOverridableAnnotation( property, Formula.class, buildingContext ); property.getAnnotation( Column.class ),
columns = AnnotatedColumn.buildColumnFromAnnotation( comment,
new Column[] { ann }, nullability,
formulaAnn, propertyHolder,
inferredData,
entityBinder.getSecondaryTables(),
buildingContext
);
}
else if ( property.isAnnotationPresent( Formula.class ) ) {
columns = buildFormulaFromAnnotation(
getOverridableAnnotation( property, Formula.class, buildingContext ),
comment, comment,
nullability, nullability,
propertyHolder, propertyHolder,
@ -92,10 +104,8 @@ class ColumnsBuilder {
); );
} }
else if ( property.isAnnotationPresent( Columns.class ) ) { else if ( property.isAnnotationPresent( Columns.class ) ) {
Columns anns = property.getAnnotation( Columns.class ); columns = buildColumnsFromAnnotations(
columns = AnnotatedColumn.buildColumnFromAnnotation( property.getAnnotation( Columns.class ).columns(),
anns.columns(),
null,
comment, comment,
nullability, nullability,
propertyHolder, propertyHolder,
@ -110,20 +120,17 @@ class ColumnsBuilder {
( property.isAnnotationPresent( ManyToOne.class ) ( property.isAnnotationPresent( ManyToOne.class )
|| property.isAnnotationPresent( OneToOne.class ) ) || property.isAnnotationPresent( OneToOne.class ) )
) { ) {
joinColumns = buildDefaultJoinColumnsForXToOne(property, inferredData); joinColumns = buildDefaultJoinColumnsForXToOne( property, inferredData );
} }
else if ( joinColumns == null && else if ( joinColumns == null &&
( property.isAnnotationPresent( OneToMany.class ) ( property.isAnnotationPresent( OneToMany.class )
|| property.isAnnotationPresent( ElementCollection.class ) || property.isAnnotationPresent( ElementCollection.class )
) ) { ) ) {
OneToMany oneToMany = property.getAnnotation( OneToMany.class ); OneToMany oneToMany = property.getAnnotation( OneToMany.class );
String mappedBy = oneToMany != null ?
oneToMany.mappedBy() :
"";
joinColumns = AnnotatedJoinColumn.buildJoinColumns( joinColumns = AnnotatedJoinColumn.buildJoinColumns(
null, null,
comment, comment,
mappedBy, oneToMany != null ? oneToMany.mappedBy() : "",
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
inferredData.getPropertyName(), inferredData.getPropertyName(),
@ -136,9 +143,7 @@ class ColumnsBuilder {
} }
if ( columns == null && !property.isAnnotationPresent( ManyToMany.class ) ) { if ( columns == null && !property.isAnnotationPresent( ManyToMany.class ) ) {
//useful for collection of embedded elements //useful for collection of embedded elements
columns = AnnotatedColumn.buildColumnFromAnnotation( columns = buildColumnFromNoAnnotation(
null,
null,
comment, comment,
nullability, nullability,
propertyHolder, propertyHolder,

View File

@ -28,7 +28,6 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.IdentifierBag; import org.hibernate.mapping.IdentifierBag;
import org.hibernate.mapping.IdentifierCollection; import org.hibernate.mapping.IdentifierCollection;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.SemanticsResolver;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.resource.beans.spi.ManagedBean; import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.usertype.UserCollectionType; import org.hibernate.usertype.UserCollectionType;
@ -49,7 +48,7 @@ public class IdBagBinder extends BagBinder {
@Override @Override
protected boolean bindStarToManySecondPass( protected boolean bindStarToManySecondPass(
Map persistentClasses, Map<String, PersistentClass> persistentClasses,
XClass collType, XClass collType,
AnnotatedJoinColumn[] fkJoinColumns, AnnotatedJoinColumn[] fkJoinColumns,
AnnotatedJoinColumn[] keyColumns, AnnotatedJoinColumn[] keyColumns,
@ -62,8 +61,18 @@ public class IdBagBinder extends BagBinder {
boolean ignoreNotFound, boolean ignoreNotFound,
MetadataBuildingContext buildingContext) { MetadataBuildingContext buildingContext) {
boolean result = super.bindStarToManySecondPass( boolean result = super.bindStarToManySecondPass(
persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns, elementColumns, isEmbedded, persistentClasses,
property, unique, associationTableBinder, ignoreNotFound, getBuildingContext() collType,
fkJoinColumns,
keyColumns,
inverseColumns,
elementColumns,
isEmbedded,
property,
unique,
associationTableBinder,
ignoreNotFound,
getBuildingContext()
); );
final CollectionId collectionIdAnn = property.getAnnotation( CollectionId.class ); final CollectionId collectionIdAnn = property.getAnnotation( CollectionId.class );
@ -82,10 +91,9 @@ public class IdBagBinder extends BagBinder {
"id" "id"
); );
final AnnotatedColumn[] idColumns = AnnotatedColumn.buildColumnFromAnnotation( final AnnotatedColumn[] idColumns = AnnotatedColumn.buildColumnsFromAnnotations(
new Column[] { collectionIdAnn.column() }, new Column[] { collectionIdAnn.column() },
null, null,
null,
Nullability.FORCED_NOT_NULL, Nullability.FORCED_NOT_NULL,
propertyHolder, propertyHolder,
propertyData, propertyData,
@ -98,7 +106,7 @@ public class IdBagBinder extends BagBinder {
idColumn.setNullable( false ); idColumn.setNullable( false );
} }
final BasicValueBinder valueBinder = new BasicValueBinder( BasicValueBinder.Kind.COLLECTION_ID, buildingContext ); final BasicValueBinder<?> valueBinder = new BasicValueBinder<>( BasicValueBinder.Kind.COLLECTION_ID, buildingContext );
final Table table = collection.getCollectionTable(); final Table table = collection.getCollectionTable();
valueBinder.setTable( table ); valueBinder.setTable( table );

View File

@ -24,7 +24,7 @@ import static org.junit.Assert.fail;
*/ */
public class EntityNonEntityTest extends BaseCoreFunctionalTestCase { public class EntityNonEntityTest extends BaseCoreFunctionalTestCase {
@Test @Test
public void testMix() throws Exception { public void testMix() {
GSM gsm = new GSM(); GSM gsm = new GSM();
gsm.brand = "Sony"; gsm.brand = "Sony";
gsm.frequency = 900; gsm.frequency = 900;
@ -37,7 +37,7 @@ public class EntityNonEntityTest extends BaseCoreFunctionalTestCase {
tx.commit(); tx.commit();
s.clear(); s.clear();
tx = s.beginTransaction(); tx = s.beginTransaction();
gsm = (GSM) s.get( GSM.class, gsm.id ); gsm = s.get( GSM.class, gsm.id );
assertEquals( "top mapped superclass", 2, gsm.number ); assertEquals( "top mapped superclass", 2, gsm.number );
assertNull( "non entity between mapped superclass and entity", gsm.species ); assertNull( "non entity between mapped superclass and entity", gsm.species );
assertTrue( "mapped superclass under entity", gsm.isNumeric ); assertTrue( "mapped superclass under entity", gsm.isNumeric );

View File

@ -27,7 +27,7 @@ public class BasicSessionFactoryScopeTests {
assertThat( scope.getSessionFactory(), notNullValue() ); assertThat( scope.getSessionFactory(), notNullValue() );
// check we can use the SF to create Sessions // check we can use the SF to create Sessions
scope.inTransaction( scope.inTransaction(
(session) -> session.createQuery( "from AnEntity" ).list() session -> session.createQuery( "from AnEntity" ).list()
); );
} }