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

View File

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

View File

@ -65,6 +65,8 @@ import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.TableGenerator;
import jakarta.persistence.UniqueConstraint;
import static org.hibernate.cfg.AnnotatedColumn.buildColumnOrFormulaFromAnnotation;
/**
* @author Emmanuel Bernard
*/
@ -817,8 +819,8 @@ public class BinderHelper {
final BasicValueBinder<?> discriminatorValueBinder =
new BasicValueBinder<>( BasicValueBinder.Kind.ANY_DISCRIMINATOR, context );
final AnnotatedColumn[] discriminatorColumns = AnnotatedColumn.buildColumnFromAnnotation(
new jakarta.persistence.Column[] { discriminatorColumn },
final AnnotatedColumn[] discriminatorColumns = buildColumnOrFormulaFromAnnotation(
discriminatorColumn,
discriminatorFormula,
null,
nullability,
@ -947,8 +949,8 @@ public class BinderHelper {
}
return pd;
}
String propertyPath = isId ? "" : propertyName;
return buildingContext.getMetadataCollector().getPropertyAnnotatedWithMapsId( persistentXClass, propertyPath );
return buildingContext.getMetadataCollector()
.getPropertyAnnotatedWithMapsId( persistentXClass, isId ? "" : propertyName);
}
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.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;
/**
@ -77,12 +81,20 @@ class ColumnsBuilder {
Comment comment = property.getAnnotation(Comment.class);
if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent( Formula.class ) ) {
Column ann = property.getAnnotation( Column.class );
Formula formulaAnn = getOverridableAnnotation( property, Formula.class, buildingContext );
columns = AnnotatedColumn.buildColumnFromAnnotation(
new Column[] { ann },
formulaAnn,
if ( property.isAnnotationPresent( Column.class ) ) {
columns = buildColumnFromAnnotation(
property.getAnnotation( Column.class ),
comment,
nullability,
propertyHolder,
inferredData,
entityBinder.getSecondaryTables(),
buildingContext
);
}
else if ( property.isAnnotationPresent( Formula.class ) ) {
columns = buildFormulaFromAnnotation(
getOverridableAnnotation( property, Formula.class, buildingContext ),
comment,
nullability,
propertyHolder,
@ -92,10 +104,8 @@ class ColumnsBuilder {
);
}
else if ( property.isAnnotationPresent( Columns.class ) ) {
Columns anns = property.getAnnotation( Columns.class );
columns = AnnotatedColumn.buildColumnFromAnnotation(
anns.columns(),
null,
columns = buildColumnsFromAnnotations(
property.getAnnotation( Columns.class ).columns(),
comment,
nullability,
propertyHolder,
@ -110,20 +120,17 @@ class ColumnsBuilder {
( property.isAnnotationPresent( ManyToOne.class )
|| property.isAnnotationPresent( OneToOne.class ) )
) {
joinColumns = buildDefaultJoinColumnsForXToOne(property, inferredData);
joinColumns = buildDefaultJoinColumnsForXToOne( property, inferredData );
}
else if ( joinColumns == null &&
( property.isAnnotationPresent( OneToMany.class )
|| property.isAnnotationPresent( ElementCollection.class )
) ) {
OneToMany oneToMany = property.getAnnotation( OneToMany.class );
String mappedBy = oneToMany != null ?
oneToMany.mappedBy() :
"";
joinColumns = AnnotatedJoinColumn.buildJoinColumns(
null,
comment,
mappedBy,
oneToMany != null ? oneToMany.mappedBy() : "",
entityBinder.getSecondaryTables(),
propertyHolder,
inferredData.getPropertyName(),
@ -136,9 +143,7 @@ class ColumnsBuilder {
}
if ( columns == null && !property.isAnnotationPresent( ManyToMany.class ) ) {
//useful for collection of embedded elements
columns = AnnotatedColumn.buildColumnFromAnnotation(
null,
null,
columns = buildColumnFromNoAnnotation(
comment,
nullability,
propertyHolder,

View File

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

View File

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

View File

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