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