finally move propertyName from AnnotatedColumn

This commit is contained in:
Gavin King 2022-10-31 15:41:17 +01:00
parent e4c1d493e3
commit 849246e3cd
11 changed files with 123 additions and 151 deletions

View File

@ -6,7 +6,6 @@
*/ */
package org.hibernate.cfg; package org.hibernate.cfg;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
@ -44,7 +43,6 @@ import static org.hibernate.cfg.BinderHelper.isEmptyAnnotationValue;
import static org.hibernate.internal.util.StringHelper.isEmpty; import static org.hibernate.internal.util.StringHelper.isEmpty;
import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.StringHelper.nullIfEmpty; import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
import static org.hibernate.internal.util.StringHelper.qualify;
/** /**
* A mapping to a column, logically representing a * A mapping to a column, logically representing a
@ -75,7 +73,6 @@ public class AnnotatedColumn {
private Integer precision; private Integer precision;
private Integer scale; private Integer scale;
private String logicalColumnName; private String logicalColumnName;
private String propertyName; // this is really a .-separated property path
private boolean unique; private boolean unique;
private boolean nullable = true; private boolean nullable = true;
private String formulaString; private String formulaString;
@ -180,17 +177,6 @@ public class AnnotatedColumn {
this.logicalColumnName = logicalColumnName; this.logicalColumnName = logicalColumnName;
} }
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
/**
* A property path relative to the {@link #getPropertyHolder() PropertyHolder}.
*/
public String getPropertyName() {
return propertyName;
}
public void setUnique(boolean unique) { public void setUnique(boolean unique) {
this.unique = unique; this.unique = unique;
} }
@ -243,7 +229,7 @@ public class AnnotatedColumn {
else { else {
initMappingColumn( initMappingColumn(
logicalColumnName, logicalColumnName,
propertyName, getParent().getPropertyName(),
length, length,
precision, precision,
scale, scale,
@ -361,8 +347,8 @@ public class AnnotatedColumn {
public boolean isCollectionElement() { public boolean isCollectionElement() {
// if the propertyHolder is a collection, assume the // if the propertyHolder is a collection, assume the
// @Column refers to the element column // @Column refers to the element column
return !getPropertyHolder().isComponent() final PropertyHolder propertyHolder = getParent().getPropertyHolder();
&& !getPropertyHolder().isEntity(); return !propertyHolder.isComponent() && !propertyHolder.isEntity();
} }
@Override @Override
@ -409,10 +395,6 @@ public class AnnotatedColumn {
} }
} }
public PropertyHolder getPropertyHolder() {
return getParent().getPropertyHolder();
}
protected void setMappingColumn(Column mappingColumn) { protected void setMappingColumn(Column mappingColumn) {
this.mappingColumn = mappingColumn; this.mappingColumn = mappingColumn;
} }
@ -450,7 +432,7 @@ public class AnnotatedColumn {
new ImplicitBasicColumnNameSource() { new ImplicitBasicColumnNameSource() {
@Override @Override
public AttributePath getAttributePath() { public AttributePath getAttributePath() {
return AttributePath.parse( propertyName ); return AttributePath.parse( getParent().getPropertyName() );
} }
@Override @Override
@ -470,27 +452,6 @@ public class AnnotatedColumn {
getBuildingContext().getMetadataCollector().addColumnNameBinding( value.getTable(), logicalColumnName, getMappingColumn() ); getBuildingContext().getMetadataCollector().addColumnNameBinding( value.getTable(), logicalColumnName, getMappingColumn() );
} }
/**
* Find appropriate table of the column.
* It can come from a secondary table or from the main table of the persistent class
*
* @return appropriate table
* @throws AnnotationException missing secondary table
*/
public Table getTable() {
return getParent().getTable();
}
//TODO: move to AnnotatedColumns
public boolean isSecondary() {
return getParent().isSecondary();
}
//TODO: move to AnnotatedColumns
public Join getJoin() {
return getParent().getJoin();
}
public void forceNotNull() { public void forceNotNull() {
if ( mappingColumn == null ) { if ( mappingColumn == null ) {
throw new CannotForceNonNullableException( throw new CannotForceNonNullableException(
@ -639,6 +600,7 @@ public class AnnotatedColumn {
if ( formulaAnn != null ) { if ( formulaAnn != null ) {
final AnnotatedColumns parent = new AnnotatedColumns(); final AnnotatedColumns parent = new AnnotatedColumns();
parent.setPropertyHolder( propertyHolder ); parent.setPropertyHolder( propertyHolder );
parent.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
parent.setBuildingContext( context ); parent.setBuildingContext( context );
parent.setJoins( secondaryTables ); //unnecessary parent.setJoins( secondaryTables ); //unnecessary
final AnnotatedColumn formulaColumn = new AnnotatedColumn(); final AnnotatedColumn formulaColumn = new AnnotatedColumn();
@ -681,15 +643,14 @@ public class AnnotatedColumn {
jakarta.persistence.Column[] columns, jakarta.persistence.Column[] columns,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
PropertyData inferredData ) { PropertyData inferredData ) {
final jakarta.persistence.Column[] overriddenCols = propertyHolder.getOverriddenColumn( final String path = getPath( propertyHolder, inferredData );
qualify( propertyHolder.getPath(), inferredData.getPropertyName() ) final jakarta.persistence.Column[] overriddenCols = propertyHolder.getOverriddenColumn( path );
);
if ( overriddenCols != null ) { if ( overriddenCols != null ) {
//check for overridden first //check for overridden first
if ( columns != null && overriddenCols.length != columns.length ) { if ( columns != null && overriddenCols.length != columns.length ) {
//TODO: unfortunately, we never actually see this nice error message, since //TODO: unfortunately, we never actually see this nice error message, since
// PersistentClass.validate() gets called first and produces a worse message // PersistentClass.validate() gets called first and produces a worse message
throw new AnnotationException( "Property '" + getPath( propertyHolder, inferredData ) throw new AnnotationException( "Property '" + path
+ "' specifies " + columns.length + "' specifies " + columns.length
+ " '@AttributeOverride's but the overridden property has " + overriddenCols.length + " '@AttributeOverride's but the overridden property has " + overriddenCols.length
+ " columns (every column must have exactly one '@AttributeOverride')" ); + " columns (every column must have exactly one '@AttributeOverride')" );
@ -712,6 +673,7 @@ public class AnnotatedColumn {
jakarta.persistence.Column[] actualCols) { jakarta.persistence.Column[] actualCols) {
final AnnotatedColumns parent = new AnnotatedColumns(); final AnnotatedColumns parent = new AnnotatedColumns();
parent.setPropertyHolder( propertyHolder ); parent.setPropertyHolder( propertyHolder );
parent.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
parent.setJoins( secondaryTables ); parent.setJoins( secondaryTables );
parent.setBuildingContext( context ); parent.setBuildingContext( context );
for ( jakarta.persistence.Column column : actualCols ) { for ( jakarta.persistence.Column column : actualCols ) {
@ -760,7 +722,7 @@ public class AnnotatedColumn {
jakarta.persistence.Column column, jakarta.persistence.Column column,
String sqlType, String sqlType,
String tableName) { String tableName) {
final String columnName = getLogicalColumnName( inferredData, suffixForDefaultColumnName, database, column ); final String columnName = logicalColumnName( inferredData, suffixForDefaultColumnName, database, column );
final AnnotatedColumn annotatedColumn = new AnnotatedColumn(); final AnnotatedColumn annotatedColumn = new AnnotatedColumn();
annotatedColumn.setLogicalColumnName( columnName ); annotatedColumn.setLogicalColumnName( columnName );
annotatedColumn.setImplicit( false ); annotatedColumn.setImplicit( false );
@ -769,7 +731,7 @@ public class AnnotatedColumn {
annotatedColumn.setPrecision( column.precision() ); annotatedColumn.setPrecision( column.precision() );
annotatedColumn.setScale( column.scale() ); annotatedColumn.setScale( column.scale() );
// annotatedColumn.setPropertyHolder( propertyHolder ); // annotatedColumn.setPropertyHolder( propertyHolder );
annotatedColumn.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) ); // annotatedColumn.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
annotatedColumn.setNullable( column.nullable() ); //TODO force to not null if available? This is a (bad) user choice. annotatedColumn.setNullable( column.nullable() ); //TODO force to not null if available? This is a (bad) user choice.
if ( comment != null ) { if ( comment != null ) {
annotatedColumn.setComment( comment.value() ); annotatedColumn.setComment( comment.value() );
@ -789,7 +751,7 @@ public class AnnotatedColumn {
return annotatedColumn; return annotatedColumn;
} }
private static String getLogicalColumnName( private static String logicalColumnName(
PropertyData inferredData, PropertyData inferredData,
String suffixForDefaultColumnName, String suffixForDefaultColumnName,
Database database, Database database,
@ -896,6 +858,7 @@ public class AnnotatedColumn {
MetadataBuildingContext context) { MetadataBuildingContext context) {
final AnnotatedColumns columns = new AnnotatedColumns(); final AnnotatedColumns columns = new AnnotatedColumns();
columns.setPropertyHolder( propertyHolder ); columns.setPropertyHolder( propertyHolder );
columns.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
columns.setBuildingContext( context ); columns.setBuildingContext( context );
columns.setJoins( secondaryTables ); columns.setJoins( secondaryTables );
columns.setPropertyHolder( propertyHolder ); columns.setPropertyHolder( propertyHolder );
@ -911,7 +874,7 @@ public class AnnotatedColumn {
} }
final String propertyName = inferredData.getPropertyName(); final String propertyName = inferredData.getPropertyName();
// column.setPropertyHolder( propertyHolder ); // column.setPropertyHolder( propertyHolder );
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); // column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
// column.setJoins( secondaryTables ); // column.setJoins( secondaryTables );
// column.setBuildingContext( context ); // column.setBuildingContext( context );
// property name + suffix is an "explicit" column name // property name + suffix is an "explicit" column name
@ -929,37 +892,6 @@ public class AnnotatedColumn {
return columns; return columns;
} }
public static void checkPropertyConsistency(List<AnnotatedColumn> columns, String propertyName) {
if ( columns.size() > 1 ) {
for ( int currentIndex = 1; currentIndex < columns.size(); currentIndex++ ) {
final AnnotatedColumn current = columns.get( currentIndex );
final AnnotatedColumn previous = columns.get( currentIndex - 1 );
if ( !current.isFormula() && !previous.isFormula() ) {
if ( current.isNullable() != previous.isNullable() ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix nullable with 'not null'"
);
}
if ( current.isInsertable() != previous.isInsertable() ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix insertable with 'insertable=false'"
);
}
if ( current.isUpdatable() != previous.isUpdatable() ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix updatable with 'updatable=false'"
);
}
if ( !current.getExplicitTableName().equals( previous.getExplicitTableName() ) ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix distinct secondary tables"
);
}
}
}
}
}
public void addIndex(Index index, boolean inSecondPass) { public void addIndex(Index index, boolean inSecondPass) {
if ( index != null ) { if ( index != null ) {
addIndex( index.name(), inSecondPass ); addIndex( index.name(), inSecondPass );

View File

@ -1,7 +1,6 @@
package org.hibernate.cfg; package org.hibernate.cfg;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.mapping.Join; import org.hibernate.mapping.Join;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
@ -32,6 +31,7 @@ public class AnnotatedColumns {
private final List<AnnotatedColumn> columns = new ArrayList<>(); private final List<AnnotatedColumn> columns = new ArrayList<>();
private Table table; private Table table;
private PropertyHolder propertyHolder; private PropertyHolder propertyHolder;
private String propertyName; // this is really a .-separated property path
private Map<String, Join> joins = Collections.emptyMap(); private Map<String, Join> joins = Collections.emptyMap();
private MetadataBuildingContext buildingContext; private MetadataBuildingContext buildingContext;
@ -47,6 +47,17 @@ public class AnnotatedColumns {
this.propertyHolder = propertyHolder; this.propertyHolder = propertyHolder;
} }
/**
* A property path relative to the {@link #getPropertyHolder() PropertyHolder}.
*/
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public void setBuildingContext(MetadataBuildingContext buildingContext) { public void setBuildingContext(MetadataBuildingContext buildingContext) {
this.buildingContext = buildingContext; this.buildingContext = buildingContext;
} }
@ -62,6 +73,7 @@ public class AnnotatedColumns {
public Join getJoin() { public Join getJoin() {
final AnnotatedColumn firstColumn = columns.get(0); final AnnotatedColumn firstColumn = columns.get(0);
final String explicitTableName = firstColumn.getExplicitTableName(); final String explicitTableName = firstColumn.getExplicitTableName();
//note: checkPropertyConsistency() is responsible for ensuring they all have the same table name
Join join = joins.get( explicitTableName ); Join join = joins.get( explicitTableName );
if ( join == null ) { if ( join == null ) {
// annotation binding seems to use logical and physical naming somewhat inconsistently... // annotation binding seems to use logical and physical naming somewhat inconsistently...
@ -77,19 +89,27 @@ public class AnnotatedColumns {
+ "' is not declared (use '@SecondaryTable' to declare the secondary table)" + "' is not declared (use '@SecondaryTable' to declare the secondary table)"
); );
} }
else {
return join; return join;
} }
}
public boolean isSecondary() { public boolean isSecondary() {
if ( getPropertyHolder() == null ) {
throw new AssertionFailure( "Should not call isSecondary() on column w/o persistent class defined" );
}
final AnnotatedColumn firstColumn = columns.get(0); final AnnotatedColumn firstColumn = columns.get(0);
final String explicitTableName = firstColumn.getExplicitTableName(); final String explicitTableName = firstColumn.getExplicitTableName();
//note: checkPropertyConsistency() is responsible for ensuring they all have the same table name
return isNotEmpty( explicitTableName ) return isNotEmpty( explicitTableName )
&& !getPropertyHolder().getTable().getName().equals( explicitTableName ); && !getPropertyHolder().getTable().getName().equals( explicitTableName );
} }
/**
* Find the table to which these columns belong, taking into account secondary tables.
*
* @return the {@link Table} given in the code by {@link jakarta.persistence.Column#table()}
* and held here by {@code explicitTableName}.
* @throws AnnotationException if the table named by {@code explicitTableName} is not found
* among the secondary tables in {@code joins}.
*/
public Table getTable() { public Table getTable() {
if ( table != null ) { if ( table != null ) {
return table; return table;
@ -98,8 +118,7 @@ public class AnnotatedColumns {
// all the columns have to be mapped to the same table // all the columns have to be mapped to the same table
// even though at the annotation level it looks like // even though at the annotation level it looks like
// they could each specify a different table // they could each specify a different table
final AnnotatedColumn firstColumn = columns.get(0); return isSecondary() ? getJoin().getTable() : getPropertyHolder().getTable();
return firstColumn.isSecondary() ? getJoin().getTable() : getPropertyHolder().getTable();
} }
} }
@ -115,4 +134,35 @@ public class AnnotatedColumns {
public void addColumn(AnnotatedColumn child) { public void addColumn(AnnotatedColumn child) {
columns.add( child ); columns.add( child );
} }
public void checkPropertyConsistency() {
if ( columns.size() > 1 ) {
for ( int currentIndex = 1; currentIndex < columns.size(); currentIndex++ ) {
final AnnotatedColumn current = columns.get( currentIndex );
final AnnotatedColumn previous = columns.get( currentIndex - 1 );
if ( !current.isFormula() && !previous.isFormula() ) {
if ( current.isNullable() != previous.isNullable() ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix nullable with 'not null'"
);
}
if ( current.isInsertable() != previous.isInsertable() ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix insertable with 'insertable=false'"
);
}
if ( current.isUpdatable() != previous.isUpdatable() ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix updatable with 'updatable=false'"
);
}
if ( !current.getExplicitTableName().equals( previous.getExplicitTableName() ) ) {
throw new AnnotationException(
"Column mappings for property '" + propertyName + "' mix distinct secondary tables"
);
}
}
}
}
}
} }

View File

@ -95,15 +95,13 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
public static AnnotatedJoinColumn buildJoinFormula( public static AnnotatedJoinColumn buildJoinFormula(
JoinFormula joinFormula, JoinFormula joinFormula,
AnnotatedJoinColumns parent, AnnotatedJoinColumns parent) {
PropertyHolder propertyHolder,
String propertyName) {
final AnnotatedJoinColumn formulaColumn = new AnnotatedJoinColumn(); final AnnotatedJoinColumn formulaColumn = new AnnotatedJoinColumn();
formulaColumn.setFormula( joinFormula.value() ); formulaColumn.setFormula( joinFormula.value() );
formulaColumn.setReferencedColumn( joinFormula.referencedColumnName() ); formulaColumn.setReferencedColumn( joinFormula.referencedColumnName() );
// formulaColumn.setContext( buildingContext ); // formulaColumn.setContext( buildingContext );
// formulaColumn.setPropertyHolder( propertyHolder ); // formulaColumn.setPropertyHolder( propertyHolder );
formulaColumn.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); // formulaColumn.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
// formulaColumn.setJoins( joins ); // formulaColumn.setJoins( joins );
formulaColumn.setParent( parent ); formulaColumn.setParent( parent );
formulaColumn.bind(); formulaColumn.bind();
@ -125,10 +123,10 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
+ "' is 'mappedBy' a different entity and may not explicitly specify the '@JoinColumn'" + "' is 'mappedBy' a different entity and may not explicitly specify the '@JoinColumn'"
); );
} }
return explicitJoinColumn( joinColumn, comment, parent, propertyHolder, propertyName, defaultColumnSuffix ); return explicitJoinColumn( joinColumn, comment, parent, propertyName, defaultColumnSuffix );
} }
else { else {
return implicitJoinColumn( parent, propertyHolder, propertyName, defaultColumnSuffix ); return implicitJoinColumn( parent, propertyName, defaultColumnSuffix );
} }
} }
@ -136,7 +134,6 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
JoinColumn joinColumn, JoinColumn joinColumn,
Comment comment, Comment comment,
AnnotatedJoinColumns parent, AnnotatedJoinColumns parent,
PropertyHolder propertyHolder,
String propertyName, String propertyName,
String defaultColumnSuffix) { String defaultColumnSuffix) {
final AnnotatedJoinColumn column = new AnnotatedJoinColumn(); final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
@ -147,7 +144,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
if ( isEmpty( column.getLogicalColumnName() ) && isNotEmpty( defaultColumnSuffix ) ) { if ( isEmpty( column.getLogicalColumnName() ) && isNotEmpty( defaultColumnSuffix ) ) {
column.setLogicalColumnName( propertyName + defaultColumnSuffix ); column.setLogicalColumnName( propertyName + defaultColumnSuffix );
} }
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); // column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
column.setImplicit( false ); column.setImplicit( false );
column.setParent( parent ); column.setParent( parent );
column.applyJoinAnnotation( joinColumn, null ); column.applyJoinAnnotation( joinColumn, null );
@ -157,14 +154,13 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
private static AnnotatedJoinColumn implicitJoinColumn( private static AnnotatedJoinColumn implicitJoinColumn(
AnnotatedJoinColumns parent, AnnotatedJoinColumns parent,
PropertyHolder propertyHolder,
String propertyName, String propertyName,
String defaultColumnSuffix) { String defaultColumnSuffix) {
final AnnotatedJoinColumn column = new AnnotatedJoinColumn(); final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
// column.setContext( context ); // column.setContext( context );
// column.setJoins( joins ); // column.setJoins( joins );
// column.setPropertyHolder( propertyHolder ); // column.setPropertyHolder( propertyHolder );
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); // column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
// property name + suffix is an "explicit" column name // property name + suffix is an "explicit" column name
if ( isNotEmpty( defaultColumnSuffix ) ) { if ( isNotEmpty( defaultColumnSuffix ) ) {
column.setLogicalColumnName( propertyName + defaultColumnSuffix ); column.setLogicalColumnName( propertyName + defaultColumnSuffix );
@ -370,7 +366,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
final String unquotedRefColumn = unquote( referencedColumn ); final String unquotedRefColumn = unquote( referencedColumn );
final String collectionColName = isNotEmpty( unquotedLogColName ) final String collectionColName = isNotEmpty( unquotedLogColName )
? unquotedLogColName ? unquotedLogColName
: getPropertyName() + '_' + unquotedRefColumn; : getParent().getPropertyName() + '_' + unquotedRefColumn;
final InFlightMetadataCollector collector = getBuildingContext().getMetadataCollector(); final InFlightMetadataCollector collector = getBuildingContext().getMetadataCollector();
final String logicalCollectionColumnName = collector.getDatabase() final String logicalCollectionColumnName = collector.getDatabase()
.getJdbcEnvironment() .getJdbcEnvironment()
@ -490,7 +486,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
column.setImplicit( true ); column.setImplicit( true );
column.setNullable( false ); //I break the spec, but it's for good column.setNullable( false ); //I break the spec, but it's for good
// column.setPropertyHolder( propertyHolder ); // column.setPropertyHolder( propertyHolder );
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); // column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
// column.setJoins( secondaryTables ); // column.setJoins( secondaryTables );
// column.setContext( context ); // column.setContext( context );
column.setParent( parent ); column.setParent( parent );
@ -506,7 +502,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
final AnnotatedJoinColumn column = new AnnotatedJoinColumn(); final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
column.setImplicit( true ); column.setImplicit( true );
// column.setPropertyHolder( propertyHolder ); // column.setPropertyHolder( propertyHolder );
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); // column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
// column.setJoins( secondaryTables ); // column.setJoins( secondaryTables );
// column.setContext( context ); // column.setContext( context );
column.setNullable( false ); //I break the spec, but it's for good column.setNullable( false ); //I break the spec, but it's for good

View File

@ -78,7 +78,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
final JoinFormula formula = columnOrFormula.formula(); final JoinFormula formula = columnOrFormula.formula();
final JoinColumn column = columnOrFormula.column(); final JoinColumn column = columnOrFormula.column();
if ( !isEmptyOrNullAnnotationValue( formula.value() ) ) { if ( !isEmptyOrNullAnnotationValue( formula.value() ) ) {
AnnotatedJoinColumn.buildJoinFormula( formula, parent, propertyHolder, propertyName ); AnnotatedJoinColumn.buildJoinFormula( formula, parent );
} }
else { else {
AnnotatedJoinColumn.buildJoinColumn( column, mappedBy, parent, propertyHolder, propertyName ); AnnotatedJoinColumn.buildJoinColumn( column, mappedBy, parent, propertyHolder, propertyName );
@ -87,6 +87,21 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
return parent; return parent;
} }
static AnnotatedJoinColumns buildJoinColumnsWithFormula(
String propertyName,
JoinFormula joinFormula,
Map<String, Join> secondaryTables,
PropertyHolder propertyHolder,
MetadataBuildingContext context) {
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
joinColumns.setBuildingContext( context );
joinColumns.setJoins( secondaryTables );
joinColumns.setPropertyHolder( propertyHolder );
joinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
AnnotatedJoinColumn.buildJoinFormula( joinFormula, joinColumns );
return joinColumns;
}
public static AnnotatedJoinColumns buildJoinColumns( public static AnnotatedJoinColumns buildJoinColumns(
JoinColumn[] joinColumns, JoinColumn[] joinColumns,
Comment comment, Comment comment,

View File

@ -1640,14 +1640,14 @@ public final class AnnotationBinder {
final NaturalId naturalIdAnn = property.getAnnotation( NaturalId.class ); final NaturalId naturalIdAnn = property.getAnnotation( NaturalId.class );
if ( naturalIdAnn != null ) { if ( naturalIdAnn != null ) {
if ( joinColumns != null ) { if ( joinColumns != null ) {
String keyName = "UK_" + Constraint.hashedName( joinColumns.getTable().getName() + "_NaturalID" );
for ( AnnotatedColumn column : joinColumns.getColumns() ) { for ( AnnotatedColumn column : joinColumns.getColumns() ) {
String keyName = "UK_" + Constraint.hashedName( column.getTable().getName() + "_NaturalID" );
column.addUniqueKey( keyName, inSecondPass ); column.addUniqueKey( keyName, inSecondPass );
} }
} }
else { else {
String keyName = "UK_" + Constraint.hashedName( columns.getTable().getName() + "_NaturalID" );
for ( AnnotatedColumn column : columns.getColumns() ) { for ( AnnotatedColumn column : columns.getColumns() ) {
String keyName = "UK_" + Constraint.hashedName( column.getTable().getName() + "_NaturalID" );
column.addUniqueKey( keyName, inSecondPass ); column.addUniqueKey( keyName, inSecondPass );
} }
} }

View File

@ -1111,8 +1111,7 @@ public class BinderHelper {
final BasicValue keyDescriptor = keyValueBinder.make(); final BasicValue keyDescriptor = keyValueBinder.make();
value.setKey( keyDescriptor ); value.setKey( keyDescriptor );
keyValueBinder.fillSimpleValue(); keyValueBinder.fillSimpleValue();
final String path = qualify( propertyHolder.getEntityName(), inferredData.getPropertyName() ); keyColumns.checkPropertyConsistency();
AnnotatedColumn.checkPropertyConsistency( keyColumns.getColumns(), path );
columns.get(0).linkWithValue( keyDescriptor ); //TODO: nasty columns.get(0).linkWithValue( keyDescriptor ); //TODO: nasty
return value; return value;
} }

View File

@ -5,6 +5,7 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/ */
package org.hibernate.cfg; package org.hibernate.cfg;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection; import jakarta.persistence.ElementCollection;
import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinColumn;
@ -34,7 +35,6 @@ import static org.hibernate.cfg.AnnotatedColumn.buildFormulaFromAnnotation;
import static org.hibernate.cfg.BinderHelper.getOverridableAnnotation; import static org.hibernate.cfg.BinderHelper.getOverridableAnnotation;
import static org.hibernate.cfg.BinderHelper.getPath; import static org.hibernate.cfg.BinderHelper.getPath;
import static org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId; import static org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId;
import static org.hibernate.cfg.BinderHelper.getRelativePath;
import static org.hibernate.internal.util.StringHelper.isEmpty; import static org.hibernate.internal.util.StringHelper.isEmpty;
/** /**
@ -202,7 +202,6 @@ class ColumnsBuilder {
private AnnotatedJoinColumns buildExplicitJoinColumns(XProperty property, PropertyData inferredData) { private AnnotatedJoinColumns buildExplicitJoinColumns(XProperty property, PropertyData inferredData) {
// process @JoinColumns before @Columns to handle collection of entities properly // process @JoinColumns before @Columns to handle collection of entities properly
final String propertyName = inferredData.getPropertyName(); final String propertyName = inferredData.getPropertyName();
final JoinColumn[] joinColumnAnnotations = getJoinColumnAnnotations( property, inferredData ); final JoinColumn[] joinColumnAnnotations = getJoinColumnAnnotations( property, inferredData );
@ -232,22 +231,18 @@ class ColumnsBuilder {
if ( property.isAnnotationPresent( JoinFormula.class) ) { if ( property.isAnnotationPresent( JoinFormula.class) ) {
final JoinFormula joinFormula = getOverridableAnnotation( property, JoinFormula.class, buildingContext ); final JoinFormula joinFormula = getOverridableAnnotation( property, JoinFormula.class, buildingContext );
return buildJoinColumnsWithFormula( propertyName, joinFormula ); return AnnotatedJoinColumns.buildJoinColumnsWithFormula(
propertyName,
joinFormula,
entityBinder.getSecondaryTables(),
propertyHolder,
buildingContext
);
} }
return null; return null;
} }
private AnnotatedJoinColumns buildJoinColumnsWithFormula(String propertyName, JoinFormula joinFormula) {
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
joinColumns.setBuildingContext( buildingContext );
joinColumns.setJoins( entityBinder.getSecondaryTables() );
joinColumns.setPropertyHolder( propertyHolder );
joinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
AnnotatedJoinColumn.buildJoinFormula( joinFormula, joinColumns, propertyHolder, propertyName );
return joinColumns;
}
private JoinColumnOrFormula[] joinColumnOrFormulaAnnotations(XProperty property, PropertyData inferredData) { private JoinColumnOrFormula[] joinColumnOrFormulaAnnotations(XProperty property, PropertyData inferredData) {
if ( property.isAnnotationPresent( JoinColumnOrFormula.class ) ) { if ( property.isAnnotationPresent( JoinColumnOrFormula.class ) ) {
return new JoinColumnOrFormula[] { property.getAnnotation( JoinColumnOrFormula.class ) }; return new JoinColumnOrFormula[] { property.getAnnotation( JoinColumnOrFormula.class ) };

View File

@ -64,16 +64,13 @@ public class IndexOrUniqueKeySecondPass implements SecondPass {
} }
} }
if ( column != null ) { if ( column != null ) {
table = column.getTable(); table = column.getParent().getTable();
final PropertyHolder propertyHolder = column.getParent().getPropertyHolder();
final PropertyHolder propertyHolder = column.getPropertyHolder(); final String entityName = propertyHolder.isComponent()
final String entityName = ( propertyHolder.isComponent() ) ? ? propertyHolder.getPersistentClass().getEntityName()
propertyHolder.getPersistentClass().getEntityName() : : propertyHolder.getEntityName();
propertyHolder.getEntityName();
final PersistentClass persistentClass = persistentClasses.get( entityName ); final PersistentClass persistentClass = persistentClasses.get( entityName );
final Property property = persistentClass.getProperty( column.getPropertyName() ); final Property property = persistentClass.getProperty( column.getParent().getPropertyName() );
if ( property.getValue() instanceof Component ) { if ( property.getValue() instanceof Component ) {
final Component component = (Component) property.getValue(); final Component component = (Component) property.getValue();
final List<Column> columns = new ArrayList<>(); final List<Column> columns = new ArrayList<>();

View File

@ -45,7 +45,6 @@ import org.hibernate.mapping.ToOne;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.hibernate.cfg.AnnotatedColumn.checkPropertyConsistency;
import static org.hibernate.cfg.AnnotationBinder.matchIgnoreNotFoundWithFetchType; import static org.hibernate.cfg.AnnotationBinder.matchIgnoreNotFoundWithFetchType;
import static org.hibernate.cfg.BinderHelper.getCascadeStrategy; import static org.hibernate.cfg.BinderHelper.getCascadeStrategy;
import static org.hibernate.cfg.BinderHelper.getFetchMode; import static org.hibernate.cfg.BinderHelper.getFetchMode;
@ -196,7 +195,6 @@ public class ToOneBinder {
cascadeStrategy, cascadeStrategy,
joinColumns, joinColumns,
optional, optional,
propertyHolder,
inferredData, inferredData,
isIdentifierMapper, isIdentifierMapper,
propertyBinder, propertyBinder,
@ -242,7 +240,6 @@ public class ToOneBinder {
String cascadeStrategy, String cascadeStrategy,
AnnotatedJoinColumns columns, AnnotatedJoinColumns columns,
boolean optional, boolean optional,
PropertyHolder propertyHolder,
PropertyData inferredData, PropertyData inferredData,
boolean isIdentifierMapper, boolean isIdentifierMapper,
PropertyBinder propertyBinder, PropertyBinder propertyBinder,
@ -250,7 +247,7 @@ public class ToOneBinder {
boolean hasSpecjManyToOne, boolean hasSpecjManyToOne,
String propertyName) { String propertyName) {
checkPropertyConsistency( columns.getColumns(), qualify( propertyHolder.getEntityName(), propertyName ) ); columns.checkPropertyConsistency();
//PropertyBinder binder = new PropertyBinder(); //PropertyBinder binder = new PropertyBinder();
propertyBinder.setName( propertyName ); propertyBinder.setName( propertyName );

View File

@ -1069,16 +1069,12 @@ public class BasicValueBinder implements JdbcTypeIndicators {
this.explicitBasicTypeName = explicitType; this.explicitBasicTypeName = explicitType;
} }
private void validate() {
AnnotatedColumn.checkPropertyConsistency( columns.getColumns(), propertyName );
}
public BasicValue make() { public BasicValue make() {
if ( basicValue != null ) { if ( basicValue != null ) {
return basicValue; return basicValue;
} }
validate(); columns.checkPropertyConsistency();
LOG.debugf( "building BasicValue for %s", propertyName ); LOG.debugf( "building BasicValue for %s", propertyName );
@ -1130,7 +1126,7 @@ public class BasicValueBinder implements JdbcTypeIndicators {
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns(); final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
joinColumns.setBuildingContext( buildingContext ); joinColumns.setBuildingContext( buildingContext );
joinColumns.setPropertyHolder( columns.getPropertyHolder() ); joinColumns.setPropertyHolder( columns.getPropertyHolder() );
joinColumns.setPropertyName( firstColumn.getPropertyName() ); joinColumns.setPropertyName( columns.getPropertyName() );
//TODO: resetting the parent here looks like a dangerous thing to do //TODO: resetting the parent here looks like a dangerous thing to do
// should we be cloning them first (the legacy code did not) // should we be cloning them first (the legacy code did not)
for ( AnnotatedColumn column : columns.getColumns() ) { for ( AnnotatedColumn column : columns.getColumns() ) {

View File

@ -154,7 +154,6 @@ import static org.hibernate.cfg.AnnotatedColumn.buildColumnFromAnnotation;
import static org.hibernate.cfg.AnnotatedColumn.buildColumnFromNoAnnotation; import static org.hibernate.cfg.AnnotatedColumn.buildColumnFromNoAnnotation;
import static org.hibernate.cfg.AnnotatedColumn.buildColumnsFromAnnotations; import static org.hibernate.cfg.AnnotatedColumn.buildColumnsFromAnnotations;
import static org.hibernate.cfg.AnnotatedColumn.buildFormulaFromAnnotation; import static org.hibernate.cfg.AnnotatedColumn.buildFormulaFromAnnotation;
import static org.hibernate.cfg.AnnotatedColumn.checkPropertyConsistency;
import static org.hibernate.cfg.AnnotatedJoinColumns.buildJoinColumnsWithDefaultColumnSuffix; import static org.hibernate.cfg.AnnotatedJoinColumns.buildJoinColumnsWithDefaultColumnSuffix;
import static org.hibernate.cfg.AnnotatedJoinColumns.buildJoinTableJoinColumns; import static org.hibernate.cfg.AnnotatedJoinColumns.buildJoinTableJoinColumns;
import static org.hibernate.cfg.AnnotationBinder.fillComponent; import static org.hibernate.cfg.AnnotationBinder.fillComponent;
@ -417,12 +416,10 @@ public abstract class CollectionBinder {
final String mappedBy; final String mappedBy;
final ReflectionManager reflectionManager = context.getBootstrapContext().getReflectionManager(); final ReflectionManager reflectionManager = context.getBootstrapContext().getReflectionManager();
if ( oneToManyAnn != null ) { if ( oneToManyAnn != null ) {
for ( AnnotatedJoinColumn column : joinColumns.getJoinColumns() ) { if ( joinColumns.isSecondary() ) {
if ( column.isSecondary() ) {
//TODO: fix the error message //TODO: fix the error message
throw new NotYetImplementedException( "Collections having FK in secondary table" ); throw new NotYetImplementedException( "Collections having FK in secondary table" );
} }
}
collectionBinder.setFkJoinColumns( joinColumns ); collectionBinder.setFkJoinColumns( joinColumns );
mappedBy = oneToManyAnn.mappedBy(); mappedBy = oneToManyAnn.mappedBy();
//noinspection unchecked //noinspection unchecked
@ -433,12 +430,10 @@ public abstract class CollectionBinder {
collectionBinder.setOneToMany( true ); collectionBinder.setOneToMany( true );
} }
else if ( elementCollectionAnn != null ) { else if ( elementCollectionAnn != null ) {
for ( AnnotatedJoinColumn column : joinColumns.getJoinColumns() ) { if ( joinColumns.isSecondary() ) {
if ( column.isSecondary() ) {
//TODO: fix the error message //TODO: fix the error message
throw new NotYetImplementedException( "Collections having FK in secondary table" ); throw new NotYetImplementedException( "Collections having FK in secondary table" );
} }
}
collectionBinder.setFkJoinColumns( joinColumns ); collectionBinder.setFkJoinColumns( joinColumns );
mappedBy = ""; mappedBy = "";
final Class<?> targetElement = elementCollectionAnn.targetClass(); final Class<?> targetElement = elementCollectionAnn.targetClass();
@ -1852,8 +1847,8 @@ public abstract class CollectionBinder {
final DependantValue key = new DependantValue( buildingContext, collection.getCollectionTable(), keyValue ); final DependantValue key = new DependantValue( buildingContext, collection.getCollectionTable(), keyValue );
key.setTypeName( null ); key.setTypeName( null );
joinColumns.checkPropertyConsistency();
final List<AnnotatedColumn> columns = joinColumns.getColumns(); final List<AnnotatedColumn> columns = joinColumns.getColumns();
checkPropertyConsistency( columns, collection.getOwnerEntityName() );
key.setNullable( columns.isEmpty() || columns.get(0).isNullable() ); key.setNullable( columns.isEmpty() || columns.get(0).isNullable() );
key.setUpdateable( columns.isEmpty() || columns.get(0).isUpdatable() ); key.setUpdateable( columns.isEmpty() || columns.get(0).isUpdatable() );
key.setCascadeDeleteEnabled( cascadeDeleteEnabled ); key.setCascadeDeleteEnabled( cascadeDeleteEnabled );