finally move context + joins from AnnotatedColumn
This commit is contained in:
parent
18003b92dc
commit
e4c1d493e3
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
package org.hibernate.cfg;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.annotations.Check;
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
|
@ -65,13 +65,10 @@ public class AnnotatedColumn {
|
|||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, AnnotatedColumn.class.getName());
|
||||
|
||||
private MetadataBuildingContext context;
|
||||
|
||||
private Column mappingColumn;
|
||||
private boolean insertable = true;
|
||||
private boolean updatable = true;
|
||||
private String explicitTableName; // the JPA @Column annotation lets you specify a table name
|
||||
protected Map<String, Join> joins;
|
||||
private boolean isImplicit;
|
||||
public String sqlType;
|
||||
private Long length;
|
||||
|
@ -94,7 +91,12 @@ public class AnnotatedColumn {
|
|||
|
||||
private AnnotatedColumns parent;
|
||||
|
||||
void setParent(AnnotatedColumns parent) {
|
||||
public AnnotatedColumns getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(AnnotatedColumns parent) {
|
||||
parent.addColumn( this );
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
@ -154,14 +156,6 @@ public class AnnotatedColumn {
|
|||
this.updatable = updatable;
|
||||
}
|
||||
|
||||
protected MetadataBuildingContext getBuildingContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setBuildingContext(MetadataBuildingContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void setImplicit(boolean implicit) {
|
||||
isImplicit = implicit;
|
||||
}
|
||||
|
@ -337,21 +331,21 @@ public class AnnotatedColumn {
|
|||
|
||||
private String processColumnName(String columnName, boolean applyNamingStrategy) {
|
||||
if ( applyNamingStrategy ) {
|
||||
final Database database = context.getMetadataCollector().getDatabase();
|
||||
return context.getBuildingOptions().getPhysicalNamingStrategy()
|
||||
final Database database = getBuildingContext().getMetadataCollector().getDatabase();
|
||||
return getBuildingContext().getBuildingOptions().getPhysicalNamingStrategy()
|
||||
.toPhysicalColumnName( database.toIdentifier( columnName ), database.getJdbcEnvironment() )
|
||||
.render( database.getDialect() );
|
||||
}
|
||||
else {
|
||||
return context.getObjectNameNormalizer().toDatabaseIdentifierText( columnName );
|
||||
return getBuildingContext().getObjectNameNormalizer().toDatabaseIdentifierText( columnName );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String inferColumnName(String propertyName) {
|
||||
final Database database = context.getMetadataCollector().getDatabase();
|
||||
final ObjectNameNormalizer normalizer = context.getObjectNameNormalizer();
|
||||
final ImplicitNamingStrategy implicitNamingStrategy = context.getBuildingOptions().getImplicitNamingStrategy();
|
||||
final Database database = getBuildingContext().getMetadataCollector().getDatabase();
|
||||
final ObjectNameNormalizer normalizer = getBuildingContext().getObjectNameNormalizer();
|
||||
final ImplicitNamingStrategy implicitNamingStrategy = getBuildingContext().getBuildingOptions().getImplicitNamingStrategy();
|
||||
|
||||
Identifier implicitName = normalizer.normalizeIdentifierQuoting(
|
||||
implicitNamingStrategy.determineBasicColumnName(
|
||||
|
@ -373,7 +367,7 @@ public class AnnotatedColumn {
|
|||
|
||||
@Override
|
||||
public MetadataBuildingContext getBuildingContext() {
|
||||
return context;
|
||||
return AnnotatedColumn.this.getBuildingContext();
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -387,7 +381,7 @@ public class AnnotatedColumn {
|
|||
);
|
||||
}
|
||||
|
||||
return context.getBuildingOptions().getPhysicalNamingStrategy()
|
||||
return getBuildingContext().getBuildingOptions().getPhysicalNamingStrategy()
|
||||
.toPhysicalColumnName( implicitName, database.getJdbcEnvironment() )
|
||||
.render( database.getDialect() );
|
||||
}
|
||||
|
@ -409,20 +403,14 @@ public class AnnotatedColumn {
|
|||
}
|
||||
|
||||
public void setNullable(boolean nullable) {
|
||||
this.nullable = nullable;
|
||||
if ( mappingColumn != null ) {
|
||||
mappingColumn.setNullable( nullable );
|
||||
}
|
||||
else {
|
||||
this.nullable = nullable;
|
||||
}
|
||||
}
|
||||
|
||||
public void setJoins(Map<String, Join> joins) {
|
||||
this.joins = joins;
|
||||
}
|
||||
|
||||
public PropertyHolder getPropertyHolder() {
|
||||
return parent.getPropertyHolder();
|
||||
return getParent().getPropertyHolder();
|
||||
}
|
||||
|
||||
protected void setMappingColumn(Column mappingColumn) {
|
||||
|
@ -436,8 +424,8 @@ public class AnnotatedColumn {
|
|||
}
|
||||
else {
|
||||
final Table table = value.getTable();
|
||||
if ( parent != null ) {
|
||||
parent.setTableInternal( table );
|
||||
if ( getParent() != null ) {
|
||||
getParent().setTableInternal( table );
|
||||
}
|
||||
getMappingColumn().setValue( value );
|
||||
value.addColumn( getMappingColumn(), insertable, updatable );
|
||||
|
@ -452,9 +440,9 @@ public class AnnotatedColumn {
|
|||
logicalColumnName = this.logicalColumnName;
|
||||
}
|
||||
else {
|
||||
final ObjectNameNormalizer normalizer = context.getObjectNameNormalizer();
|
||||
final Database database = context.getMetadataCollector().getDatabase();
|
||||
final ImplicitNamingStrategy implicitNamingStrategy = context.getBuildingOptions()
|
||||
final ObjectNameNormalizer normalizer = getBuildingContext().getObjectNameNormalizer();
|
||||
final Database database = getBuildingContext().getMetadataCollector().getDatabase();
|
||||
final ImplicitNamingStrategy implicitNamingStrategy = getBuildingContext().getBuildingOptions()
|
||||
.getImplicitNamingStrategy();
|
||||
|
||||
final Identifier implicitName = normalizer.normalizeIdentifierQuoting(
|
||||
|
@ -472,14 +460,14 @@ public class AnnotatedColumn {
|
|||
|
||||
@Override
|
||||
public MetadataBuildingContext getBuildingContext() {
|
||||
return context;
|
||||
return AnnotatedColumn.this.getBuildingContext();
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
logicalColumnName = implicitName.render( database.getDialect() );
|
||||
}
|
||||
context.getMetadataCollector().addColumnNameBinding( value.getTable(), logicalColumnName, getMappingColumn() );
|
||||
getBuildingContext().getMetadataCollector().addColumnNameBinding( value.getTable(), logicalColumnName, getMappingColumn() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -490,38 +478,17 @@ public class AnnotatedColumn {
|
|||
* @throws AnnotationException missing secondary table
|
||||
*/
|
||||
public Table getTable() {
|
||||
return parent.getTable();
|
||||
return getParent().getTable();
|
||||
}
|
||||
|
||||
//TODO: move to AnnotatedColumns
|
||||
public boolean isSecondary() {
|
||||
if ( getPropertyHolder() == null ) {
|
||||
throw new AssertionFailure( "Should not call isSecondary() on column w/o persistent class defined" );
|
||||
}
|
||||
return isNotEmpty( explicitTableName )
|
||||
&& !getPropertyHolder().getTable().getName().equals( explicitTableName );
|
||||
return getParent().isSecondary();
|
||||
}
|
||||
|
||||
//TODO: move to AnnotatedColumns
|
||||
public Join getJoin() {
|
||||
Join join = joins.get( explicitTableName );
|
||||
if ( join == null ) {
|
||||
// annotation binding seems to use logical and physical naming somewhat inconsistently...
|
||||
final String physicalTableName = getBuildingContext().getMetadataCollector()
|
||||
.getPhysicalTableName( explicitTableName );
|
||||
if ( physicalTableName != null ) {
|
||||
join = joins.get( physicalTableName );
|
||||
}
|
||||
}
|
||||
|
||||
if ( join == null ) {
|
||||
throw new AnnotationException(
|
||||
"Secondary table '" + explicitTableName + "' for property '" + getPropertyHolder().getClassName()
|
||||
+ "' is not declared (use '@SecondaryTable' to declare the secondary table)"
|
||||
);
|
||||
}
|
||||
|
||||
return join;
|
||||
return getParent().getJoin();
|
||||
}
|
||||
|
||||
public void forceNotNull() {
|
||||
|
@ -531,6 +498,7 @@ public class AnnotatedColumn {
|
|||
"likely a formula"
|
||||
);
|
||||
}
|
||||
nullable = false;
|
||||
mappingColumn.setNullable( false );
|
||||
}
|
||||
|
||||
|
@ -669,16 +637,18 @@ public class AnnotatedColumn {
|
|||
MetadataBuildingContext context) {
|
||||
|
||||
if ( formulaAnn != null ) {
|
||||
AnnotatedColumn formulaColumn = new AnnotatedColumn();
|
||||
final AnnotatedColumns parent = new AnnotatedColumns();
|
||||
parent.setPropertyHolder( propertyHolder );
|
||||
parent.setBuildingContext( context );
|
||||
parent.setJoins( secondaryTables ); //unnecessary
|
||||
final AnnotatedColumn formulaColumn = new AnnotatedColumn();
|
||||
formulaColumn.setFormula( formulaAnn.value() );
|
||||
formulaColumn.setImplicit( false );
|
||||
formulaColumn.setBuildingContext( context );
|
||||
// formulaColumn.setBuildingContext( context );
|
||||
// formulaColumn.setPropertyHolder( propertyHolder );
|
||||
final AnnotatedColumns result = new AnnotatedColumns();
|
||||
result.setPropertyHolder( propertyHolder );
|
||||
result.setColumns( new AnnotatedColumn[] {formulaColumn} );
|
||||
formulaColumn.setParent( parent );
|
||||
formulaColumn.bind();
|
||||
return result;
|
||||
return parent;
|
||||
}
|
||||
else {
|
||||
final jakarta.persistence.Column[] actualColumns = overrideColumns( columns, propertyHolder, inferredData );
|
||||
|
@ -740,10 +710,11 @@ public class AnnotatedColumn {
|
|||
Map<String, Join> secondaryTables,
|
||||
MetadataBuildingContext context,
|
||||
jakarta.persistence.Column[] actualCols) {
|
||||
final int length = actualCols.length;
|
||||
final AnnotatedColumn[] columns = new AnnotatedColumn[length];
|
||||
for ( int index = 0; index < length; index++ ) {
|
||||
final jakarta.persistence.Column column = actualCols[index];
|
||||
final AnnotatedColumns parent = new AnnotatedColumns();
|
||||
parent.setPropertyHolder( propertyHolder );
|
||||
parent.setJoins( secondaryTables );
|
||||
parent.setBuildingContext( context );
|
||||
for ( jakarta.persistence.Column column : actualCols ) {
|
||||
final Database database = context.getMetadataCollector().getDatabase();
|
||||
final String sqlType = getSqlType( context, column );
|
||||
final String tableName = getTableName( column, database );
|
||||
|
@ -752,24 +723,20 @@ public class AnnotatedColumn {
|
|||
// .toIdentifier( column.table() );
|
||||
// final Identifier physicalName = physicalNamingStrategy.toPhysicalTableName( logicalName );
|
||||
// tableName = physicalName.render( database.getDialect() );
|
||||
columns[index] = buildColumn(
|
||||
buildColumn(
|
||||
comment,
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
suffixForDefaultColumnName,
|
||||
secondaryTables,
|
||||
context,
|
||||
length,
|
||||
parent,
|
||||
actualCols.length,
|
||||
database,
|
||||
column,
|
||||
sqlType,
|
||||
tableName
|
||||
);
|
||||
}
|
||||
final AnnotatedColumns result = new AnnotatedColumns();
|
||||
result.setPropertyHolder( propertyHolder );
|
||||
result.setColumns( columns );
|
||||
return result;
|
||||
return parent;
|
||||
}
|
||||
|
||||
private static String getTableName(jakarta.persistence.Column column, Database database) {
|
||||
|
@ -787,42 +754,39 @@ public class AnnotatedColumn {
|
|||
PropertyHolder propertyHolder,
|
||||
PropertyData inferredData,
|
||||
String suffixForDefaultColumnName,
|
||||
Map<String, Join> secondaryTables,
|
||||
MetadataBuildingContext context,
|
||||
int length,
|
||||
AnnotatedColumns parent,
|
||||
int numberOfColumns,
|
||||
Database database,
|
||||
jakarta.persistence.Column col,
|
||||
jakarta.persistence.Column column,
|
||||
String sqlType,
|
||||
String tableName) {
|
||||
|
||||
final AnnotatedColumn column = new AnnotatedColumn();
|
||||
column.setLogicalColumnName( getLogicalColumnName( inferredData, suffixForDefaultColumnName, database, col ) );
|
||||
column.setImplicit( false );
|
||||
column.setSqlType(sqlType);
|
||||
column.setLength( (long) col.length() );
|
||||
column.setPrecision( col.precision() );
|
||||
column.setScale( col.scale() );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
column.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
|
||||
column.setNullable( col.nullable() ); //TODO force to not null if available? This is a (bad) user choice.
|
||||
final String columnName = getLogicalColumnName( inferredData, suffixForDefaultColumnName, database, column );
|
||||
final AnnotatedColumn annotatedColumn = new AnnotatedColumn();
|
||||
annotatedColumn.setLogicalColumnName( columnName );
|
||||
annotatedColumn.setImplicit( false );
|
||||
annotatedColumn.setSqlType( sqlType );
|
||||
annotatedColumn.setLength( (long) column.length() );
|
||||
annotatedColumn.setPrecision( column.precision() );
|
||||
annotatedColumn.setScale( column.scale() );
|
||||
// annotatedColumn.setPropertyHolder( propertyHolder );
|
||||
annotatedColumn.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
|
||||
annotatedColumn.setNullable( column.nullable() ); //TODO force to not null if available? This is a (bad) user choice.
|
||||
if ( comment != null ) {
|
||||
column.setComment( comment.value() );
|
||||
annotatedColumn.setComment( comment.value() );
|
||||
}
|
||||
column.setUnique( col.unique() );
|
||||
column.setInsertable( col.insertable() );
|
||||
column.setUpdatable( col.updatable() );
|
||||
column.setExplicitTableName( tableName );
|
||||
column.setJoins( secondaryTables );
|
||||
column.setBuildingContext( context );
|
||||
column.applyColumnDefault( inferredData, length );
|
||||
column.applyGeneratedAs( inferredData, length );
|
||||
column.applyCheckConstraint( inferredData, length );
|
||||
column.extractDataFromPropertyData( propertyHolder, inferredData );
|
||||
AnnotatedColumns temp = new AnnotatedColumns();
|
||||
temp.setPropertyHolder( propertyHolder );
|
||||
temp.setColumns( new AnnotatedColumn[] { column } );
|
||||
column.bind();
|
||||
return column;
|
||||
annotatedColumn.setUnique( column.unique() );
|
||||
annotatedColumn.setInsertable( column.insertable() );
|
||||
annotatedColumn.setUpdatable( column.updatable() );
|
||||
annotatedColumn.setExplicitTableName( tableName );
|
||||
// annotatedColumn.setJoins( secondaryTables );
|
||||
// annotatedColumn.setBuildingContext( context );
|
||||
annotatedColumn.setParent( parent );
|
||||
annotatedColumn.applyColumnDefault( inferredData, numberOfColumns );
|
||||
annotatedColumn.applyGeneratedAs( inferredData, numberOfColumns );
|
||||
annotatedColumn.applyCheckConstraint( inferredData, numberOfColumns );
|
||||
annotatedColumn.extractDataFromPropertyData( propertyHolder, inferredData );
|
||||
annotatedColumn.bind();
|
||||
return annotatedColumn;
|
||||
}
|
||||
|
||||
private static String getLogicalColumnName(
|
||||
|
@ -843,9 +807,10 @@ public class AnnotatedColumn {
|
|||
}
|
||||
|
||||
private void applyColumnDefault(PropertyData inferredData, int length) {
|
||||
final XProperty xProperty = inferredData.getProperty();
|
||||
if ( xProperty != null ) {
|
||||
final ColumnDefault columnDefault = getOverridableAnnotation( xProperty, ColumnDefault.class, context );
|
||||
final XProperty property = inferredData.getProperty();
|
||||
if ( property != null ) {
|
||||
final ColumnDefault columnDefault =
|
||||
getOverridableAnnotation( property, ColumnDefault.class, getBuildingContext() );
|
||||
if ( columnDefault != null ) {
|
||||
if ( length!=1 ) {
|
||||
throw new MappingException("@ColumnDefault may only be applied to single-column mappings");
|
||||
|
@ -859,9 +824,10 @@ public class AnnotatedColumn {
|
|||
}
|
||||
|
||||
private void applyGeneratedAs(PropertyData inferredData, int length) {
|
||||
final XProperty xProperty = inferredData.getProperty();
|
||||
if ( xProperty != null ) {
|
||||
final GeneratedColumn generatedColumn = getOverridableAnnotation( xProperty, GeneratedColumn.class, context );
|
||||
final XProperty property = inferredData.getProperty();
|
||||
if ( property != null ) {
|
||||
final GeneratedColumn generatedColumn =
|
||||
getOverridableAnnotation( property, GeneratedColumn.class, getBuildingContext() );
|
||||
if ( generatedColumn != null ) {
|
||||
if (length!=1) {
|
||||
throw new MappingException("@GeneratedColumn may only be applied to single-column mappings");
|
||||
|
@ -875,9 +841,9 @@ public class AnnotatedColumn {
|
|||
}
|
||||
|
||||
private void applyCheckConstraint(PropertyData inferredData, int length) {
|
||||
final XProperty xProperty = inferredData.getProperty();
|
||||
if ( xProperty != null ) {
|
||||
final Check check = getOverridableAnnotation( xProperty, Check.class, context );
|
||||
final XProperty property = inferredData.getProperty();
|
||||
if ( property != null ) {
|
||||
final Check check = getOverridableAnnotation( property, Check.class, getBuildingContext() );
|
||||
if ( check != null ) {
|
||||
if (length!=1) {
|
||||
throw new MappingException("@Check may only be applied to single-column mappings (use a table-level @Check)");
|
||||
|
@ -928,29 +894,11 @@ public class AnnotatedColumn {
|
|||
Comment comment,
|
||||
Nullability nullability,
|
||||
MetadataBuildingContext context) {
|
||||
final AnnotatedColumns result = new AnnotatedColumns();
|
||||
result.setPropertyHolder( propertyHolder );
|
||||
final AnnotatedColumn column = bindImplicitColumn(
|
||||
inferredData,
|
||||
suffixForDefaultColumnName,
|
||||
secondaryTables,
|
||||
propertyHolder,
|
||||
comment,
|
||||
nullability,
|
||||
context
|
||||
);
|
||||
result.setColumns( new AnnotatedColumn[] { column } );
|
||||
return result;
|
||||
}
|
||||
|
||||
private static AnnotatedColumn bindImplicitColumn(
|
||||
PropertyData inferredData,
|
||||
String suffixForDefaultColumnName,
|
||||
Map<String, Join> secondaryTables,
|
||||
PropertyHolder propertyHolder,
|
||||
Comment comment,
|
||||
Nullability nullability,
|
||||
MetadataBuildingContext context) {
|
||||
final AnnotatedColumns columns = new AnnotatedColumns();
|
||||
columns.setPropertyHolder( propertyHolder );
|
||||
columns.setBuildingContext( context );
|
||||
columns.setJoins( secondaryTables );
|
||||
columns.setPropertyHolder( propertyHolder );
|
||||
final AnnotatedColumn column = new AnnotatedColumn();
|
||||
if ( comment != null ) {
|
||||
column.setComment( comment.value() );
|
||||
|
@ -964,45 +912,45 @@ public class AnnotatedColumn {
|
|||
final String propertyName = inferredData.getPropertyName();
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
column.setJoins( secondaryTables );
|
||||
column.setBuildingContext( context );
|
||||
// column.setJoins( secondaryTables );
|
||||
// column.setBuildingContext( context );
|
||||
// property name + suffix is an "explicit" column name
|
||||
boolean implicit = isEmpty( suffixForDefaultColumnName );
|
||||
final boolean implicit = isEmpty( suffixForDefaultColumnName );
|
||||
if ( !implicit ) {
|
||||
column.setLogicalColumnName( propertyName + suffixForDefaultColumnName );
|
||||
}
|
||||
column.setImplicit( implicit );
|
||||
column.setParent( columns );
|
||||
column.applyColumnDefault( inferredData, 1 );
|
||||
column.applyGeneratedAs( inferredData, 1 );
|
||||
column.applyCheckConstraint( inferredData, 1 );
|
||||
column.extractDataFromPropertyData( propertyHolder, inferredData );
|
||||
AnnotatedColumns temp = new AnnotatedColumns();
|
||||
temp.setPropertyHolder( propertyHolder );
|
||||
temp.setColumns( new AnnotatedColumn[] { column } );
|
||||
column.bind();
|
||||
return column;
|
||||
return columns;
|
||||
}
|
||||
|
||||
public static void checkPropertyConsistency(AnnotatedColumn[] columns, String propertyName) {
|
||||
if ( columns.length > 1 ) {
|
||||
for (int currentIndex = 1; currentIndex < columns.length; currentIndex++) {
|
||||
if ( !columns[currentIndex].isFormula() && !columns[currentIndex - 1].isFormula() ) {
|
||||
if ( columns[currentIndex].isNullable() != columns[currentIndex - 1].isNullable() ) {
|
||||
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 ( columns[currentIndex].isInsertable() != columns[currentIndex - 1].isInsertable() ) {
|
||||
if ( current.isInsertable() != previous.isInsertable() ) {
|
||||
throw new AnnotationException(
|
||||
"Column mappings for property '" + propertyName + "' mix insertable with 'insertable=false'"
|
||||
);
|
||||
}
|
||||
if ( columns[currentIndex].isUpdatable() != columns[currentIndex - 1].isUpdatable() ) {
|
||||
if ( current.isUpdatable() != previous.isUpdatable() ) {
|
||||
throw new AnnotationException(
|
||||
"Column mappings for property '" + propertyName + "' mix updatable with 'updatable=false'"
|
||||
);
|
||||
}
|
||||
if ( !columns[currentIndex].getTable().equals( columns[currentIndex - 1].getTable() ) ) {
|
||||
if ( !current.getExplicitTableName().equals( previous.getExplicitTableName() ) ) {
|
||||
throw new AnnotationException(
|
||||
"Column mappings for property '" + propertyName + "' mix distinct secondary tables"
|
||||
);
|
||||
|
@ -1020,23 +968,23 @@ public class AnnotatedColumn {
|
|||
|
||||
void addIndex(String indexName, boolean inSecondPass) {
|
||||
final IndexOrUniqueKeySecondPass secondPass =
|
||||
new IndexOrUniqueKeySecondPass( indexName, this, context, false );
|
||||
new IndexOrUniqueKeySecondPass( indexName, this, getBuildingContext(), false );
|
||||
if ( inSecondPass ) {
|
||||
secondPass.doSecondPass( context.getMetadataCollector().getEntityBindingMap() );
|
||||
secondPass.doSecondPass( getBuildingContext().getMetadataCollector().getEntityBindingMap() );
|
||||
}
|
||||
else {
|
||||
context.getMetadataCollector().addSecondPass( secondPass );
|
||||
getBuildingContext().getMetadataCollector().addSecondPass( secondPass );
|
||||
}
|
||||
}
|
||||
|
||||
void addUniqueKey(String uniqueKeyName, boolean inSecondPass) {
|
||||
final IndexOrUniqueKeySecondPass secondPass =
|
||||
new IndexOrUniqueKeySecondPass( uniqueKeyName, this, context, true );
|
||||
new IndexOrUniqueKeySecondPass( uniqueKeyName, this, getBuildingContext(), true );
|
||||
if ( inSecondPass ) {
|
||||
secondPass.doSecondPass( context.getMetadataCollector().getEntityBindingMap() );
|
||||
secondPass.doSecondPass( getBuildingContext().getMetadataCollector().getEntityBindingMap() );
|
||||
}
|
||||
else {
|
||||
context.getMetadataCollector().addSecondPass( secondPass );
|
||||
getBuildingContext().getMetadataCollector().addSecondPass( secondPass );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1056,4 +1004,8 @@ public class AnnotatedColumn {
|
|||
string.append( ")" );
|
||||
return string.toString();
|
||||
}
|
||||
|
||||
MetadataBuildingContext getBuildingContext() {
|
||||
return getParent().getBuildingContext();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,19 @@
|
|||
package org.hibernate.cfg;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.mapping.Join;
|
||||
import org.hibernate.mapping.Table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||
|
||||
/**
|
||||
* A list of columns that are mapped to a single Java property
|
||||
* or field. This is a slightly uncomfortable abstraction here,
|
||||
|
@ -17,21 +29,14 @@ import org.hibernate.mapping.Table;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class AnnotatedColumns {
|
||||
private AnnotatedColumn[] columns;
|
||||
private final List<AnnotatedColumn> columns = new ArrayList<>();
|
||||
private Table table;
|
||||
private PropertyHolder propertyHolder;
|
||||
private Map<String, Join> joins = Collections.emptyMap();
|
||||
private MetadataBuildingContext buildingContext;
|
||||
|
||||
public void setColumns(AnnotatedColumn[] columns) {
|
||||
this.columns = columns;
|
||||
if ( columns != null ) {
|
||||
for ( AnnotatedColumn column : columns ) {
|
||||
column.setParent( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AnnotatedColumn[] getColumns() {
|
||||
return columns;
|
||||
public List<AnnotatedColumn> getColumns() {
|
||||
return unmodifiableList( columns );
|
||||
}
|
||||
|
||||
public PropertyHolder getPropertyHolder() {
|
||||
|
@ -42,6 +47,49 @@ public class AnnotatedColumns {
|
|||
this.propertyHolder = propertyHolder;
|
||||
}
|
||||
|
||||
public void setBuildingContext(MetadataBuildingContext buildingContext) {
|
||||
this.buildingContext = buildingContext;
|
||||
}
|
||||
|
||||
public MetadataBuildingContext getBuildingContext() {
|
||||
return buildingContext;
|
||||
}
|
||||
|
||||
public void setJoins(Map<String, Join> joins) {
|
||||
this.joins = joins;
|
||||
}
|
||||
|
||||
public Join getJoin() {
|
||||
final AnnotatedColumn firstColumn = columns.get(0);
|
||||
final String explicitTableName = firstColumn.getExplicitTableName();
|
||||
Join join = joins.get( explicitTableName );
|
||||
if ( join == null ) {
|
||||
// annotation binding seems to use logical and physical naming somewhat inconsistently...
|
||||
final String physicalTableName = getBuildingContext().getMetadataCollector()
|
||||
.getPhysicalTableName( explicitTableName );
|
||||
if ( physicalTableName != null ) {
|
||||
join = joins.get( physicalTableName );
|
||||
}
|
||||
}
|
||||
if ( join == null ) {
|
||||
throw new AnnotationException(
|
||||
"Secondary table '" + explicitTableName + "' for property '" + getPropertyHolder().getClassName()
|
||||
+ "' is not declared (use '@SecondaryTable' to declare the secondary table)"
|
||||
);
|
||||
}
|
||||
return join;
|
||||
}
|
||||
|
||||
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 String explicitTableName = firstColumn.getExplicitTableName();
|
||||
return isNotEmpty( explicitTableName )
|
||||
&& !getPropertyHolder().getTable().getName().equals( explicitTableName );
|
||||
}
|
||||
|
||||
public Table getTable() {
|
||||
if ( table != null ) {
|
||||
return table;
|
||||
|
@ -50,10 +98,8 @@ public class AnnotatedColumns {
|
|||
// all the columns have to be mapped to the same table
|
||||
// even though at the annotation level it looks like
|
||||
// they could each specify a different table
|
||||
final AnnotatedColumn firstColumn = columns[0];
|
||||
return firstColumn.isSecondary()
|
||||
? firstColumn.getJoin().getTable()
|
||||
: firstColumn.getPropertyHolder().getTable();
|
||||
final AnnotatedColumn firstColumn = columns.get(0);
|
||||
return firstColumn.isSecondary() ? getJoin().getTable() : getPropertyHolder().getTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,4 +111,8 @@ public class AnnotatedColumns {
|
|||
void setTableInternal(Table table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public void addColumn(AnnotatedColumn child) {
|
||||
columns.add( child );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,9 +49,11 @@ public class AnnotatedDiscriminatorColumn extends AnnotatedColumn {
|
|||
DiscriminatorColumn discriminatorColumn,
|
||||
DiscriminatorFormula discriminatorFormula,
|
||||
MetadataBuildingContext context) {
|
||||
final AnnotatedColumns parent = new AnnotatedColumns();
|
||||
parent.setBuildingContext( context );
|
||||
final AnnotatedDiscriminatorColumn column = new AnnotatedDiscriminatorColumn();
|
||||
column.setBuildingContext( context );
|
||||
if ( discriminatorFormula != null ) {
|
||||
// column.setContext( context );
|
||||
if ( discriminatorFormula != null ) {
|
||||
column.setImplicit( false );
|
||||
column.setFormula( discriminatorFormula.value() );
|
||||
}
|
||||
|
@ -69,31 +71,32 @@ public class AnnotatedDiscriminatorColumn extends AnnotatedColumn {
|
|||
column.setImplicit( true );
|
||||
}
|
||||
setDiscriminatorType( type, discriminatorColumn, column );
|
||||
column.setParent( parent );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
|
||||
private static void setDiscriminatorType(
|
||||
DiscriminatorType type,
|
||||
DiscriminatorColumn discAnn,
|
||||
AnnotatedDiscriminatorColumn discriminatorColumn) {
|
||||
DiscriminatorColumn discriminatorColumn,
|
||||
AnnotatedDiscriminatorColumn column) {
|
||||
if ( type == null ) {
|
||||
discriminatorColumn.setDiscriminatorTypeName( "string" );
|
||||
column.setDiscriminatorTypeName( "string" );
|
||||
}
|
||||
else {
|
||||
switch ( type ) {
|
||||
case CHAR:
|
||||
discriminatorColumn.setDiscriminatorTypeName( "character" );
|
||||
discriminatorColumn.setImplicit( false );
|
||||
column.setDiscriminatorTypeName( "character" );
|
||||
column.setImplicit( false );
|
||||
break;
|
||||
case INTEGER:
|
||||
discriminatorColumn.setDiscriminatorTypeName( "integer" );
|
||||
discriminatorColumn.setImplicit( false );
|
||||
column.setDiscriminatorTypeName( "integer" );
|
||||
column.setImplicit( false );
|
||||
break;
|
||||
case STRING:
|
||||
discriminatorColumn.setDiscriminatorTypeName( "string" );
|
||||
if ( discAnn != null ) {
|
||||
discriminatorColumn.setLength( (long) discAnn.length() );
|
||||
column.setDiscriminatorTypeName( "string" );
|
||||
if ( discriminatorColumn != null ) {
|
||||
column.setLength( (long) discriminatorColumn.length() );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.cfg;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.PrimaryKeyJoinColumn;
|
||||
|
||||
|
@ -54,7 +53,6 @@ import static org.hibernate.internal.util.StringHelper.unquote;
|
|||
public class AnnotatedJoinColumn extends AnnotatedColumn {
|
||||
|
||||
private String referencedColumn;
|
||||
private AnnotatedJoinColumns parent;
|
||||
|
||||
// due to @AnnotationOverride overriding rules,
|
||||
// we don't want the constructor to be public
|
||||
|
@ -82,42 +80,32 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
static AnnotatedJoinColumn buildJoinColumn(
|
||||
JoinColumn joinColumn,
|
||||
String mappedBy,
|
||||
Map<String, Join> joins,
|
||||
AnnotatedJoinColumns parent,
|
||||
PropertyHolder propertyHolder,
|
||||
String propertyName,
|
||||
MetadataBuildingContext buildingContext) {
|
||||
String propertyName) {
|
||||
final String path = qualify( propertyHolder.getPath(), propertyName );
|
||||
final JoinColumn[] overriddes = propertyHolder.getOverriddenJoinColumn( path );
|
||||
if ( overriddes != null ) {
|
||||
final JoinColumn[] overrides = propertyHolder.getOverriddenJoinColumn( path );
|
||||
if ( overrides != null ) {
|
||||
//TODO: relax this restriction
|
||||
throw new AnnotationException("Property '" + path
|
||||
+ "' overrides mapping specified using '@JoinColumnOrFormula'");
|
||||
}
|
||||
return buildJoinColumn(
|
||||
joinColumn,
|
||||
null,
|
||||
mappedBy,
|
||||
joins,
|
||||
propertyHolder,
|
||||
propertyName,
|
||||
"",
|
||||
buildingContext
|
||||
);
|
||||
return buildJoinColumn( joinColumn, null, mappedBy, parent, propertyHolder, propertyName, "" );
|
||||
}
|
||||
|
||||
public static AnnotatedJoinColumn buildJoinFormula(
|
||||
JoinFormula joinFormula,
|
||||
Map<String, Join> joins,
|
||||
AnnotatedJoinColumns parent,
|
||||
PropertyHolder propertyHolder,
|
||||
String propertyName,
|
||||
MetadataBuildingContext buildingContext) {
|
||||
String propertyName) {
|
||||
final AnnotatedJoinColumn formulaColumn = new AnnotatedJoinColumn();
|
||||
formulaColumn.setFormula( joinFormula.value() );
|
||||
formulaColumn.setReferencedColumn( joinFormula.referencedColumnName() );
|
||||
formulaColumn.setBuildingContext( buildingContext );
|
||||
// formulaColumn.setContext( buildingContext );
|
||||
// formulaColumn.setPropertyHolder( propertyHolder );
|
||||
formulaColumn.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
formulaColumn.setJoins( joins );
|
||||
// formulaColumn.setJoins( joins );
|
||||
formulaColumn.setParent( parent );
|
||||
formulaColumn.bind();
|
||||
return formulaColumn;
|
||||
}
|
||||
|
@ -126,11 +114,10 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
JoinColumn joinColumn,
|
||||
Comment comment,
|
||||
String mappedBy,
|
||||
Map<String, Join> joins,
|
||||
AnnotatedJoinColumns parent,
|
||||
PropertyHolder propertyHolder,
|
||||
String propertyName,
|
||||
String defaultColumnSuffix,
|
||||
MetadataBuildingContext context) {
|
||||
String defaultColumnSuffix) {
|
||||
if ( joinColumn != null ) {
|
||||
if ( !isEmptyOrNullAnnotationValue( mappedBy ) ) {
|
||||
throw new AnnotationException(
|
||||
|
@ -138,44 +125,44 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
+ "' is 'mappedBy' a different entity and may not explicitly specify the '@JoinColumn'"
|
||||
);
|
||||
}
|
||||
return explicitJoinColumn( joinColumn, comment, joins, propertyHolder, propertyName, defaultColumnSuffix, context );
|
||||
return explicitJoinColumn( joinColumn, comment, parent, propertyHolder, propertyName, defaultColumnSuffix );
|
||||
}
|
||||
else {
|
||||
return implicitJoinColumn( joins, propertyHolder, propertyName, defaultColumnSuffix, context );
|
||||
return implicitJoinColumn( parent, propertyHolder, propertyName, defaultColumnSuffix );
|
||||
}
|
||||
}
|
||||
|
||||
private static AnnotatedJoinColumn explicitJoinColumn(
|
||||
JoinColumn joinColumn,
|
||||
Comment comment,
|
||||
Map<String, Join> joins,
|
||||
AnnotatedJoinColumns parent,
|
||||
PropertyHolder propertyHolder,
|
||||
String propertyName,
|
||||
String defaultColumnSuffix,
|
||||
MetadataBuildingContext context) {
|
||||
String defaultColumnSuffix) {
|
||||
final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
|
||||
column.setComment( comment != null ? comment.value() : null );
|
||||
column.setBuildingContext( context );
|
||||
column.setJoinAnnotation(joinColumn, null );
|
||||
// column.setContext( context );
|
||||
// column.setJoins( joins );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
if ( isEmpty( column.getLogicalColumnName() ) && isNotEmpty( defaultColumnSuffix ) ) {
|
||||
column.setLogicalColumnName( propertyName + defaultColumnSuffix );
|
||||
}
|
||||
column.setJoins( joins );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
column.setImplicit( false );
|
||||
column.setParent( parent );
|
||||
column.applyJoinAnnotation( joinColumn, null );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
|
||||
private static AnnotatedJoinColumn implicitJoinColumn(
|
||||
Map<String, Join> joins,
|
||||
AnnotatedJoinColumns parent,
|
||||
PropertyHolder propertyHolder,
|
||||
String propertyName,
|
||||
String defaultColumnSuffix,
|
||||
MetadataBuildingContext context) {
|
||||
String defaultColumnSuffix) {
|
||||
final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
|
||||
column.setJoins( joins );
|
||||
// column.setContext( context );
|
||||
// column.setJoins( joins );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
// property name + suffix is an "explicit" column name
|
||||
|
@ -186,14 +173,14 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
else {
|
||||
column.setImplicit( true );
|
||||
}
|
||||
column.setBuildingContext( context );
|
||||
column.setParent( parent );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
|
||||
|
||||
// TODO default name still useful in association table
|
||||
public void setJoinAnnotation(JoinColumn joinColumn, String defaultName) {
|
||||
public void applyJoinAnnotation(JoinColumn joinColumn, String defaultName) {
|
||||
if ( joinColumn == null ) {
|
||||
setImplicit( true );
|
||||
}
|
||||
|
@ -233,21 +220,19 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
PrimaryKeyJoinColumn primaryKeyJoinColumn,
|
||||
JoinColumn joinColumn,
|
||||
Value identifier,
|
||||
Map<String, Join> joins,
|
||||
PropertyHolder propertyHolder,
|
||||
AnnotatedJoinColumns parent,
|
||||
MetadataBuildingContext context) {
|
||||
final String defaultColumnName = context.getMetadataCollector()
|
||||
.getLogicalColumnName( identifier.getTable(), identifier.getColumns().get(0).getQuotedName() );
|
||||
return primaryKeyJoinColumn != null || joinColumn != null
|
||||
? explicitJoinColumn( primaryKeyJoinColumn, joinColumn, joins, propertyHolder, context, defaultColumnName )
|
||||
: implicitJoinColumn( joins, propertyHolder, context, defaultColumnName );
|
||||
? explicitJoinColumn( primaryKeyJoinColumn, joinColumn, parent, context, defaultColumnName )
|
||||
: implicitJoinColumn( parent, context, defaultColumnName );
|
||||
}
|
||||
|
||||
private static AnnotatedJoinColumn explicitJoinColumn(
|
||||
PrimaryKeyJoinColumn primaryKeyJoinColumn,
|
||||
JoinColumn joinColumn,
|
||||
Map<String, Join> joins,
|
||||
PropertyHolder propertyHolder,
|
||||
AnnotatedJoinColumns parent,
|
||||
MetadataBuildingContext context,
|
||||
String defaultColumnName) {
|
||||
final String columnName;
|
||||
|
@ -267,34 +252,35 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
final String columnDef = columnDefinition.isEmpty() ? null
|
||||
: normalizer.toDatabaseIdentifierText( columnDefinition );
|
||||
final String logicalColumnName = columnName != null && columnName.isEmpty()
|
||||
? normalizer.normalizeIdentifierQuotingAsString(defaultColumnName)
|
||||
? normalizer.normalizeIdentifierQuotingAsString( defaultColumnName )
|
||||
: normalizer.normalizeIdentifierQuotingAsString( columnName );
|
||||
final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
|
||||
column.setSqlType( columnDef );
|
||||
column.setLogicalColumnName( logicalColumnName );
|
||||
column.setReferencedColumn( referencedColumnName );
|
||||
// column.setPropertyHolder(propertyHolder);
|
||||
column.setJoins(joins);
|
||||
column.setBuildingContext(context);
|
||||
// column.setJoins(joins);
|
||||
// column.setContext( context );
|
||||
column.setImplicit( false );
|
||||
column.setNullable( false );
|
||||
column.setParent( parent );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
|
||||
private static AnnotatedJoinColumn implicitJoinColumn(
|
||||
Map<String, Join> joins,
|
||||
PropertyHolder propertyHolder,
|
||||
AnnotatedJoinColumns parent,
|
||||
MetadataBuildingContext context,
|
||||
String defaultColumnName ) {
|
||||
final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
|
||||
final ObjectNameNormalizer normalizer = context.getObjectNameNormalizer();
|
||||
column.setLogicalColumnName( normalizer.normalizeIdentifierQuotingAsString(defaultColumnName) );
|
||||
column.setLogicalColumnName( normalizer.normalizeIdentifierQuotingAsString( defaultColumnName ) );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
column.setJoins(joins);
|
||||
column.setBuildingContext(context);
|
||||
// column.setJoins(joins);
|
||||
// column.setContext( context );
|
||||
column.setImplicit( true );
|
||||
column.setNullable( false );
|
||||
column.setParent( parent );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
|
@ -328,7 +314,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
SimpleValue value) {
|
||||
final String logicalReferencedColumn = getBuildingContext().getMetadataCollector()
|
||||
.getLogicalColumnName( referencedEntity.getTable(), referencedColumn.getQuotedName() );
|
||||
final String columnName = parent.buildDefaultColumnName( referencedEntity, logicalReferencedColumn );
|
||||
final String columnName = getParent().buildDefaultColumnName( referencedEntity, logicalReferencedColumn );
|
||||
//yuk side effect on an implicit column
|
||||
setLogicalColumnName( columnName );
|
||||
setReferencedColumn( logicalReferencedColumn );
|
||||
|
@ -347,7 +333,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
}
|
||||
|
||||
public void addDefaultJoinColumnName(PersistentClass referencedEntity, String logicalReferencedColumn) {
|
||||
final String columnName = parent.buildDefaultColumnName( referencedEntity, logicalReferencedColumn );
|
||||
final String columnName = getParent().buildDefaultColumnName( referencedEntity, logicalReferencedColumn );
|
||||
getMappingColumn().setName( columnName );
|
||||
setLogicalColumnName( columnName );
|
||||
}
|
||||
|
@ -373,7 +359,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
|
||||
@Override
|
||||
protected void addColumnBinding(SimpleValue value) {
|
||||
if ( isEmpty( parent.getMappedBy() ) ) {
|
||||
if ( isEmpty( getParent().getMappedBy() ) ) {
|
||||
// was the column explicitly quoted in the mapping/annotation
|
||||
// TODO: in metamodel, we need to better split global quoting and explicit quoting w/ respect to logical names
|
||||
boolean isLogicalColumnQuoted = isQuoted( getLogicalColumnName() );
|
||||
|
@ -407,12 +393,12 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
AnnotatedJoinColumns joinColumns,
|
||||
PersistentClass referencedEntity,
|
||||
MetadataBuildingContext context) {
|
||||
final AnnotatedJoinColumn[] columns = joinColumns.getColumns();
|
||||
if ( columns.length == 0 ) {
|
||||
final List<AnnotatedJoinColumn> columns = joinColumns.getJoinColumns();
|
||||
if ( columns.size() == 0 ) {
|
||||
return NO_REFERENCE; //shortcut
|
||||
}
|
||||
|
||||
final AnnotatedJoinColumn firstColumn = columns[0];
|
||||
final AnnotatedJoinColumn firstColumn = columns.get(0);
|
||||
final Object columnOwner = findReferencedColumnOwner( referencedEntity, firstColumn, context );
|
||||
if ( columnOwner == null ) {
|
||||
try {
|
||||
|
@ -441,7 +427,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
}
|
||||
if ( explicitColumnReference ) {
|
||||
// if we got to here, all the columns belong to the PK
|
||||
return keyColumns.size() == columns.length
|
||||
return keyColumns.size() == columns.size()
|
||||
// we have all the PK columns
|
||||
? PK_REFERENCE
|
||||
// we have a subset of the PK columns
|
||||
|
@ -497,36 +483,36 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
}
|
||||
|
||||
static AnnotatedJoinColumn buildImplicitJoinTableJoinColumn(
|
||||
Map<String, Join> secondaryTables,
|
||||
AnnotatedJoinColumns parent,
|
||||
PropertyHolder propertyHolder,
|
||||
String propertyName,
|
||||
MetadataBuildingContext context) {
|
||||
String propertyName) {
|
||||
final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
|
||||
column.setImplicit( true );
|
||||
column.setNullable( false ); //I break the spec, but it's for good
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
column.setJoins( secondaryTables );
|
||||
column.setBuildingContext( context );
|
||||
// column.setJoins( secondaryTables );
|
||||
// column.setContext( context );
|
||||
column.setParent( parent );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
|
||||
static AnnotatedJoinColumn buildExplicitJoinTableJoinColumn(
|
||||
Map<String, Join> secondaryTables,
|
||||
AnnotatedJoinColumns parent,
|
||||
PropertyHolder propertyHolder,
|
||||
String propertyName,
|
||||
MetadataBuildingContext context,
|
||||
JoinColumn joinColumn) {
|
||||
final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
|
||||
column.setImplicit( true );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
column.setJoins( secondaryTables );
|
||||
column.setBuildingContext( context );
|
||||
column.setJoinAnnotation( joinColumn, propertyName );
|
||||
// column.setJoins( secondaryTables );
|
||||
// column.setContext( context );
|
||||
column.setNullable( false ); //I break the spec, but it's for good
|
||||
//done after the annotation to override it
|
||||
column.setParent( parent );
|
||||
column.applyJoinAnnotation( joinColumn, propertyName );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
|
@ -548,8 +534,20 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
return string.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotatedJoinColumns getParent() {
|
||||
return (AnnotatedJoinColumns) super.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(AnnotatedColumns parent) {
|
||||
if ( !(parent instanceof AnnotatedJoinColumns) ) {
|
||||
throw new UnsupportedOperationException("wrong kind of parent");
|
||||
}
|
||||
super.setParent( parent );
|
||||
}
|
||||
|
||||
public void setParent(AnnotatedJoinColumns parent) {
|
||||
super.setParent( parent );
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.hibernate.cfg;
|
|||
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.JoinColumnOrFormula;
|
||||
import org.hibernate.annotations.JoinFormula;
|
||||
|
@ -25,6 +26,8 @@ import org.hibernate.mapping.Property;
|
|||
import org.hibernate.mapping.Selectable;
|
||||
import org.hibernate.mapping.SimpleValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -47,9 +50,8 @@ import static org.hibernate.internal.util.StringHelper.qualify;
|
|||
*/
|
||||
public class AnnotatedJoinColumns extends AnnotatedColumns {
|
||||
|
||||
private AnnotatedJoinColumn[] columns;
|
||||
private final List<AnnotatedJoinColumn> columns = new ArrayList<>();
|
||||
private String propertyName; // this is really a .-separated property path
|
||||
private MetadataBuildingContext buildingContext;
|
||||
|
||||
//TODO: do we really need to hang so many strings off this class?
|
||||
private String mappedBy;
|
||||
|
@ -66,22 +68,23 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
PropertyHolder propertyHolder,
|
||||
String propertyName,
|
||||
MetadataBuildingContext context) {
|
||||
final AnnotatedJoinColumn[] columns = new AnnotatedJoinColumn[joinColumnOrFormulas.length];
|
||||
for ( int i = 0; i < joinColumnOrFormulas.length; i++ ) {
|
||||
final JoinColumnOrFormula columnOrFormula = joinColumnOrFormulas[i];
|
||||
final AnnotatedJoinColumns parent = new AnnotatedJoinColumns();
|
||||
parent.setBuildingContext( context );
|
||||
parent.setJoins( joins );
|
||||
parent.setPropertyHolder( propertyHolder );
|
||||
parent.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
parent.setMappedBy( mappedBy );
|
||||
for ( JoinColumnOrFormula columnOrFormula : joinColumnOrFormulas ) {
|
||||
final JoinFormula formula = columnOrFormula.formula();
|
||||
final JoinColumn column = columnOrFormula.column();
|
||||
columns[i] = formula.value() != null && !formula.value().isEmpty()
|
||||
? AnnotatedJoinColumn.buildJoinFormula( formula, joins, propertyHolder, propertyName, context )
|
||||
: AnnotatedJoinColumn.buildJoinColumn( column, mappedBy, joins, propertyHolder, propertyName, context );
|
||||
if ( !isEmptyOrNullAnnotationValue( formula.value() ) ) {
|
||||
AnnotatedJoinColumn.buildJoinFormula( formula, parent, propertyHolder, propertyName );
|
||||
}
|
||||
else {
|
||||
AnnotatedJoinColumn.buildJoinColumn( column, mappedBy, parent, propertyHolder, propertyName );
|
||||
}
|
||||
}
|
||||
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
|
||||
joinColumns.setBuildingContext( context );
|
||||
joinColumns.setPropertyHolder( propertyHolder );
|
||||
joinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
joinColumns.setColumns( columns );
|
||||
joinColumns.setMappedBy( mappedBy );
|
||||
return joinColumns;
|
||||
return parent;
|
||||
}
|
||||
|
||||
public static AnnotatedJoinColumns buildJoinColumns(
|
||||
|
@ -116,47 +119,38 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
final String path = qualify( propertyHolder.getPath(), propertyName );
|
||||
final JoinColumn[] overriddes = propertyHolder.getOverriddenJoinColumn( path );
|
||||
final JoinColumn[] actualColumns = overriddes == null ? joinColumns : overriddes;
|
||||
final AnnotatedJoinColumns parent = new AnnotatedJoinColumns();
|
||||
parent.setBuildingContext( context );
|
||||
parent.setJoins( joins );
|
||||
parent.setPropertyHolder( propertyHolder );
|
||||
parent.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
parent.setMappedBy( mappedBy );
|
||||
if ( actualColumns == null || actualColumns.length == 0 ) {
|
||||
final AnnotatedJoinColumn joinColumn = AnnotatedJoinColumn.buildJoinColumn(
|
||||
AnnotatedJoinColumn.buildJoinColumn(
|
||||
null,
|
||||
comment,
|
||||
mappedBy,
|
||||
joins,
|
||||
parent,
|
||||
propertyHolder,
|
||||
propertyName,
|
||||
defaultColumnSuffix,
|
||||
context
|
||||
defaultColumnSuffix
|
||||
);
|
||||
final AnnotatedJoinColumns annotatedJoinColumns = new AnnotatedJoinColumns();
|
||||
annotatedJoinColumns.setBuildingContext( context );
|
||||
annotatedJoinColumns.setPropertyHolder( propertyHolder );
|
||||
annotatedJoinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
annotatedJoinColumns.setColumns( new AnnotatedJoinColumn[] { joinColumn } );
|
||||
annotatedJoinColumns.setMappedBy( mappedBy );
|
||||
return annotatedJoinColumns;
|
||||
}
|
||||
else {
|
||||
final AnnotatedJoinColumn[] result = new AnnotatedJoinColumn[actualColumns.length];
|
||||
for ( int index = 0; index < actualColumns.length; index++ ) {
|
||||
result[index] = AnnotatedJoinColumn.buildJoinColumn(
|
||||
actualColumns[index],
|
||||
parent.setMappedBy( mappedBy );
|
||||
for ( JoinColumn actualColumn : actualColumns ) {
|
||||
AnnotatedJoinColumn.buildJoinColumn(
|
||||
actualColumn,
|
||||
comment,
|
||||
mappedBy,
|
||||
joins,
|
||||
parent,
|
||||
propertyHolder,
|
||||
propertyName,
|
||||
defaultColumnSuffix,
|
||||
context
|
||||
defaultColumnSuffix
|
||||
);
|
||||
}
|
||||
final AnnotatedJoinColumns annotatedJoinColumns = new AnnotatedJoinColumns();
|
||||
annotatedJoinColumns.setBuildingContext( context );
|
||||
annotatedJoinColumns.setPropertyHolder( propertyHolder );
|
||||
annotatedJoinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
annotatedJoinColumns.setColumns( result );
|
||||
annotatedJoinColumns.setMappedBy( mappedBy );
|
||||
return annotatedJoinColumns;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
public static AnnotatedJoinColumns buildJoinTableJoinColumns(
|
||||
|
@ -166,56 +160,39 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
String propertyName,
|
||||
String mappedBy,
|
||||
MetadataBuildingContext context) {
|
||||
final AnnotatedJoinColumn[] columns;
|
||||
final AnnotatedJoinColumns parent = new AnnotatedJoinColumns();
|
||||
parent.setBuildingContext( context );
|
||||
parent.setJoins( secondaryTables );
|
||||
parent.setPropertyHolder( propertyHolder );
|
||||
parent.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
parent.setMappedBy( mappedBy );
|
||||
if ( joinColumns == null ) {
|
||||
columns = new AnnotatedJoinColumn[] { AnnotatedJoinColumn.buildImplicitJoinTableJoinColumn(
|
||||
secondaryTables,
|
||||
propertyHolder,
|
||||
propertyName,
|
||||
context
|
||||
) };
|
||||
AnnotatedJoinColumn.buildImplicitJoinTableJoinColumn( parent, propertyHolder, propertyName );
|
||||
}
|
||||
else {
|
||||
columns = new AnnotatedJoinColumn[joinColumns.length];
|
||||
int length = joinColumns.length;
|
||||
for (int index = 0; index < length; index++) {
|
||||
columns[index] = AnnotatedJoinColumn.buildExplicitJoinTableJoinColumn(
|
||||
secondaryTables,
|
||||
propertyHolder,
|
||||
propertyName,
|
||||
context,
|
||||
joinColumns[index]
|
||||
);
|
||||
for ( JoinColumn joinColumn : joinColumns ) {
|
||||
AnnotatedJoinColumn.buildExplicitJoinTableJoinColumn( parent, propertyHolder, propertyName, joinColumn );
|
||||
}
|
||||
}
|
||||
final AnnotatedJoinColumns annotatedJoinColumns = new AnnotatedJoinColumns();
|
||||
annotatedJoinColumns.setBuildingContext( context );
|
||||
annotatedJoinColumns.setPropertyHolder( propertyHolder );
|
||||
annotatedJoinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
annotatedJoinColumns.setColumns( columns );
|
||||
annotatedJoinColumns.setMappedBy( mappedBy );
|
||||
return annotatedJoinColumns;
|
||||
return parent;
|
||||
}
|
||||
|
||||
public AnnotatedJoinColumn[] getColumns() {
|
||||
public List<AnnotatedJoinColumn> getJoinColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColumns(AnnotatedColumn[] columns) {
|
||||
throw new UnsupportedOperationException( "wrong sort of columns" );
|
||||
}
|
||||
|
||||
public void setColumns(AnnotatedJoinColumn[] columns) {
|
||||
super.setColumns( columns );
|
||||
this.columns = columns;
|
||||
if ( columns != null ) {
|
||||
for ( AnnotatedJoinColumn column : columns ) {
|
||||
column.setParent( this );
|
||||
}
|
||||
public void addColumn(AnnotatedColumn child) {
|
||||
if ( !(child instanceof AnnotatedJoinColumn) ) {
|
||||
throw new AssertionFailure( "wrong sort of column" );
|
||||
}
|
||||
addColumn( (AnnotatedJoinColumn) child );
|
||||
}
|
||||
|
||||
public void addColumn(AnnotatedJoinColumn child) {
|
||||
super.addColumn( child );
|
||||
columns.add( child );
|
||||
}
|
||||
public String getMappedBy() {
|
||||
return mappedBy;
|
||||
}
|
||||
|
@ -258,7 +235,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
final PropertyHolder propertyHolder = buildPropertyHolder(
|
||||
persistentClass,
|
||||
joins,
|
||||
buildingContext,
|
||||
getBuildingContext(),
|
||||
inheritanceStatePerClass
|
||||
);
|
||||
setPropertyHolder( propertyHolder );
|
||||
|
@ -267,10 +244,6 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
// }
|
||||
}
|
||||
|
||||
public void setBuildingContext(MetadataBuildingContext buildingContext) {
|
||||
this.buildingContext = buildingContext;
|
||||
}
|
||||
|
||||
public boolean isElementCollection() {
|
||||
return elementCollection;
|
||||
}
|
||||
|
@ -294,7 +267,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
}
|
||||
|
||||
String buildDefaultColumnName(PersistentClass referencedEntity, String logicalReferencedColumn) {
|
||||
final MetadataBuildingOptions options = buildingContext.getBuildingOptions();
|
||||
final MetadataBuildingOptions options = getBuildingContext().getBuildingOptions();
|
||||
final ImplicitNamingStrategy implicitNamingStrategy = options.getImplicitNamingStrategy();
|
||||
final PhysicalNamingStrategy physicalNamingStrategy = options.getPhysicalNamingStrategy();
|
||||
|
||||
|
@ -302,7 +275,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
boolean ownerSide = getPropertyName() != null;
|
||||
boolean isRefColumnQuoted = isQuoted( logicalReferencedColumn );
|
||||
|
||||
final InFlightMetadataCollector collector = buildingContext.getMetadataCollector();
|
||||
final InFlightMetadataCollector collector = getBuildingContext().getMetadataCollector();
|
||||
final Database database = collector.getDatabase();
|
||||
|
||||
Identifier columnIdentifier;
|
||||
|
@ -350,7 +323,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
new ImplicitPrimaryKeyJoinColumnNameSource() {
|
||||
@Override
|
||||
public MetadataBuildingContext getBuildingContext() {
|
||||
return buildingContext;
|
||||
return AnnotatedJoinColumns.this.getBuildingContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -407,7 +380,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
private final Identifier referencedTableName;
|
||||
private final String logicalReferencedColumn;
|
||||
|
||||
final InFlightMetadataCollector collector = buildingContext.getMetadataCollector();
|
||||
final InFlightMetadataCollector collector = getBuildingContext().getMetadataCollector();
|
||||
final Database database = collector.getDatabase();
|
||||
|
||||
public UnownedImplicitJoinColumnNameSource(PersistentClass referencedEntity, String logicalReferencedColumn) {
|
||||
|
@ -505,7 +478,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
|
||||
@Override
|
||||
public MetadataBuildingContext getBuildingContext() {
|
||||
return buildingContext;
|
||||
return AnnotatedJoinColumns.this.getBuildingContext();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,7 +491,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
private final Identifier referencedTableName;
|
||||
private final Identifier referencedColumnName;
|
||||
|
||||
final InFlightMetadataCollector collector = buildingContext.getMetadataCollector();
|
||||
final InFlightMetadataCollector collector = getBuildingContext().getMetadataCollector();
|
||||
final Database database = collector.getDatabase();
|
||||
|
||||
public OwnedImplicitJoinColumnNameSource(PersistentClass referencedEntity, String logicalTableName, String logicalReferencedColumn) {
|
||||
|
@ -571,7 +544,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
|
|||
|
||||
@Override
|
||||
public MetadataBuildingContext getBuildingContext() {
|
||||
return buildingContext;
|
||||
return AnnotatedJoinColumns.this.getBuildingContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1510,16 +1510,23 @@ public final class AnnotationBinder {
|
|||
if ( isOverridden ) {
|
||||
// careful: not always a @MapsId property, sometimes it's from an @IdClass
|
||||
final PropertyData mapsIdProperty = getPropertyOverriddenByMapperOrMapsId(
|
||||
propertyBinder.isId(), propertyHolder, property.getName(), context
|
||||
propertyBinder.isId(),
|
||||
propertyHolder,
|
||||
property.getName(),
|
||||
context
|
||||
);
|
||||
referencedEntityName = mapsIdProperty.getClassOrElementName();
|
||||
propertyName = mapsIdProperty.getPropertyName();
|
||||
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
|
||||
joinColumns.setBuildingContext( context );
|
||||
joinColumns.setPropertyHolder( propertyHolder );
|
||||
joinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
joinColumns.setColumns( (AnnotatedJoinColumn[]) columns.getColumns() );
|
||||
actualColumns = joinColumns;
|
||||
final AnnotatedJoinColumns parent = new AnnotatedJoinColumns();
|
||||
parent.setBuildingContext( context );
|
||||
parent.setPropertyHolder( propertyHolder );
|
||||
parent.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
//TODO: resetting the parent here looks like a dangerous thing to do
|
||||
// should we be cloning them first (the legacy code did not)
|
||||
for ( AnnotatedColumn column : columns.getColumns() ) {
|
||||
column.setParent( parent );
|
||||
}
|
||||
actualColumns = parent;
|
||||
}
|
||||
else {
|
||||
referencedEntityName = null;
|
||||
|
@ -1579,7 +1586,7 @@ public final class AnnotationBinder {
|
|||
final JoinTable assocTable = propertyHolder.getJoinTable(property);
|
||||
if ( assocTable != null ) {
|
||||
Join join = propertyHolder.addJoin( assocTable, false );
|
||||
for ( AnnotatedJoinColumn joinColumn : joinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn joinColumn : joinColumns.getJoinColumns() ) {
|
||||
joinColumn.setExplicitTableName( join.getTable().getName() );
|
||||
}
|
||||
}
|
||||
|
@ -2247,7 +2254,7 @@ public final class AnnotationBinder {
|
|||
binder.setUpdatable( false );
|
||||
}
|
||||
else {
|
||||
final AnnotatedJoinColumn firstColumn = columns.getColumns()[0];
|
||||
final AnnotatedJoinColumn firstColumn = columns.getJoinColumns().get(0);
|
||||
binder.setInsertable( firstColumn.isInsertable() );
|
||||
binder.setUpdatable( firstColumn.isUpdatable() );
|
||||
}
|
||||
|
|
|
@ -172,18 +172,16 @@ public class BinderHelper {
|
|||
// true when we do the reverse side of a @ManyToMany
|
||||
boolean inverse,
|
||||
MetadataBuildingContext context) {
|
||||
final AnnotatedJoinColumn[] columns = joinColumns.getColumns();
|
||||
|
||||
// this work is not necessary for a primary key reference
|
||||
if ( checkReferencedColumnsType( joinColumns, targetEntity, context ) == NON_PK_REFERENCE ) { // && !firstColumn.isImplicit()
|
||||
// all the columns have to belong to the same table;
|
||||
// figure out which table has the columns by looking
|
||||
// for a PersistentClass or Join in the hierarchy of
|
||||
// the target entity which has the first column
|
||||
final Object columnOwner = findReferencedColumnOwner( targetEntity, columns[0], context );
|
||||
final Object columnOwner = findReferencedColumnOwner( targetEntity, joinColumns.getJoinColumns().get(0), context );
|
||||
checkColumnInSameTable( joinColumns, targetEntity, associatedEntity, context, columnOwner );
|
||||
// find all properties mapped to each column
|
||||
final List<Property> properties = findPropertiesByColumns( columnOwner, columns, associatedEntity, context );
|
||||
final List<Property> properties = findPropertiesByColumns( columnOwner, joinColumns, associatedEntity, context );
|
||||
// create a Property along with the new synthetic
|
||||
// Component if necessary (or reuse the existing
|
||||
// Property that matches exactly)
|
||||
|
@ -224,19 +222,19 @@ public class BinderHelper {
|
|||
// we should only get called for owning side of association
|
||||
throw new AssertionFailure("no need to create synthetic properties for unowned collections");
|
||||
}
|
||||
for ( AnnotatedJoinColumn column: joinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn column: joinColumns.getJoinColumns() ) {
|
||||
final Object owner = findReferencedColumnOwner( targetEntity, column, context );
|
||||
if ( owner == null ) {
|
||||
throw new AnnotationException( "A '@JoinColumn' for association "
|
||||
+ associationMessage( associatedEntity, column )
|
||||
+ associationMessage( associatedEntity, joinColumns )
|
||||
+ " references a column named '" + column.getReferencedColumn()
|
||||
+ "' which is not mapped by the target entity '"
|
||||
+ targetEntity.getEntityName() + "'" );
|
||||
}
|
||||
if ( owner != columnOwner) {
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getColumns()[0];
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getJoinColumns().get(0);
|
||||
throw new AnnotationException( "The '@JoinColumn's for association "
|
||||
+ associationMessage( associatedEntity, column )
|
||||
+ associationMessage( associatedEntity, joinColumns )
|
||||
+ " reference columns of different tables mapped by the target entity '"
|
||||
+ targetEntity.getEntityName() + "' ('" + column.getReferencedColumn() +
|
||||
"' belongs to a different table to '" + firstColumn.getReferencedColumn() + "'" );
|
||||
|
@ -334,21 +332,21 @@ public class BinderHelper {
|
|||
return syntheticPropertyName;
|
||||
}
|
||||
|
||||
private static String associationMessage(PersistentClass associatedEntity, AnnotatedJoinColumn firstColumn) {
|
||||
private static String associationMessage(PersistentClass associatedEntity, AnnotatedJoinColumns joinColumns) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
if ( associatedEntity != null ) {
|
||||
message.append( "'" )
|
||||
.append( associatedEntity.getEntityName() )
|
||||
.append( "." )
|
||||
.append( firstColumn.getPropertyName() )
|
||||
.append( joinColumns.getPropertyName() )
|
||||
.append( "'" );
|
||||
}
|
||||
else {
|
||||
if ( firstColumn.getPropertyHolder() != null ) {
|
||||
if ( joinColumns.getPropertyHolder() != null ) {
|
||||
message.append( "'" )
|
||||
.append( firstColumn.getPropertyHolder().getEntityName() )
|
||||
.append( joinColumns.getPropertyHolder().getEntityName() )
|
||||
.append( "." )
|
||||
.append( firstColumn.getPropertyName() )
|
||||
.append( joinColumns.getPropertyName() )
|
||||
.append( "'" );
|
||||
}
|
||||
}
|
||||
|
@ -415,7 +413,7 @@ public class BinderHelper {
|
|||
|
||||
private static List<Property> findPropertiesByColumns(
|
||||
Object columnOwner,
|
||||
AnnotatedJoinColumn[] columns,
|
||||
AnnotatedJoinColumns columns,
|
||||
PersistentClass associatedEntity,
|
||||
MetadataBuildingContext context) {
|
||||
|
||||
|
@ -436,12 +434,12 @@ public class BinderHelper {
|
|||
|
||||
// Build the list of column names in the exact order they were
|
||||
// specified by the @JoinColumn annotations.
|
||||
final List<Column> orderedColumns = new ArrayList<>( columns.length );
|
||||
final List<Column> orderedColumns = new ArrayList<>( columns.getJoinColumns().size() );
|
||||
final Map<Column, Set<Property>> columnsToProperty = new HashMap<>();
|
||||
final InFlightMetadataCollector collector = context.getMetadataCollector();
|
||||
for ( AnnotatedJoinColumn joinColumn : columns ) {
|
||||
for ( AnnotatedJoinColumn joinColumn : columns.getJoinColumns() ) {
|
||||
if ( joinColumn.isReferenceImplicit() ) {
|
||||
throw new AnnotationException("Association " + associationMessage( associatedEntity, joinColumn )
|
||||
throw new AnnotationException("Association " + associationMessage( associatedEntity, columns )
|
||||
+ " has a '@JoinColumn' which does not specify the 'referencedColumnName'"
|
||||
+ " (when an association has multiple '@JoinColumn's, they must each specify their 'referencedColumnName')");
|
||||
}
|
||||
|
@ -492,7 +490,7 @@ public class BinderHelper {
|
|||
if ( properties.isEmpty() ) {
|
||||
// no property found which maps to this column
|
||||
throw new AnnotationException( "Referenced column '" + column.getName()
|
||||
+ "' in '@JoinColumn' for " + associationMessage( associatedEntity, columns[0] )
|
||||
+ "' in '@JoinColumn' for " + associationMessage( associatedEntity, columns )
|
||||
+ " is not mapped by any property of the target entity" );
|
||||
}
|
||||
for ( Property property : properties ) {
|
||||
|
@ -503,7 +501,7 @@ public class BinderHelper {
|
|||
throw new AnnotationException( "Referenced column '" + column.getName()
|
||||
+ "' mapped by target property '" + property.getName()
|
||||
+ "' occurs out of order in the list of '@JoinColumn's for association "
|
||||
+ associationMessage( associatedEntity, columns[0] ) );
|
||||
+ associationMessage( associatedEntity, columns ) );
|
||||
}
|
||||
lastPropertyColumnIndex++;
|
||||
if ( lastPropertyColumnIndex == currentProperty.getColumnSpan() ) {
|
||||
|
@ -516,7 +514,7 @@ public class BinderHelper {
|
|||
// we didn't use up all the columns of the previous property
|
||||
throw new AnnotationException( "Target property '" + property.getName() + "' has "
|
||||
+ property.getColumnSpan() + " columns which must be referenced by a '@JoinColumn' for "
|
||||
+ associationMessage( associatedEntity, columns[0] )
|
||||
+ associationMessage( associatedEntity, columns )
|
||||
+ " (every column mapped by '" + property.getName()
|
||||
+ "' must occur exactly once as a 'referencedColumnName', and in the correct order)" );
|
||||
}
|
||||
|
@ -524,7 +522,7 @@ public class BinderHelper {
|
|||
// we already used up all the columns of this property
|
||||
throw new AnnotationException( "Target property '" + property.getName() + "' has only "
|
||||
+ property.getColumnSpan() + " columns which may be referenced by a '@JoinColumn' for "
|
||||
+ associationMessage( associatedEntity, columns[0] )
|
||||
+ associationMessage( associatedEntity, columns )
|
||||
+ " (each column mapped by '" + property.getName()
|
||||
+ "' may only occur once as a 'referencedColumnName')" );
|
||||
|
||||
|
@ -1070,7 +1068,7 @@ public class BinderHelper {
|
|||
entityBinder.getSecondaryTables(),
|
||||
context
|
||||
);
|
||||
assert discriminatorColumns.getColumns().length == 1;
|
||||
assert discriminatorColumns.getColumns().size() == 1;
|
||||
|
||||
discriminatorColumns.setTable( value.getTable() );
|
||||
discriminatorValueBinder.setColumns( discriminatorColumns );
|
||||
|
@ -1082,7 +1080,7 @@ public class BinderHelper {
|
|||
value.setDiscriminator( discriminatorDescriptor );
|
||||
discriminatorValueBinder.fillSimpleValue();
|
||||
// TODO: this is nasty
|
||||
final AnnotatedColumn firstDiscriminatorColumn = discriminatorColumns.getColumns()[0];
|
||||
final AnnotatedColumn firstDiscriminatorColumn = discriminatorColumns.getColumns().get(0);
|
||||
firstDiscriminatorColumn.linkWithValue( discriminatorDescriptor );
|
||||
|
||||
final JavaType<?> discriminatorJavaType = discriminatorDescriptor
|
||||
|
@ -1100,8 +1098,8 @@ public class BinderHelper {
|
|||
value.setDiscriminatorValueMappings( discriminatorValueMappings );
|
||||
|
||||
final BasicValueBinder keyValueBinder = new BasicValueBinder( BasicValueBinder.Kind.ANY_KEY, context );
|
||||
final AnnotatedJoinColumn[] columns = keyColumns.getColumns();
|
||||
assert columns.length == 1;
|
||||
final List<AnnotatedJoinColumn> columns = keyColumns.getJoinColumns();
|
||||
assert columns.size() == 1;
|
||||
keyColumns.setTable( value.getTable() );
|
||||
keyValueBinder.setColumns( keyColumns );
|
||||
if ( !optional ) {
|
||||
|
@ -1114,8 +1112,8 @@ public class BinderHelper {
|
|||
value.setKey( keyDescriptor );
|
||||
keyValueBinder.fillSimpleValue();
|
||||
final String path = qualify( propertyHolder.getEntityName(), inferredData.getPropertyName() );
|
||||
AnnotatedColumn.checkPropertyConsistency( columns, path );
|
||||
columns[0].linkWithValue( keyDescriptor );
|
||||
AnnotatedColumn.checkPropertyConsistency( keyColumns.getColumns(), path );
|
||||
columns.get(0).linkWithValue( keyDescriptor ); //TODO: nasty
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -1175,23 +1173,22 @@ public class BinderHelper {
|
|||
PropertyHolder propertyHolder,
|
||||
String propertyName,
|
||||
MetadataBuildingContext buildingContext) {
|
||||
final XClass persistentXClass = buildingContext.getBootstrapContext().getReflectionManager()
|
||||
final XClass mappedClass = buildingContext.getBootstrapContext().getReflectionManager()
|
||||
.toXClass( propertyHolder.getPersistentClass().getMappedClass() );
|
||||
final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector();
|
||||
if ( propertyHolder.isInIdClass() ) {
|
||||
PropertyData pd = metadataCollector.getPropertyAnnotatedWithIdAndToOne( persistentXClass, propertyName );
|
||||
if ( pd == null && buildingContext.getBuildingOptions().isSpecjProprietarySyntaxEnabled() ) {
|
||||
pd = metadataCollector.getPropertyAnnotatedWithMapsId( persistentXClass, propertyName );
|
||||
}
|
||||
return pd;
|
||||
final PropertyData propertyData = metadataCollector.getPropertyAnnotatedWithIdAndToOne( mappedClass, propertyName );
|
||||
return propertyData == null && buildingContext.getBuildingOptions().isSpecjProprietarySyntaxEnabled()
|
||||
? metadataCollector.getPropertyAnnotatedWithMapsId( mappedClass, propertyName )
|
||||
: propertyData;
|
||||
}
|
||||
else {
|
||||
return metadataCollector.getPropertyAnnotatedWithMapsId( persistentXClass, isId ? "" : propertyName);
|
||||
return metadataCollector.getPropertyAnnotatedWithMapsId( mappedClass, isId ? "" : propertyName );
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String,String> toAliasTableMap(SqlFragmentAlias[] aliases){
|
||||
Map<String,String> ret = new HashMap<>();
|
||||
final Map<String,String> ret = new HashMap<>();
|
||||
for ( SqlFragmentAlias aliase : aliases ) {
|
||||
if ( isNotEmpty( aliase.table() ) ) {
|
||||
ret.put( aliase.alias(), aliase.table() );
|
||||
|
@ -1201,13 +1198,13 @@ public class BinderHelper {
|
|||
}
|
||||
|
||||
public static Map<String,String> toAliasEntityMap(SqlFragmentAlias[] aliases){
|
||||
Map<String,String> ret = new HashMap<>();
|
||||
final Map<String,String> result = new HashMap<>();
|
||||
for ( SqlFragmentAlias aliase : aliases ) {
|
||||
if ( aliase.entity() != void.class ) {
|
||||
ret.put( aliase.alias(), aliase.entity().getName() );
|
||||
result.put( aliase.alias(), aliase.entity().getName() );
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean hasToOneAnnotation(XAnnotatedElement property) {
|
||||
|
@ -1219,13 +1216,13 @@ public class BinderHelper {
|
|||
XAnnotatedElement element,
|
||||
Class<T> annotationType,
|
||||
MetadataBuildingContext context) {
|
||||
Dialect dialect = context.getMetadataCollector().getDatabase().getDialect();
|
||||
Iterator<Annotation> annotations =
|
||||
final Dialect dialect = context.getMetadataCollector().getDatabase().getDialect();
|
||||
final Iterator<Annotation> annotations =
|
||||
Arrays.stream( element.getAnnotations() )
|
||||
.flatMap(annotation -> {
|
||||
.flatMap( annotation -> {
|
||||
try {
|
||||
Method value = annotation.annotationType().getDeclaredMethod("value");
|
||||
Class<?> returnType = value.getReturnType();
|
||||
final Method value = annotation.annotationType().getDeclaredMethod("value");
|
||||
final Class<?> returnType = value.getReturnType();
|
||||
if ( returnType.isArray()
|
||||
&& returnType.getComponentType().isAnnotationPresent(Repeatable.class)
|
||||
&& returnType.getComponentType().isAnnotationPresent(DialectOverride.OverridesAnnotation.class) ) {
|
||||
|
@ -1237,21 +1234,22 @@ public class BinderHelper {
|
|||
throw new AssertionFailure("could not read @DialectOverride annotation", e);
|
||||
}
|
||||
return Stream.of(annotation);
|
||||
}).iterator();
|
||||
} ).iterator();
|
||||
while ( annotations.hasNext() ) {
|
||||
Annotation annotation = annotations.next();
|
||||
Class<? extends Annotation> type = annotation.annotationType();
|
||||
DialectOverride.OverridesAnnotation overridesAnnotation = type.getAnnotation(DialectOverride.OverridesAnnotation.class);
|
||||
final Annotation annotation = annotations.next();
|
||||
final Class<? extends Annotation> type = annotation.annotationType();
|
||||
final DialectOverride.OverridesAnnotation overridesAnnotation =
|
||||
type.getAnnotation(DialectOverride.OverridesAnnotation.class);
|
||||
if ( overridesAnnotation != null
|
||||
&& overridesAnnotation.value().equals(annotationType) ) {
|
||||
try {
|
||||
//noinspection unchecked
|
||||
Class<? extends Dialect> overrideDialect = (Class<? extends Dialect>)
|
||||
final Class<? extends Dialect> overrideDialect = (Class<? extends Dialect>)
|
||||
type.getDeclaredMethod("dialect").invoke(annotation);
|
||||
if ( overrideDialect.isAssignableFrom( dialect.getClass() ) ) {
|
||||
DialectOverride.Version before = (DialectOverride.Version)
|
||||
final DialectOverride.Version before = (DialectOverride.Version)
|
||||
type.getDeclaredMethod("before").invoke(annotation);
|
||||
DialectOverride.Version sameOrAfter = (DialectOverride.Version)
|
||||
final DialectOverride.Version sameOrAfter = (DialectOverride.Version)
|
||||
type.getDeclaredMethod("sameOrAfter").invoke(annotation);
|
||||
if ( dialect.getVersion().isBefore( before.major(), before.minor() )
|
||||
&& dialect.getVersion().isSameOrAfter( sameOrAfter.major(), sameOrAfter.minor() ) ) {
|
||||
|
@ -1306,8 +1304,8 @@ public class BinderHelper {
|
|||
Cascade hibernateCascadeAnnotation,
|
||||
boolean orphanRemoval,
|
||||
boolean forcePersist) {
|
||||
EnumSet<CascadeType> cascadeTypes = convertToHibernateCascadeType( ejbCascades );
|
||||
CascadeType[] hibernateCascades = hibernateCascadeAnnotation == null ? null : hibernateCascadeAnnotation.value();
|
||||
final EnumSet<CascadeType> cascadeTypes = convertToHibernateCascadeType( ejbCascades );
|
||||
final CascadeType[] hibernateCascades = hibernateCascadeAnnotation == null ? null : hibernateCascadeAnnotation.value();
|
||||
if ( hibernateCascades != null && hibernateCascades.length > 0 ) {
|
||||
cascadeTypes.addAll( Arrays.asList( hibernateCascades ) );
|
||||
}
|
||||
|
@ -1322,7 +1320,7 @@ public class BinderHelper {
|
|||
}
|
||||
|
||||
private static String renderCascadeTypeList(EnumSet<CascadeType> cascadeTypes) {
|
||||
StringBuilder cascade = new StringBuilder();
|
||||
final StringBuilder cascade = new StringBuilder();
|
||||
for ( CascadeType cascadeType : cascadeTypes) {
|
||||
switch ( cascadeType ) {
|
||||
case ALL:
|
||||
|
|
|
@ -12,7 +12,6 @@ import jakarta.persistence.Convert;
|
|||
import jakarta.persistence.Converts;
|
||||
import jakarta.persistence.JoinTable;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.annotations.common.reflection.XClass;
|
||||
|
@ -183,18 +182,10 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
|||
}
|
||||
|
||||
public void addProperty(Property prop, AnnotatedColumns columns, XClass declaringClass) {
|
||||
//Ejb3Column.checkPropertyConsistency( ); //already called earlier
|
||||
//AnnotatedColumn.checkPropertyConsistency( ); //already called earlier
|
||||
if ( columns != null ) {
|
||||
final AnnotatedColumn firstColumn = columns.getColumns()[0];
|
||||
if ( firstColumn.isSecondary() ) {
|
||||
//TODO move the getJoin() code here?
|
||||
for ( AnnotatedColumn column : columns.getColumns() ) {
|
||||
if ( !column.isSecondary() || column.getJoin() != firstColumn.getJoin() ) {
|
||||
//TODO: fix the error message
|
||||
throw new AnnotationException("different columns mapped to different tables for a single property");
|
||||
}
|
||||
}
|
||||
addPropertyToJoin( prop, declaringClass, firstColumn.getJoin() );
|
||||
if ( columns.isSecondary() ) {
|
||||
addPropertyToJoin( prop, declaringClass, columns.getJoin() );
|
||||
}
|
||||
else {
|
||||
addProperty( prop, declaringClass );
|
||||
|
|
|
@ -239,19 +239,12 @@ class ColumnsBuilder {
|
|||
}
|
||||
|
||||
private AnnotatedJoinColumns buildJoinColumnsWithFormula(String propertyName, JoinFormula joinFormula) {
|
||||
final AnnotatedJoinColumn[] columns = new AnnotatedJoinColumn[1];
|
||||
columns[0] = AnnotatedJoinColumn.buildJoinFormula(
|
||||
joinFormula,
|
||||
entityBinder.getSecondaryTables(),
|
||||
propertyHolder,
|
||||
propertyName,
|
||||
buildingContext
|
||||
);
|
||||
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
|
||||
joinColumns.setBuildingContext( buildingContext );
|
||||
joinColumns.setJoins( entityBinder.getSecondaryTables() );
|
||||
joinColumns.setPropertyHolder( propertyHolder );
|
||||
joinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName) );
|
||||
joinColumns.setColumns( columns );
|
||||
joinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
|
||||
AnnotatedJoinColumn.buildJoinFormula( joinFormula, joinColumns, propertyHolder, propertyName );
|
||||
return joinColumns;
|
||||
}
|
||||
|
||||
|
@ -260,13 +253,13 @@ class ColumnsBuilder {
|
|||
return new JoinColumnOrFormula[] { property.getAnnotation( JoinColumnOrFormula.class ) };
|
||||
}
|
||||
else if ( property.isAnnotationPresent( JoinColumnsOrFormulas.class ) ) {
|
||||
JoinColumnsOrFormulas joinColumnsOrFormulasAnnotations = property.getAnnotation( JoinColumnsOrFormulas.class );
|
||||
final JoinColumnOrFormula[] joinColumnOrFormulaAnnotations = joinColumnsOrFormulasAnnotations.value();
|
||||
if ( joinColumnOrFormulaAnnotations.length == 0 ) {
|
||||
final JoinColumnsOrFormulas joinColumnsOrFormulas = property.getAnnotation( JoinColumnsOrFormulas.class );
|
||||
final JoinColumnOrFormula[] joinColumnOrFormula = joinColumnsOrFormulas.value();
|
||||
if ( joinColumnOrFormula.length == 0 ) {
|
||||
throw new AnnotationException( "Property '" + getPath( propertyHolder, inferredData)
|
||||
+ "' has an empty '@JoinColumnsOrFormulas' annotation" );
|
||||
}
|
||||
return joinColumnOrFormulaAnnotations;
|
||||
return joinColumnOrFormula;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
|
@ -278,33 +271,34 @@ class ColumnsBuilder {
|
|||
return new JoinColumn[] { property.getAnnotation( JoinColumn.class ) };
|
||||
}
|
||||
else if ( property.isAnnotationPresent( JoinColumns.class ) ) {
|
||||
final JoinColumns joinColumnAnnotation = property.getAnnotation( JoinColumns.class );
|
||||
final JoinColumn[] joinColumnAnnotations = joinColumnAnnotation.value();
|
||||
if ( joinColumnAnnotations.length == 0 ) {
|
||||
final JoinColumns joinColumns = property.getAnnotation( JoinColumns.class );
|
||||
final JoinColumn[] joinColumn = joinColumns.value();
|
||||
if ( joinColumn.length == 0 ) {
|
||||
throw new AnnotationException( "Property '" + getPath( propertyHolder, inferredData)
|
||||
+ "' has an empty '@JoinColumns' annotation" );
|
||||
}
|
||||
return joinColumnAnnotations;
|
||||
return joinColumn;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
AnnotatedColumns overrideColumnFromMapperOrMapsIdProperty(boolean isId) {
|
||||
final PropertyData overridingProperty =
|
||||
getPropertyOverriddenByMapperOrMapsId( isId, propertyHolder, property.getName(), buildingContext );
|
||||
return overridingProperty != null ? buildExplicitOrDefaultJoinColumn( overridingProperty ) : columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful to override a column either by {@code @MapsId} or by {@code @IdClass}
|
||||
*/
|
||||
//TODO: should we introduce an AnnotatedColumns type and return that here?
|
||||
private AnnotatedColumns buildExplicitOrDefaultJoinColumn(PropertyData overridingProperty) {
|
||||
final AnnotatedJoinColumns columns = buildExplicitJoinColumns( overridingProperty.getProperty(), overridingProperty );
|
||||
return columns == null
|
||||
? buildDefaultJoinColumnsForToOne( overridingProperty.getProperty(), overridingProperty )
|
||||
: columns;
|
||||
AnnotatedColumns overrideColumnFromMapperOrMapsIdProperty(boolean isId) {
|
||||
final PropertyData override =
|
||||
getPropertyOverriddenByMapperOrMapsId( isId, propertyHolder, property.getName(), buildingContext );
|
||||
if ( override != null ) {
|
||||
final AnnotatedJoinColumns joinColumns = buildExplicitJoinColumns( override.getProperty(), override );
|
||||
return joinColumns == null
|
||||
? buildDefaultJoinColumnsForToOne( override.getProperty(), override )
|
||||
: joinColumns;
|
||||
}
|
||||
else {
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.cfg;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -67,12 +68,12 @@ public class CopyIdentifierComponentSecondPass extends FkSecondPass {
|
|||
|
||||
@Override
|
||||
public void doSecondPass(Map<String, PersistentClass> persistentClasses) throws MappingException {
|
||||
PersistentClass referencedPersistentClass = persistentClasses.get( referencedEntityName );
|
||||
final PersistentClass referencedPersistentClass = persistentClasses.get( referencedEntityName );
|
||||
if ( referencedPersistentClass == null ) {
|
||||
// TODO: much better error message if this is something that can really happen!
|
||||
throw new AnnotationException( "Unknown entity name '" + referencedEntityName + "'");
|
||||
}
|
||||
KeyValue identifier = referencedPersistentClass.getIdentifier();
|
||||
final KeyValue identifier = referencedPersistentClass.getIdentifier();
|
||||
if ( !(identifier instanceof Component) ) {
|
||||
// The entity with the @MapsId annotation has a composite
|
||||
// id type, but the referenced entity has a basic-typed id.
|
||||
|
@ -87,13 +88,13 @@ public class CopyIdentifierComponentSecondPass extends FkSecondPass {
|
|||
);
|
||||
}
|
||||
|
||||
Component referencedComponent = (Component) identifier;
|
||||
final Component referencedComponent = (Component) identifier;
|
||||
|
||||
//prepare column name structure
|
||||
boolean isExplicitReference = true;
|
||||
final AnnotatedJoinColumn[] cols = joinColumns.getColumns();
|
||||
final Map<String, AnnotatedJoinColumn> columnByReferencedName = mapOfSize( cols.length );
|
||||
for ( AnnotatedJoinColumn joinColumn : cols) {
|
||||
final List<AnnotatedJoinColumn> columns = joinColumns.getJoinColumns();
|
||||
final Map<String, AnnotatedJoinColumn> columnByReferencedName = mapOfSize( columns.size() );
|
||||
for ( AnnotatedJoinColumn joinColumn : columns ) {
|
||||
if ( !joinColumn.isReferenceImplicit() ) {
|
||||
//JPA 2 requires referencedColumnNames to be case-insensitive
|
||||
columnByReferencedName.put( joinColumn.getReferencedColumn().toLowerCase(Locale.ROOT), joinColumn );
|
||||
|
@ -102,8 +103,8 @@ public class CopyIdentifierComponentSecondPass extends FkSecondPass {
|
|||
//try default column orientation
|
||||
if ( columnByReferencedName.isEmpty() ) {
|
||||
isExplicitReference = false;
|
||||
for (int i = 0; i < cols.length; i++ ) {
|
||||
columnByReferencedName.put( String.valueOf( i ), cols[i] );
|
||||
for (int i = 0; i < columns.size(); i++ ) {
|
||||
columnByReferencedName.put( String.valueOf( i ), columns.get(i) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,7 +186,8 @@ public class CopyIdentifierComponentSecondPass extends FkSecondPass {
|
|||
final SimpleValue referencedValue = (SimpleValue) referencedProperty.getValue();
|
||||
value.copyTypeFrom( referencedValue );
|
||||
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getColumns()[0];
|
||||
//TODO: this bit is nasty, move up to AnnotatedJoinColumns
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getJoinColumns().get(0);
|
||||
if ( firstColumn.isNameDeferred() ) {
|
||||
firstColumn.copyReferencedStructureAndCreateDefaultJoinColumns(
|
||||
referencedPersistentClass,
|
||||
|
|
|
@ -29,53 +29,48 @@ public class IndexColumn extends AnnotatedColumn {
|
|||
}
|
||||
|
||||
public static IndexColumn fromAnnotations(
|
||||
OrderColumn jpaAnnotation,
|
||||
org.hibernate.annotations.IndexColumn hibAnnotation,
|
||||
ListIndexBase indexBaseAnnotation,
|
||||
OrderColumn orderColumn,
|
||||
org.hibernate.annotations.IndexColumn indexColumn,
|
||||
ListIndexBase listIndexBase,
|
||||
PropertyHolder propertyHolder,
|
||||
PropertyData inferredData,
|
||||
Map<String, Join> secondaryTables,
|
||||
MetadataBuildingContext context) {
|
||||
final IndexColumn column;
|
||||
if ( jpaAnnotation != null ) {
|
||||
column = buildColumnFromAnnotation(
|
||||
jpaAnnotation,
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
secondaryTables,
|
||||
context
|
||||
);
|
||||
if ( orderColumn != null ) {
|
||||
column = buildColumnFromAnnotation( orderColumn, propertyHolder, inferredData, secondaryTables, context );
|
||||
}
|
||||
else if ( hibAnnotation != null ) {
|
||||
column = buildColumnFromAnnotation(
|
||||
hibAnnotation,
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
context
|
||||
);
|
||||
column.setBase( hibAnnotation.base() );
|
||||
else if ( indexColumn != null ) {
|
||||
column = buildColumnFromAnnotation( indexColumn, propertyHolder, inferredData, context );
|
||||
column.setBase( indexColumn.base() );
|
||||
}
|
||||
else {
|
||||
column = new IndexColumn();
|
||||
column.setLogicalColumnName( inferredData.getPropertyName() + "_ORDER" ); //JPA default name
|
||||
column.setImplicit( true );
|
||||
column.setBuildingContext( context );
|
||||
// column.setContext( context );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
createParent( propertyHolder, column );
|
||||
createParent( propertyHolder, secondaryTables, column, context );
|
||||
column.bind();
|
||||
}
|
||||
|
||||
if ( indexBaseAnnotation != null ) {
|
||||
column.setBase( indexBaseAnnotation.value() );
|
||||
if ( listIndexBase != null ) {
|
||||
column.setBase( listIndexBase.value() );
|
||||
}
|
||||
|
||||
return column;
|
||||
}
|
||||
|
||||
private static void createParent(PropertyHolder propertyHolder, IndexColumn column) {
|
||||
final AnnotatedColumns columns = new AnnotatedColumns();
|
||||
columns.setColumns( new AnnotatedColumn[] {column} );
|
||||
columns.setPropertyHolder( propertyHolder );
|
||||
private static void createParent(
|
||||
PropertyHolder propertyHolder,
|
||||
Map<String,Join> secondaryTables,
|
||||
IndexColumn column,
|
||||
MetadataBuildingContext context) {
|
||||
final AnnotatedColumns parent = new AnnotatedColumns();
|
||||
parent.setPropertyHolder( propertyHolder );
|
||||
parent.setJoins( secondaryTables );
|
||||
parent.setBuildingContext( context );
|
||||
column.setParent( parent );
|
||||
}
|
||||
|
||||
public int getBase() {
|
||||
|
@ -101,30 +96,29 @@ public class IndexColumn extends AnnotatedColumn {
|
|||
PropertyHolder propertyHolder,
|
||||
PropertyData inferredData,
|
||||
Map<String, Join> secondaryTables,
|
||||
MetadataBuildingContext buildingContext) {
|
||||
MetadataBuildingContext context) {
|
||||
if ( orderColumn != null ) {
|
||||
final String sqlType = isEmptyAnnotationValue( orderColumn.columnDefinition() ) ? null : orderColumn.columnDefinition();
|
||||
final String name = isEmptyAnnotationValue( orderColumn.name() ) ? inferredData.getPropertyName() + "_ORDER" : orderColumn.name();
|
||||
//TODO move it to a getter based system and remove the constructor
|
||||
final IndexColumn column = new IndexColumn();
|
||||
column.setLogicalColumnName( name );
|
||||
column.setSqlType( sqlType );
|
||||
column.setNullable( orderColumn.nullable() );
|
||||
column.setJoins( secondaryTables );
|
||||
// column.setJoins( secondaryTables );
|
||||
column.setInsertable( orderColumn.insertable() );
|
||||
column.setUpdatable( orderColumn.updatable() );
|
||||
column.setBuildingContext( buildingContext );
|
||||
// column.setContext( context );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
createParent( propertyHolder, column );
|
||||
createParent( propertyHolder, secondaryTables, column, context );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
else {
|
||||
final IndexColumn column = new IndexColumn();
|
||||
column.setImplicit( true );
|
||||
column.setBuildingContext( buildingContext );
|
||||
// column.setContext( context );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
createParent( propertyHolder, column );
|
||||
createParent( propertyHolder, secondaryTables, column, context );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
|
@ -133,38 +127,38 @@ public class IndexColumn extends AnnotatedColumn {
|
|||
/**
|
||||
* Legacy {@link IndexColumn @IndexColumn} processing.
|
||||
*
|
||||
* @param ann The IndexColumn annotation instance
|
||||
* @param indexColumn The IndexColumn annotation instance
|
||||
* @param propertyHolder Information about the property
|
||||
* @param inferredData Yeah, right. Uh...
|
||||
*
|
||||
* @return The index column
|
||||
*/
|
||||
public static IndexColumn buildColumnFromAnnotation(
|
||||
org.hibernate.annotations.IndexColumn ann,
|
||||
org.hibernate.annotations.IndexColumn indexColumn,
|
||||
PropertyHolder propertyHolder,
|
||||
PropertyData inferredData,
|
||||
MetadataBuildingContext buildingContext) {
|
||||
if ( ann != null ) {
|
||||
final String sqlType = isEmptyAnnotationValue( ann.columnDefinition() ) ? null : ann.columnDefinition();
|
||||
final String name = isEmptyAnnotationValue( ann.name() ) ? inferredData.getPropertyName() : ann.name();
|
||||
MetadataBuildingContext context) {
|
||||
if ( indexColumn != null ) {
|
||||
final String sqlType = isEmptyAnnotationValue( indexColumn.columnDefinition() ) ? null : indexColumn.columnDefinition();
|
||||
final String name = isEmptyAnnotationValue( indexColumn.name() ) ? inferredData.getPropertyName() : indexColumn.name();
|
||||
//TODO move it to a getter based system and remove the constructor
|
||||
final IndexColumn column = new IndexColumn();
|
||||
column.setLogicalColumnName( name );
|
||||
column.setSqlType( sqlType );
|
||||
column.setNullable( ann.nullable() );
|
||||
column.setBase( ann.base() );
|
||||
column.setBuildingContext( buildingContext );
|
||||
column.setNullable( indexColumn.nullable() );
|
||||
column.setBase( indexColumn.base() );
|
||||
// column.setContext( context );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
createParent( propertyHolder, column );
|
||||
createParent( propertyHolder, null, column, context );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
else {
|
||||
final IndexColumn column = new IndexColumn();
|
||||
column.setImplicit( true );
|
||||
column.setBuildingContext( buildingContext );
|
||||
// column.setContext( context );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
createParent( propertyHolder, column );
|
||||
createParent( propertyHolder, null, column, context );
|
||||
column.bind();
|
||||
return column;
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ public class ToOneBinder {
|
|||
final JoinTable joinTable = propertyHolder.getJoinTable( property );
|
||||
if ( joinTable != null ) {
|
||||
final Join join = propertyHolder.addJoin( joinTable, false );
|
||||
for ( AnnotatedJoinColumn joinColumn : joinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn joinColumn : joinColumns.getJoinColumns() ) {
|
||||
joinColumn.setExplicitTableName( join.getTable().getName() );
|
||||
}
|
||||
}
|
||||
|
@ -155,14 +155,14 @@ public class ToOneBinder {
|
|||
value.setCascadeDeleteEnabled( cascadeOnDelete );
|
||||
//value.setLazy( fetchMode != FetchMode.JOIN );
|
||||
if ( !optional ) {
|
||||
for ( AnnotatedJoinColumn column : joinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn column : joinColumns.getJoinColumns() ) {
|
||||
column.setNullable( false );
|
||||
}
|
||||
}
|
||||
|
||||
if ( property.isAnnotationPresent( MapsId.class ) ) {
|
||||
//read only
|
||||
for ( AnnotatedJoinColumn column : joinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn column : joinColumns.getJoinColumns() ) {
|
||||
column.setInsertable( false );
|
||||
column.setUpdatable( false );
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ public class ToOneBinder {
|
|||
&& joinColumn.name().equals( columnName )
|
||||
&& !property.isAnnotationPresent( MapsId.class ) ) {
|
||||
hasSpecjManyToOne = true;
|
||||
for ( AnnotatedJoinColumn column : columns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn column : columns.getJoinColumns() ) {
|
||||
column.setInsertable( false );
|
||||
column.setUpdatable( false );
|
||||
}
|
||||
|
@ -256,16 +256,16 @@ public class ToOneBinder {
|
|||
propertyBinder.setName( propertyName );
|
||||
propertyBinder.setValue( value );
|
||||
//binder.setCascade(cascadeStrategy);
|
||||
if (isIdentifierMapper) {
|
||||
if ( isIdentifierMapper ) {
|
||||
propertyBinder.setInsertable( false );
|
||||
propertyBinder.setUpdatable( false );
|
||||
}
|
||||
else if (hasSpecjManyToOne) {
|
||||
else if ( hasSpecjManyToOne ) {
|
||||
propertyBinder.setInsertable( false );
|
||||
propertyBinder.setUpdatable( false );
|
||||
}
|
||||
else {
|
||||
final AnnotatedJoinColumn firstColumn = columns.getColumns()[0];
|
||||
final AnnotatedJoinColumn firstColumn = columns.getJoinColumns().get(0);
|
||||
propertyBinder.setInsertable( firstColumn.isInsertable() );
|
||||
propertyBinder.setUpdatable( firstColumn.isUpdatable() );
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ public class ToOneBinder {
|
|||
if ( notFoundAction != null ) {
|
||||
join.disableForeignKeyCreation();
|
||||
}
|
||||
for ( AnnotatedJoinColumn joinColumn : joinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn joinColumn : joinColumns.getJoinColumns() ) {
|
||||
joinColumn.setExplicitTableName( join.getTable().getName() );
|
||||
}
|
||||
}
|
||||
|
@ -493,16 +493,16 @@ public class ToOneBinder {
|
|||
}
|
||||
else {
|
||||
final List<String> idColumnNames = new ArrayList<>();
|
||||
final AnnotatedJoinColumn[] columns = joinColumns.getColumns();
|
||||
if ( identifier.getColumnSpan() != columns.length ) {
|
||||
final List<AnnotatedJoinColumn> columns = joinColumns.getJoinColumns();
|
||||
if ( identifier.getColumnSpan() != columns.size() ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
for ( org.hibernate.mapping.Column currentColumn: identifier.getColumns() ) {
|
||||
idColumnNames.add( currentColumn.getName() );
|
||||
}
|
||||
for ( AnnotatedJoinColumn col: columns ) {
|
||||
if ( !idColumnNames.contains( col.getMappingColumn().getName() ) ) {
|
||||
for ( AnnotatedJoinColumn column: columns ) {
|
||||
if ( !idColumnNames.contains( column.getMappingColumn().getName() ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ import org.hibernate.boot.spi.MetadataBuildingContext;
|
|||
import org.hibernate.cfg.AccessType;
|
||||
import org.hibernate.cfg.AnnotatedColumn;
|
||||
import org.hibernate.cfg.AnnotatedColumns;
|
||||
import org.hibernate.cfg.AnnotatedJoinColumn;
|
||||
import org.hibernate.cfg.AnnotatedJoinColumns;
|
||||
import org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass;
|
||||
import org.hibernate.cfg.SetBasicValueTypeSecondPass;
|
||||
|
@ -103,8 +102,8 @@ import static org.hibernate.cfg.annotations.HCANNHelper.findAnnotation;
|
|||
*/
|
||||
public class BasicValueBinder implements JdbcTypeIndicators {
|
||||
|
||||
// todo (6.0) : In light of how we want to build Types (specifically BasicTypes) moving forward this class should undergo major changes
|
||||
// see the comments in #setType
|
||||
// todo (6.0) : In light of how we want to build Types (specifically BasicTypes) moving
|
||||
// forward this class should undergo major changes: see the comments in #setType
|
||||
// but as always the "design" of these classes make it unclear exactly how to change it properly.
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, BasicValueBinder.class.getName() );
|
||||
|
@ -1126,13 +1125,17 @@ public class BasicValueBinder implements JdbcTypeIndicators {
|
|||
|
||||
public void linkWithValue() {
|
||||
final InFlightMetadataCollector collector = buildingContext.getMetadataCollector();
|
||||
final AnnotatedColumn firstColumn = columns.getColumns()[0];
|
||||
final AnnotatedColumn firstColumn = columns.getColumns().get(0);
|
||||
if ( !collector.isInSecondPass() && firstColumn.isNameDeferred() && referencedEntityName != null ) {
|
||||
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
|
||||
joinColumns.setBuildingContext( buildingContext );
|
||||
joinColumns.setPropertyHolder( firstColumn.getPropertyHolder() );
|
||||
joinColumns.setPropertyHolder( columns.getPropertyHolder() );
|
||||
joinColumns.setPropertyName( firstColumn.getPropertyName() );
|
||||
joinColumns.setColumns( (AnnotatedJoinColumn[]) columns.getColumns() );
|
||||
//TODO: resetting the parent here looks like a dangerous thing to do
|
||||
// should we be cloning them first (the legacy code did not)
|
||||
for ( AnnotatedColumn column : columns.getColumns() ) {
|
||||
column.setParent( joinColumns );
|
||||
}
|
||||
collector.addSecondPass(
|
||||
new PkDrivenByDefaultMapsIdSecondPass( referencedEntityName, joinColumns, basicValue )
|
||||
);
|
||||
|
|
|
@ -174,7 +174,6 @@ import static org.hibernate.internal.util.StringHelper.isEmpty;
|
|||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||
import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
|
||||
import static org.hibernate.internal.util.StringHelper.qualify;
|
||||
import static org.hibernate.internal.util.collections.ArrayHelper.isEmpty;
|
||||
|
||||
/**
|
||||
* Base class for binding different types of collections to Hibernate configuration objects.
|
||||
|
@ -306,6 +305,7 @@ public abstract class CollectionBinder {
|
|||
|
||||
collectionBinder.setCache( property.getAnnotation( Cache.class ) );
|
||||
collectionBinder.setPropertyHolder(propertyHolder);
|
||||
|
||||
final Cascade hibernateCascade = property.getAnnotation( Cascade.class );
|
||||
final NotFound notFound = property.getAnnotation( NotFound.class );
|
||||
if ( notFound != null ) {
|
||||
|
@ -315,6 +315,7 @@ public abstract class CollectionBinder {
|
|||
}
|
||||
collectionBinder.setNotFoundAction( notFound.action() );
|
||||
}
|
||||
|
||||
collectionBinder.setElementType( inferredData.getProperty().getElementClass() );
|
||||
collectionBinder.setAccessType( inferredData.getDefaultAccess() );
|
||||
|
||||
|
@ -332,17 +333,16 @@ public abstract class CollectionBinder {
|
|||
virtualProperty,
|
||||
comment
|
||||
);
|
||||
final JoinColumn[] joinKeyColumns = mapKeyColumns(
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
entityBinder,
|
||||
context,
|
||||
property,
|
||||
collectionBinder,
|
||||
comment
|
||||
);
|
||||
final AnnotatedJoinColumns mapJoinColumns = buildJoinColumnsWithDefaultColumnSuffix(
|
||||
joinKeyColumns,
|
||||
mapKeyColumns(
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
entityBinder,
|
||||
context,
|
||||
property,
|
||||
collectionBinder,
|
||||
comment
|
||||
),
|
||||
comment,
|
||||
null,
|
||||
entityBinder.getSecondaryTables(),
|
||||
|
@ -356,20 +356,7 @@ public abstract class CollectionBinder {
|
|||
//potential element
|
||||
collectionBinder.setEmbedded( property.isAnnotationPresent( Embedded.class ) );
|
||||
collectionBinder.setElementColumns( elementColumns );
|
||||
collectionBinder.setProperty(property);
|
||||
|
||||
final String mappedBy = handleTargetEntity(
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
context,
|
||||
property,
|
||||
joinColumns,
|
||||
oneToManyAnn,
|
||||
manyToManyAnn,
|
||||
elementCollectionAnn,
|
||||
collectionBinder,
|
||||
hibernateCascade
|
||||
);
|
||||
collectionBinder.setProperty( property );
|
||||
|
||||
bindJoinedTableAssociation(
|
||||
property,
|
||||
|
@ -378,23 +365,34 @@ public abstract class CollectionBinder {
|
|||
collectionBinder,
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
mappedBy
|
||||
handleTargetEntity(
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
context,
|
||||
property,
|
||||
joinColumns,
|
||||
oneToManyAnn,
|
||||
manyToManyAnn,
|
||||
elementCollectionAnn,
|
||||
collectionBinder,
|
||||
hibernateCascade
|
||||
)
|
||||
);
|
||||
|
||||
final OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
|
||||
final boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE == onDeleteAnn.action();
|
||||
final OnDelete onDelete = property.getAnnotation( OnDelete.class );
|
||||
final boolean onDeleteCascade = onDelete != null && OnDeleteAction.CASCADE == onDelete.action();
|
||||
collectionBinder.setCascadeDeleteEnabled( onDeleteCascade );
|
||||
if ( isIdentifierMapper ) {
|
||||
collectionBinder.setInsertable( false );
|
||||
collectionBinder.setUpdatable( false );
|
||||
}
|
||||
if ( property.isAnnotationPresent( CollectionId.class ) ) { //do not compute the generators unless necessary
|
||||
HashMap<String, IdentifierGeneratorDefinition> localGenerators = new HashMap<>(classGenerators);
|
||||
localGenerators.putAll( AnnotationBinder.buildGenerators(property, context) );
|
||||
final HashMap<String, IdentifierGeneratorDefinition> localGenerators = new HashMap<>(classGenerators);
|
||||
localGenerators.putAll( AnnotationBinder.buildGenerators( property, context ) );
|
||||
collectionBinder.setLocalGenerators( localGenerators );
|
||||
|
||||
}
|
||||
collectionBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
|
||||
collectionBinder.setInheritanceStatePerClass( inheritanceStatePerClass );
|
||||
collectionBinder.setDeclaringClass( inferredData.getDeclaringClass() );
|
||||
collectionBinder.bind();
|
||||
}
|
||||
|
@ -419,7 +417,7 @@ public abstract class CollectionBinder {
|
|||
final String mappedBy;
|
||||
final ReflectionManager reflectionManager = context.getBootstrapContext().getReflectionManager();
|
||||
if ( oneToManyAnn != null ) {
|
||||
for ( AnnotatedJoinColumn column : joinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn column : joinColumns.getJoinColumns() ) {
|
||||
if ( column.isSecondary() ) {
|
||||
//TODO: fix the error message
|
||||
throw new NotYetImplementedException( "Collections having FK in secondary table" );
|
||||
|
@ -435,7 +433,7 @@ public abstract class CollectionBinder {
|
|||
collectionBinder.setOneToMany( true );
|
||||
}
|
||||
else if ( elementCollectionAnn != null ) {
|
||||
for ( AnnotatedJoinColumn column : joinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn column : joinColumns.getJoinColumns() ) {
|
||||
if ( column.isSecondary() ) {
|
||||
//TODO: fix the error message
|
||||
throw new NotYetImplementedException( "Collections having FK in secondary table" );
|
||||
|
@ -1499,8 +1497,8 @@ public abstract class CollectionBinder {
|
|||
&& !reversePropertyInJoin
|
||||
&& oneToMany
|
||||
&& !isExplicitAssociationTable
|
||||
&& ( joinColumns.getColumns()[0].isImplicit() && hasMappedBy() //implicit @JoinColumn
|
||||
|| !foreignJoinColumns.getColumns()[0].isImplicit() ) //this is an explicit @JoinColumn
|
||||
&& ( joinColumns.getJoinColumns().get(0).isImplicit() && hasMappedBy() //implicit @JoinColumn
|
||||
|| !foreignJoinColumns.getJoinColumns().get(0).isImplicit() ) //this is an explicit @JoinColumn
|
||||
) {
|
||||
//this is a foreign key
|
||||
bindOneToManySecondPass( persistentClasses );
|
||||
|
@ -1546,9 +1544,7 @@ public abstract class CollectionBinder {
|
|||
|
||||
final Map<String, Join> joins = buildingContext.getMetadataCollector().getJoins( referencedEntityName );
|
||||
foreignJoinColumns.setPersistentClass( associatedClass, joins, inheritanceStatePerClass );
|
||||
for ( AnnotatedJoinColumn column : foreignJoinColumns.getColumns() ) {
|
||||
column.setJoins( joins );
|
||||
}
|
||||
foreignJoinColumns.setJoins( joins );
|
||||
collection.setCollectionTable( foreignJoinColumns.getTable() );
|
||||
if ( LOG.isDebugEnabled() ) {
|
||||
LOG.debugf( "Mapping collection: %s -> %s", collection.getRole(), collection.getCollectionTable().getName() );
|
||||
|
@ -1572,7 +1568,7 @@ public abstract class CollectionBinder {
|
|||
final PersistentClass referenced = collector.getEntityBinding( entityName );
|
||||
final Backref backref = new Backref();
|
||||
final String backrefName = '_' + foreignJoinColumns.getPropertyName()
|
||||
+ '_' + foreignJoinColumns.getColumns()[0].getLogicalColumnName()
|
||||
+ '_' + foreignJoinColumns.getColumns().get(0).getLogicalColumnName()
|
||||
+ "Backref";
|
||||
backref.setName( backrefName );
|
||||
backref.setUpdateable( false);
|
||||
|
@ -1856,10 +1852,10 @@ public abstract class CollectionBinder {
|
|||
|
||||
final DependantValue key = new DependantValue( buildingContext, collection.getCollectionTable(), keyValue );
|
||||
key.setTypeName( null );
|
||||
final AnnotatedJoinColumn[] columns = joinColumns.getColumns();
|
||||
final List<AnnotatedColumn> columns = joinColumns.getColumns();
|
||||
checkPropertyConsistency( columns, collection.getOwnerEntityName() );
|
||||
key.setNullable( columns.length == 0 || columns[0].isNullable() );
|
||||
key.setUpdateable( columns.length == 0 || columns[0].isUpdatable() );
|
||||
key.setNullable( columns.isEmpty() || columns.get(0).isNullable() );
|
||||
key.setUpdateable( columns.isEmpty() || columns.get(0).isUpdatable() );
|
||||
key.setCascadeDeleteEnabled( cascadeDeleteEnabled );
|
||||
collection.setKey( key );
|
||||
|
||||
|
@ -1958,7 +1954,7 @@ public abstract class CollectionBinder {
|
|||
}
|
||||
|
||||
private void overrideReferencedPropertyName(Collection collection, AnnotatedJoinColumns joinColumns) {
|
||||
if ( hasMappedBy() && joinColumns.getColumns().length > 0 ) {
|
||||
if ( hasMappedBy() && !joinColumns.getColumns().isEmpty() ) {
|
||||
final String entityName = joinColumns.getManyToManyOwnerSideEntityName() != null
|
||||
? "inverse__" + joinColumns.getManyToManyOwnerSideEntityName()
|
||||
: joinColumns.getPropertyHolder().getEntityName();
|
||||
|
@ -2199,22 +2195,21 @@ public abstract class CollectionBinder {
|
|||
String defaultName,
|
||||
Long defaultLength,
|
||||
MetadataBuildingContext context) {
|
||||
if ( elementColumns == null || isEmpty( elementColumns.getColumns() ) ) {
|
||||
if ( elementColumns == null || elementColumns.getColumns().isEmpty() ) {
|
||||
final AnnotatedColumns columns = new AnnotatedColumns();
|
||||
columns.setBuildingContext( context );
|
||||
final AnnotatedColumn column = new AnnotatedColumn();
|
||||
column.setLogicalColumnName( defaultName );
|
||||
if ( defaultLength!=null ) {
|
||||
if ( defaultLength != null ) {
|
||||
column.setLength( defaultLength );
|
||||
}
|
||||
column.setImplicit( false );
|
||||
//not following the spec but more clean
|
||||
column.setNullable( true );
|
||||
//TODO create an EMPTY_JOINS collection
|
||||
column.setJoins( new HashMap<>() );
|
||||
column.setBuildingContext( context );
|
||||
// column.setContext( context );
|
||||
column.setParent( columns );
|
||||
column.bind();
|
||||
final AnnotatedColumns result = new AnnotatedColumns();
|
||||
result.setColumns( new AnnotatedColumn[] { column } );
|
||||
elementColumns = result;
|
||||
elementColumns = columns;
|
||||
}
|
||||
//override the table
|
||||
elementColumns.setTable( collection.getCollectionTable() );
|
||||
|
@ -2560,7 +2555,7 @@ public abstract class CollectionBinder {
|
|||
if ( hasMappedBy() ) {
|
||||
final Property property = targetEntity.getRecursiveProperty( mappedBy );
|
||||
final List<Selectable> mappedByColumns = mappedByColumns( targetEntity, property );
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getColumns()[0];
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getJoinColumns().get(0);
|
||||
for ( Selectable selectable: mappedByColumns ) {
|
||||
firstColumn.linkValueUsingAColumnCopy( (Column) selectable, value );
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ public class EntityBinder {
|
|||
//TODO: be more strict with secondary table allowance (not for ids, not for secondary table join columns etc)
|
||||
final InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess );
|
||||
final PersistentClass superEntity = getSuperEntity( clazzToProcess, inheritanceStatePerClass, context, inheritanceState );
|
||||
detectedAttributeOverrideProblem(clazzToProcess, superEntity );
|
||||
detectedAttributeOverrideProblem( clazzToProcess, superEntity );
|
||||
|
||||
final PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity, context);
|
||||
final EntityBinder entityBinder = new EntityBinder( clazzToProcess, persistentClass, context );
|
||||
|
@ -789,11 +789,13 @@ public class EntityBinder {
|
|||
if ( discriminatorColumn == null ) {
|
||||
throw new AssertionFailure( "discriminator column should have been built" );
|
||||
}
|
||||
discriminatorColumn.setJoins( secondaryTables );
|
||||
// discriminatorColumn.setPropertyHolder( propertyHolder );
|
||||
final AnnotatedColumns columns = new AnnotatedColumns();
|
||||
columns.setColumns( new AnnotatedColumn[] { discriminatorColumn } );
|
||||
columns.setPropertyHolder( propertyHolder );
|
||||
columns.setBuildingContext( context );
|
||||
columns.setJoins( secondaryTables );
|
||||
// discriminatorColumn.setJoins( secondaryTables );
|
||||
// discriminatorColumn.setPropertyHolder( propertyHolder );
|
||||
discriminatorColumn.setParent( columns );
|
||||
|
||||
final BasicValue discriminatorColumnBinding = new BasicValue( context, rootClass.getTable() );
|
||||
rootClass.setDiscriminator( discriminatorColumnBinding );
|
||||
|
@ -817,16 +819,19 @@ public class EntityBinder {
|
|||
InheritanceState inheritanceState,
|
||||
EntityBinder entityBinder) {
|
||||
|
||||
DiscriminatorColumn discAnn = clazzToProcess.getAnnotation( DiscriminatorColumn.class );
|
||||
DiscriminatorType discriminatorType = discAnn != null ? discAnn.discriminatorType() : DiscriminatorType.STRING;
|
||||
final DiscriminatorColumn discriminatorColumn = clazzToProcess.getAnnotation( DiscriminatorColumn.class );
|
||||
final DiscriminatorType discriminatorType = discriminatorColumn != null
|
||||
? discriminatorColumn.discriminatorType()
|
||||
: DiscriminatorType.STRING;
|
||||
|
||||
DiscriminatorFormula discFormulaAnn = getOverridableAnnotation( clazzToProcess, DiscriminatorFormula.class, context );
|
||||
final DiscriminatorFormula discriminatorFormula =
|
||||
getOverridableAnnotation( clazzToProcess, DiscriminatorFormula.class, context );
|
||||
|
||||
final boolean isRoot = !inheritanceState.hasParents();
|
||||
final AnnotatedDiscriminatorColumn discriminatorColumn = isRoot
|
||||
? buildDiscriminatorColumn( discriminatorType, discAnn, discFormulaAnn, context )
|
||||
final AnnotatedDiscriminatorColumn discriminator = isRoot
|
||||
? buildDiscriminatorColumn( discriminatorType, discriminatorColumn, discriminatorFormula, context )
|
||||
: null;
|
||||
if ( discAnn != null && !isRoot ) {
|
||||
if ( discriminatorColumn != null && !isRoot ) {
|
||||
//TODO: shouldn't this be an error?!
|
||||
LOG.invalidDiscriminatorAnnotation( clazzToProcess.getName() );
|
||||
}
|
||||
|
@ -836,13 +841,13 @@ public class EntityBinder {
|
|||
: null;
|
||||
entityBinder.setDiscriminatorValue( discriminatorValue );
|
||||
|
||||
DiscriminatorOptions discriminatorOptions = clazzToProcess.getAnnotation( DiscriminatorOptions.class );
|
||||
final DiscriminatorOptions discriminatorOptions = clazzToProcess.getAnnotation( DiscriminatorOptions.class );
|
||||
if ( discriminatorOptions != null) {
|
||||
entityBinder.setForceDiscriminator( discriminatorOptions.force() );
|
||||
entityBinder.setInsertableDiscriminator( discriminatorOptions.insert() );
|
||||
}
|
||||
|
||||
return discriminatorColumn;
|
||||
return discriminator;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -997,58 +1002,62 @@ public class EntityBinder {
|
|||
InheritanceState inheritanceState,
|
||||
PersistentClass superEntity) {
|
||||
|
||||
AnnotatedJoinColumn[] inheritanceJoinedColumns = null;
|
||||
final boolean hasJoinedColumns = inheritanceState.hasParents()
|
||||
&& InheritanceType.JOINED == inheritanceState.getType();
|
||||
if ( hasJoinedColumns ) {
|
||||
//@Inheritance(JOINED) subclass need to link back to the super entity
|
||||
final PrimaryKeyJoinColumns jcsAnn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumns.class );
|
||||
boolean explicitInheritanceJoinedColumns = jcsAnn != null && jcsAnn.value().length != 0;
|
||||
if ( explicitInheritanceJoinedColumns ) {
|
||||
int nbrOfInhJoinedColumns = jcsAnn.value().length;
|
||||
PrimaryKeyJoinColumn jcAnn;
|
||||
inheritanceJoinedColumns = new AnnotatedJoinColumn[nbrOfInhJoinedColumns];
|
||||
for ( int colIndex = 0; colIndex < nbrOfInhJoinedColumns; colIndex++ ) {
|
||||
jcAnn = jcsAnn.value()[colIndex];
|
||||
inheritanceJoinedColumns[colIndex] = buildJoinColumn(
|
||||
jcAnn,
|
||||
null,
|
||||
superEntity.getIdentifier(),
|
||||
null,
|
||||
null,
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PrimaryKeyJoinColumn jcAnn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class );
|
||||
inheritanceJoinedColumns = new AnnotatedJoinColumn[1];
|
||||
inheritanceJoinedColumns[0] = buildJoinColumn(
|
||||
jcAnn,
|
||||
null,
|
||||
superEntity.getIdentifier(),
|
||||
null,
|
||||
null,
|
||||
context
|
||||
);
|
||||
}
|
||||
LOG.trace( "Subclass joined column(s) created" );
|
||||
return subclassJoinColumns( clazzToProcess, superEntity, context );
|
||||
}
|
||||
else {
|
||||
if ( clazzToProcess.isAnnotationPresent( PrimaryKeyJoinColumns.class )
|
||||
|| clazzToProcess.isAnnotationPresent( PrimaryKeyJoinColumn.class ) ) {
|
||||
LOG.invalidPrimaryKeyJoinColumnAnnotation( clazzToProcess.getName() );
|
||||
}
|
||||
}
|
||||
if ( inheritanceJoinedColumns == null ) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
|
||||
joinColumns.setBuildingContext( context );
|
||||
joinColumns.setColumns( inheritanceJoinedColumns );
|
||||
return joinColumns;
|
||||
}
|
||||
|
||||
private static AnnotatedJoinColumns subclassJoinColumns(
|
||||
XClass clazzToProcess,
|
||||
PersistentClass superEntity,
|
||||
MetadataBuildingContext context) {
|
||||
//@Inheritance(JOINED) subclass need to link back to the super entity
|
||||
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
|
||||
joinColumns.setBuildingContext( context );
|
||||
final PrimaryKeyJoinColumns primaryKeyJoinColumns = clazzToProcess.getAnnotation( PrimaryKeyJoinColumns.class );
|
||||
if ( primaryKeyJoinColumns != null ) {
|
||||
final PrimaryKeyJoinColumn[] columns = primaryKeyJoinColumns.value();
|
||||
if ( columns.length > 0 ) {
|
||||
for ( PrimaryKeyJoinColumn column : columns ) {
|
||||
buildJoinColumn(
|
||||
column,
|
||||
null,
|
||||
superEntity.getIdentifier(),
|
||||
joinColumns,
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
buildJoinColumn(
|
||||
clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class ),
|
||||
null,
|
||||
superEntity.getIdentifier(),
|
||||
joinColumns,
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
buildJoinColumn(
|
||||
clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class ),
|
||||
null,
|
||||
superEntity.getIdentifier(),
|
||||
joinColumns,
|
||||
context
|
||||
);
|
||||
}
|
||||
LOG.trace( "Subclass joined column(s) created" );
|
||||
return joinColumns;
|
||||
}
|
||||
|
||||
private static PersistentClass getSuperEntity(
|
||||
|
@ -1741,7 +1750,7 @@ public class EntityBinder {
|
|||
public void finalSecondaryTableBinding(PropertyHolder propertyHolder) {
|
||||
// This operation has to be done after the id definition of the persistence class.
|
||||
// ie after the properties parsing
|
||||
Iterator<Object> joinColumns = secondaryTableJoins.values().iterator();
|
||||
final Iterator<Object> joinColumns = secondaryTableJoins.values().iterator();
|
||||
for ( Map.Entry<String, Join> entrySet : secondaryTables.entrySet() ) {
|
||||
if ( !secondaryTablesFromAnnotation.containsKey( entrySet.getKey() ) ) {
|
||||
createPrimaryColumnsToSecondaryTable( joinColumns.next(), propertyHolder, entrySet.getValue() );
|
||||
|
@ -1771,56 +1780,52 @@ public class EntityBinder {
|
|||
? createDefaultJoinColumn( propertyHolder )
|
||||
: createJoinColumns( propertyHolder, pkColumnsAnn, joinColumnsAnn );
|
||||
|
||||
for ( AnnotatedJoinColumn joinColumn : annotatedJoinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn joinColumn : annotatedJoinColumns.getJoinColumns() ) {
|
||||
joinColumn.forceNotNull();
|
||||
}
|
||||
bindJoinToPersistentClass( join, annotatedJoinColumns, context );
|
||||
}
|
||||
|
||||
private AnnotatedJoinColumns createDefaultJoinColumn(PropertyHolder propertyHolder) {
|
||||
final AnnotatedJoinColumn[] annotatedJoinColumns = new AnnotatedJoinColumn[1];
|
||||
annotatedJoinColumns[0] = buildJoinColumn(
|
||||
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
|
||||
joinColumns.setBuildingContext( context );
|
||||
joinColumns.setJoins( secondaryTables );
|
||||
joinColumns.setPropertyHolder( propertyHolder );
|
||||
buildJoinColumn(
|
||||
null,
|
||||
null,
|
||||
persistentClass.getIdentifier(),
|
||||
secondaryTables,
|
||||
propertyHolder,
|
||||
joinColumns,
|
||||
context
|
||||
);
|
||||
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
|
||||
joinColumns.setBuildingContext( context );
|
||||
joinColumns.setPropertyHolder( propertyHolder );
|
||||
joinColumns.setColumns( annotatedJoinColumns );
|
||||
return joinColumns;
|
||||
}
|
||||
|
||||
private AnnotatedJoinColumns createJoinColumns(
|
||||
PropertyHolder propertyHolder,
|
||||
PrimaryKeyJoinColumn[] pkColumnsAnn,
|
||||
JoinColumn[] joinColumnsAnn) {
|
||||
final int joinColumnCount = pkColumnsAnn != null ? pkColumnsAnn.length : joinColumnsAnn.length;
|
||||
PrimaryKeyJoinColumn[] primaryKeyJoinColumns,
|
||||
JoinColumn[] joinColumns) {
|
||||
final int joinColumnCount = primaryKeyJoinColumns != null ? primaryKeyJoinColumns.length : joinColumns.length;
|
||||
if ( joinColumnCount == 0 ) {
|
||||
return createDefaultJoinColumn( propertyHolder );
|
||||
}
|
||||
else {
|
||||
final AnnotatedJoinColumn[] annotatedJoinColumns = new AnnotatedJoinColumn[joinColumnCount];
|
||||
for (int colIndex = 0; colIndex < joinColumnCount; colIndex++) {
|
||||
final PrimaryKeyJoinColumn pkJoinAnn = pkColumnsAnn != null ? pkColumnsAnn[colIndex] : null;
|
||||
final JoinColumn joinAnn = joinColumnsAnn != null ? joinColumnsAnn[colIndex] : null;
|
||||
annotatedJoinColumns[colIndex] = buildJoinColumn(
|
||||
pkJoinAnn,
|
||||
joinAnn,
|
||||
final AnnotatedJoinColumns columns = new AnnotatedJoinColumns();
|
||||
columns.setBuildingContext( context );
|
||||
columns.setJoins( secondaryTables );
|
||||
columns.setPropertyHolder( propertyHolder );
|
||||
for ( int colIndex = 0; colIndex < joinColumnCount; colIndex++ ) {
|
||||
final PrimaryKeyJoinColumn primaryKeyJoinColumn = primaryKeyJoinColumns != null ? primaryKeyJoinColumns[colIndex] : null;
|
||||
final JoinColumn joinColumn = joinColumns != null ? joinColumns[colIndex] : null;
|
||||
buildJoinColumn(
|
||||
primaryKeyJoinColumn,
|
||||
joinColumn,
|
||||
persistentClass.getIdentifier(),
|
||||
secondaryTables,
|
||||
propertyHolder,
|
||||
columns,
|
||||
context
|
||||
);
|
||||
}
|
||||
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
|
||||
joinColumns.setBuildingContext( context );
|
||||
joinColumns.setPropertyHolder( propertyHolder );
|
||||
joinColumns.setColumns( annotatedJoinColumns );
|
||||
return joinColumns;
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@ import java.util.function.Supplier;
|
|||
import org.hibernate.MappingException;
|
||||
import org.hibernate.annotations.OrderBy;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.cfg.AnnotatedColumn;
|
||||
import org.hibernate.cfg.AnnotatedColumns;
|
||||
import org.hibernate.cfg.CollectionSecondPass;
|
||||
import org.hibernate.cfg.PropertyHolder;
|
||||
import org.hibernate.cfg.PropertyHolderBuilder;
|
||||
|
@ -86,13 +84,10 @@ public class ListBinder extends CollectionBinder {
|
|||
if ( !listValueMapping.isOneToMany() ) {
|
||||
indexColumn.forceNotNull();
|
||||
}
|
||||
// indexColumn.setPropertyHolder( valueHolder );
|
||||
final AnnotatedColumns columns = new AnnotatedColumns();
|
||||
columns.setColumns( new AnnotatedColumn[] { indexColumn } );
|
||||
columns.setPropertyHolder( valueHolder );
|
||||
indexColumn.getParent().setPropertyHolder( valueHolder );
|
||||
|
||||
final BasicValueBinder valueBinder = new BasicValueBinder( BasicValueBinder.Kind.LIST_INDEX, buildingContext );
|
||||
valueBinder.setColumns( columns );
|
||||
valueBinder.setColumns( indexColumn.getParent() );
|
||||
valueBinder.setReturnedClassName( Integer.class.getName() );
|
||||
valueBinder.setType( property, getElementType(), null, null );
|
||||
// valueBinder.setExplicitType( "integer" );
|
||||
|
|
|
@ -100,8 +100,7 @@ public class MapBinder extends CollectionBinder {
|
|||
property,
|
||||
isEmbedded,
|
||||
mapKeyColumns,
|
||||
mapKeyManyToManyColumns,
|
||||
inverseJoinColumns != null ? inverseJoinColumns.getPropertyName() : null
|
||||
mapKeyManyToManyColumns
|
||||
);
|
||||
makeOneToManyMapKeyColumnNullableIfNotInProperty( property );
|
||||
}
|
||||
|
@ -157,8 +156,7 @@ public class MapBinder extends CollectionBinder {
|
|||
XProperty property,
|
||||
boolean isEmbedded,
|
||||
AnnotatedColumns mapKeyColumns,
|
||||
AnnotatedJoinColumns mapKeyManyToManyColumns,
|
||||
String targetPropertyName) {
|
||||
AnnotatedJoinColumns mapKeyManyToManyColumns) {
|
||||
if ( mapKeyPropertyName != null ) {
|
||||
//this is an EJB3 @MapKey
|
||||
handleExplicitMapKey( elementType, persistentClasses, mapKeyPropertyName );
|
||||
|
@ -205,7 +203,7 @@ public class MapBinder extends CollectionBinder {
|
|||
//FIXME pass the Index Entity JoinColumns
|
||||
if ( !collection.isOneToMany() ) {
|
||||
//index column should not be null
|
||||
for ( AnnotatedJoinColumn column : mapKeyManyToManyColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn column : mapKeyManyToManyColumns.getJoinColumns() ) {
|
||||
column.forceNotNull();
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +241,7 @@ public class MapBinder extends CollectionBinder {
|
|||
throw new AnnotationException( "Association '" + safeCollectionRole()
|
||||
+ "' targets the type '" + elementType.getName() + "' which is not an '@Entity' type" );
|
||||
}
|
||||
final Property mapProperty = findPropertyByName( associatedClass, mapKeyPropertyName);
|
||||
final Property mapProperty = findPropertyByName( associatedClass, mapKeyPropertyName );
|
||||
if ( mapProperty == null ) {
|
||||
throw new AnnotationException( "Map key property '" + mapKeyPropertyName
|
||||
+ "' not found in target entity '" + associatedClass.getEntityName() + "'" );
|
||||
|
@ -274,7 +272,7 @@ public class MapBinder extends CollectionBinder {
|
|||
// 'propertyHolder' is the PropertyHolder for the owner of the collection
|
||||
// 'holder' is the CollectionPropertyHolder.
|
||||
// 'property' is the collection XProperty
|
||||
propertyHolder.startingProperty(property);
|
||||
propertyHolder.startingProperty( property );
|
||||
holder.prepare(property);
|
||||
return holder;
|
||||
}
|
||||
|
@ -301,9 +299,9 @@ public class MapBinder extends CollectionBinder {
|
|||
String mapKeyType,
|
||||
org.hibernate.mapping.Map map) {
|
||||
final ManyToOne element;
|
||||
element = new ManyToOne(context, map.getCollectionTable() );
|
||||
element = new ManyToOne( context, map.getCollectionTable() );
|
||||
map.setIndex( element );
|
||||
element.setReferencedEntityName(mapKeyType);
|
||||
element.setReferencedEntityName( mapKeyType );
|
||||
//element.setFetchMode( fetchMode );
|
||||
//element.setLazy( fetchMode != FetchMode.JOIN );
|
||||
//make the second join non lazy
|
||||
|
@ -344,11 +342,8 @@ public class MapBinder extends CollectionBinder {
|
|||
AnnotatedClassType classType,
|
||||
CollectionPropertyHolder holder,
|
||||
AccessType accessType) {
|
||||
final Class<? extends CompositeUserType<?>> compositeUserType = resolveCompositeUserType(
|
||||
property,
|
||||
keyClass,
|
||||
buildingContext
|
||||
);
|
||||
final Class<? extends CompositeUserType<?>> compositeUserType =
|
||||
resolveCompositeUserType( property, keyClass, buildingContext );
|
||||
|
||||
if ( AnnotatedClassType.EMBEDDABLE == classType || compositeUserType != null ) {
|
||||
final EntityBinder entityBinder = new EntityBinder();
|
||||
|
@ -375,7 +370,7 @@ public class MapBinder extends CollectionBinder {
|
|||
}
|
||||
else {
|
||||
final BasicValueBinder elementBinder = new BasicValueBinder( BasicValueBinder.Kind.MAP_KEY, buildingContext );
|
||||
elementBinder.setReturnedClassName(mapKeyType);
|
||||
elementBinder.setReturnedClassName( mapKeyType );
|
||||
final AnnotatedColumns keyColumns = createElementColumnsIfNecessary(
|
||||
collection,
|
||||
mapKeyColumns,
|
||||
|
@ -390,10 +385,10 @@ public class MapBinder extends CollectionBinder {
|
|||
property,
|
||||
keyClass,
|
||||
collection.getOwnerEntityName(),
|
||||
holder.mapKeyAttributeConverterDescriptor(property, keyClass)
|
||||
holder.mapKeyAttributeConverterDescriptor( property, keyClass )
|
||||
);
|
||||
elementBinder.setPersistentClassName( propertyHolder.getEntityName() );
|
||||
elementBinder.setAccessType(accessType);
|
||||
elementBinder.setAccessType( accessType );
|
||||
map.setIndex( elementBinder.make() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,6 @@ package org.hibernate.cfg.annotations;
|
|||
|
||||
import jakarta.persistence.NamedEntityGraph;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||
|
||||
/**
|
||||
|
|
|
@ -130,7 +130,7 @@ public class PropertyBinder {
|
|||
}
|
||||
|
||||
public void setColumns(AnnotatedColumns columns) {
|
||||
final AnnotatedColumn firstColumn = columns.getColumns()[0];
|
||||
final AnnotatedColumn firstColumn = columns.getColumns().get(0);
|
||||
insertable = firstColumn.isInsertable();
|
||||
updatable = firstColumn.isUpdatable();
|
||||
//consistency is checked later when we know the property name
|
||||
|
|
|
@ -548,7 +548,7 @@ public class TableBinder {
|
|||
associatedClass = holder == null ? null : holder.getPersistentClass();
|
||||
}
|
||||
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getColumns()[0];
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getJoinColumns().get(0);
|
||||
if ( joinColumns.hasMappedBy() ) {
|
||||
// use the columns of the property referenced by mappedBy
|
||||
// copy them and link the copy to the actual value
|
||||
|
@ -592,12 +592,12 @@ public class TableBinder {
|
|||
SimpleValue value,
|
||||
PersistentClass associatedClass) {
|
||||
//implicit case, we hope PK and FK columns are in the same order
|
||||
if ( joinColumns.getColumns().length != referencedEntity.getIdentifier().getColumnSpan() ) {
|
||||
if ( joinColumns.getColumns().size() != referencedEntity.getIdentifier().getColumnSpan() ) {
|
||||
// TODO: what about secondary tables?? associatedClass is null?
|
||||
throw new AnnotationException(
|
||||
"An association that targets entity '" + referencedEntity.getEntityName()
|
||||
+ "' from entity '" + associatedClass.getEntityName()
|
||||
+ "' has " + joinColumns.getColumns().length + " '@JoinColumn's but the primary key has "
|
||||
+ "' has " + joinColumns.getColumns().size() + " '@JoinColumn's but the primary key has "
|
||||
+ referencedEntity.getIdentifier().getColumnSpan() + " columns"
|
||||
);
|
||||
}
|
||||
|
@ -631,7 +631,7 @@ public class TableBinder {
|
|||
boolean match = false;
|
||||
// for each PK column, find the associated FK column.
|
||||
final String quotedName = column.getQuotedName( dialect );
|
||||
for ( AnnotatedJoinColumn joinColumn : joinColumns.getColumns() ) {
|
||||
for ( AnnotatedJoinColumn joinColumn : joinColumns.getJoinColumns() ) {
|
||||
final String referencedColumn = buildingContext.getMetadataCollector()
|
||||
.getPhysicalColumnName( referencedEntity.getTable(), joinColumn.getReferencedColumn() );
|
||||
// in JPA 2 referencedColumnName is case-insensitive
|
||||
|
@ -704,7 +704,7 @@ public class TableBinder {
|
|||
? referencedEntity.getKey().getColumns()
|
||||
: referencedEntity.getIdentifier().getColumns();
|
||||
for ( Column column: idColumns ) {
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getColumns()[0];
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getJoinColumns().get(0);
|
||||
firstColumn.linkValueUsingDefaultColumnNaming( column, referencedEntity, value);
|
||||
firstColumn.overrideFromReferencedColumnIfNecessary( column );
|
||||
}
|
||||
|
@ -715,7 +715,7 @@ public class TableBinder {
|
|||
SimpleValue value,
|
||||
PersistentClass associatedClass,
|
||||
String mappedByProperty) {
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getColumns()[0];
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getJoinColumns().get(0);
|
||||
for ( Column column: mappedByColumns( associatedClass, mappedByProperty ) ) {
|
||||
firstColumn.overrideFromReferencedColumnIfNecessary( column );
|
||||
firstColumn.linkValueUsingAColumnCopy( column, value);
|
||||
|
@ -744,9 +744,9 @@ public class TableBinder {
|
|||
AnnotatedJoinColumns joinColumns,
|
||||
SimpleValue simpleValue) {
|
||||
final List<Column> valueColumns = value.getColumns();
|
||||
final AnnotatedJoinColumn[] columns = joinColumns.getColumns();
|
||||
for (int i = 0; i < columns.length; i++ ) {
|
||||
final AnnotatedJoinColumn joinColumn = columns[i];
|
||||
final List<AnnotatedJoinColumn> columns = joinColumns.getJoinColumns();
|
||||
for ( int i = 0; i < columns.size(); i++ ) {
|
||||
final AnnotatedJoinColumn joinColumn = columns.get(i);
|
||||
final Column synthCol = valueColumns.get(i);
|
||||
if ( joinColumn.isNameDeferred() ) {
|
||||
//this has to be the default value
|
||||
|
|
|
@ -24,7 +24,7 @@ public class NullableDiscriminatorColumnSecondPass implements SecondPass {
|
|||
|
||||
@Override
|
||||
public void doSecondPass(Map<String, PersistentClass> persistentClasses) throws MappingException {
|
||||
PersistentClass rootPersistenceClass = persistentClasses.get( rootEntityName );
|
||||
final PersistentClass rootPersistenceClass = persistentClasses.get( rootEntityName );
|
||||
if ( hasNullDiscriminatorValue( rootPersistenceClass ) ) {
|
||||
for ( Selectable selectable: rootPersistenceClass.getDiscriminator().getSelectables() ) {
|
||||
if ( selectable instanceof Column ) {
|
||||
|
|
|
@ -106,7 +106,7 @@ public class SqlExceptionHelper {
|
|||
*/
|
||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||
logExceptions( sqlException, message + " [" + sql + "]" );
|
||||
return sqlExceptionConverter.convert( sqlException, message, sql );
|
||||
return sqlExceptionConverter.convert( sqlException, message + " [" + sqlException.getMessage() + "]", sql );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,7 +26,7 @@ public class BankAccount {
|
|||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
@OneToMany(mappedBy = "account", cascade = { CascadeType.ALL })
|
||||
@OneToMany(mappedBy = "account", cascade = CascadeType.ALL)
|
||||
@OrderColumn(name = "transactions_index")
|
||||
private List<Transaction> transactions;
|
||||
|
||||
|
|
Loading…
Reference in New Issue