diff --git a/hibernate-core/src/main/java/org/hibernate/AnnotationException.java b/hibernate-core/src/main/java/org/hibernate/AnnotationException.java
index 23de332bfc..34a2f391b0 100644
--- a/hibernate-core/src/main/java/org/hibernate/AnnotationException.java
+++ b/hibernate-core/src/main/java/org/hibernate/AnnotationException.java
@@ -7,9 +7,7 @@
package org.hibernate;
/**
- * Annotation related exception.
- *
- * The EJB3 EG will probably set a generic exception. I'll then use this one.
+ * An exception that occurs while reading mapping annotations.
*
* @author Emmanuel Bernard
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/MappingException.java b/hibernate-core/src/main/java/org/hibernate/MappingException.java
index ceb7ed9a5d..d91b74c53a 100644
--- a/hibernate-core/src/main/java/org/hibernate/MappingException.java
+++ b/hibernate-core/src/main/java/org/hibernate/MappingException.java
@@ -7,8 +7,8 @@
package org.hibernate;
/**
- * An exception that occurs while reading mapping sources (xml/annotations), usually as a result of something
- * screwy in the O-R mappings.
+ * An exception that occurs while reading mapping sources (xml/annotations),
+ * usually as a result of something screwy in the O-R mappings.
*
* @author Gavin King
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOne.java b/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOne.java
index dc00bdd9bd..f717c79a08 100644
--- a/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOne.java
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOne.java
@@ -12,7 +12,8 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Define the laziness options available for a ToOne (ie OneToOne or ManyToOne) association.
+ * Define the laziness options available for a {@link jakarta.persistence.OneToOne}
+ * or {@link jakarta.persistence.ManyToOne}) association.
*
* @author Emmanuel Bernard
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Loader.java b/hibernate-core/src/main/java/org/hibernate/annotations/Loader.java
index c5930cf9bd..6b3fd7da2f 100644
--- a/hibernate-core/src/main/java/org/hibernate/annotations/Loader.java
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/Loader.java
@@ -15,8 +15,8 @@ import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
- * Used to override how Hibernate performs load operations. naming a named query to use instead of
- * its generated SELECT SQL.
+ * Specifies that a named query should be used to load an entity,
+ * overriding the SQL that Hibernate generates by default.
*
* @author L�szl� Benke
*/
@@ -24,7 +24,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention( RUNTIME )
public @interface Loader {
/**
- * THe namedQuery to use for loading.
+ * THe named query to use for loading the entity.
*/
String namedQuery() default "";
}
diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Table.java b/hibernate-core/src/main/java/org/hibernate/annotations/Table.java
index a41e802751..1ac825757c 100644
--- a/hibernate-core/src/main/java/org/hibernate/annotations/Table.java
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/Table.java
@@ -43,6 +43,8 @@ public @interface Table {
/**
* A check constraint, written in native SQL.
+ *
+ * Useful for secondary tables, otherwise use {@link Check}.
*
* @see Check
*/
@@ -50,6 +52,8 @@ public @interface Table {
/**
* Specifies comment to add to the generated DDL for the table.
+ *
+ * Useful for secondary tables, otherwise use {@link Comment}.
*
* @see Comment
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGeneratorInterpreterImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGeneratorInterpreterImpl.java
index 09505d507d..e34fb4ec36 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGeneratorInterpreterImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/IdGeneratorInterpreterImpl.java
@@ -23,6 +23,8 @@ import jakarta.persistence.GenerationType;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.TableGenerator;
+import static org.hibernate.cfg.BinderHelper.isEmptyAnnotationValue;
+
/**
* The root (composition) IdGenerationTypeInterpreter.
*
@@ -128,31 +130,31 @@ public class IdGeneratorInterpreterImpl implements IdGeneratorStrategyInterprete
definitionBuilder.setStrategy( org.hibernate.id.enhanced.TableGenerator.class.getName() );
definitionBuilder.addParam( org.hibernate.id.enhanced.TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" );
- if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.catalog() ) ) {
+ if ( !isEmptyAnnotationValue( tableGeneratorAnnotation.catalog() ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.CATALOG, tableGeneratorAnnotation.catalog() );
}
- if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.schema() ) ) {
+ if ( !isEmptyAnnotationValue( tableGeneratorAnnotation.schema() ) ) {
definitionBuilder.addParam( PersistentIdentifierGenerator.SCHEMA, tableGeneratorAnnotation.schema() );
}
- if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.table() ) ) {
+ if ( !isEmptyAnnotationValue( tableGeneratorAnnotation.table() ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM,
tableGeneratorAnnotation.table()
);
}
- if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.pkColumnName() ) ) {
+ if ( !isEmptyAnnotationValue( tableGeneratorAnnotation.pkColumnName() ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.SEGMENT_COLUMN_PARAM,
tableGeneratorAnnotation.pkColumnName()
);
}
- if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.pkColumnValue() ) ) {
+ if ( !isEmptyAnnotationValue( tableGeneratorAnnotation.pkColumnValue() ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.SEGMENT_VALUE_PARAM,
tableGeneratorAnnotation.pkColumnValue()
);
}
- if ( !BinderHelper.isEmptyAnnotationValue( tableGeneratorAnnotation.valueColumnName() ) ) {
+ if ( !isEmptyAnnotationValue( tableGeneratorAnnotation.valueColumnName() ) ) {
definitionBuilder.addParam(
org.hibernate.id.enhanced.TableGenerator.VALUE_COLUMN_PARAM,
tableGeneratorAnnotation.valueColumnName()
@@ -182,19 +184,19 @@ public class IdGeneratorInterpreterImpl implements IdGeneratorStrategyInterprete
definitionBuilder.setName( sequenceGeneratorAnnotation.name() );
definitionBuilder.setStrategy( SequenceStyleGenerator.class.getName() );
- if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.catalog() ) ) {
+ if ( !isEmptyAnnotationValue( sequenceGeneratorAnnotation.catalog() ) ) {
definitionBuilder.addParam(
PersistentIdentifierGenerator.CATALOG,
sequenceGeneratorAnnotation.catalog()
);
}
- if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.schema() ) ) {
+ if ( !isEmptyAnnotationValue( sequenceGeneratorAnnotation.schema() ) ) {
definitionBuilder.addParam(
PersistentIdentifierGenerator.SCHEMA,
sequenceGeneratorAnnotation.schema()
);
}
- if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.sequenceName() ) ) {
+ if ( !isEmptyAnnotationValue( sequenceGeneratorAnnotation.sequenceName() ) ) {
definitionBuilder.addParam(
SequenceStyleGenerator.SEQUENCE_PARAM,
sequenceGeneratorAnnotation.sequenceName()
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java
index 58f3388487..42789e92d5 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java
@@ -19,6 +19,7 @@ import org.hibernate.boot.AttributeConverterInfo;
import org.hibernate.boot.internal.MetadataBuildingContextRootImpl;
import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings;
import org.hibernate.boot.jaxb.spi.Binding;
+import org.hibernate.boot.model.convert.internal.AttributeConverterManager;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.model.process.spi.ManagedResources;
import org.hibernate.boot.model.source.spi.MetadataSourceProcessor;
@@ -169,42 +170,34 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc
@Override
public void processTypeDefinitions() {
-
}
@Override
public void processQueryRenames() {
-
}
@Override
public void processNamedQueries() {
-
}
@Override
public void processAuxiliaryDatabaseObjectDefinitions() {
-
}
@Override
public void processIdentifierGenerators() {
-
}
@Override
public void processFilterDefinitions() {
-
}
@Override
public void processFetchProfiles() {
-
}
@Override
public void prepareForEntityHierarchyProcessing() {
-
}
@Override
@@ -215,16 +208,15 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc
rootMetadataBuildingContext
);
-
for ( XClass clazz : orderedClasses ) {
if ( processedEntityNames.contains( clazz.getName() ) ) {
log.debugf( "Skipping annotated class processing of entity [%s], as it has already been processed", clazz );
- continue;
}
-
- AnnotationBinder.bindClass( clazz, inheritanceStatePerClass, rootMetadataBuildingContext );
- AnnotationBinder.bindFetchProfilesForClass( clazz, rootMetadataBuildingContext );
- processedEntityNames.add( clazz.getName() );
+ else {
+ AnnotationBinder.bindClass( clazz, inheritanceStatePerClass, rootMetadataBuildingContext );
+ AnnotationBinder.bindFetchProfilesForClass( clazz, rootMetadataBuildingContext );
+ processedEntityNames.add( clazz.getName() );
+ }
}
}
@@ -270,16 +262,15 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc
}
private void orderHierarchy(List copy, List newList, List original, XClass clazz) {
- if ( clazz == null || reflectionManager.equals( clazz, Object.class ) ) {
- return;
- }
- //process superclass first
- orderHierarchy( copy, newList, original, clazz.getSuperclass() );
- if ( original.contains( clazz ) ) {
- if ( !newList.contains( clazz ) ) {
- newList.add( clazz );
+ if ( clazz != null && !reflectionManager.equals( clazz, Object.class ) ) {
+ //process superclass first
+ orderHierarchy( copy, newList, original, clazz.getSuperclass() );
+ if ( original.contains( clazz ) ) {
+ if ( !newList.contains( clazz ) ) {
+ newList.add( clazz );
+ }
+ copy.remove( clazz );
}
- copy.remove( clazz );
}
}
@@ -292,12 +283,10 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc
@Override
public void processResultSetMappings() {
-
}
@Override
public void finishUp() {
-
}
private static class AttributeConverterManager implements AttributeConverterDefinitionCollector {
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java
index b3fca1c5ad..7f8454ca57 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java
@@ -38,6 +38,8 @@ import org.hibernate.mapping.Table;
import org.jboss.logging.Logger;
import static org.hibernate.cfg.AnnotationBinder.getOverridableAnnotation;
+import static org.hibernate.cfg.BinderHelper.getRelativePath;
+import static org.hibernate.internal.util.StringHelper.isNotEmpty;
/**
* Wrap state of an EJB3 @Column annotation
@@ -107,7 +109,7 @@ public class AnnotatedColumn {
}
public boolean isFormula() {
- return StringHelper.isNotEmpty( formulaString );
+ return isNotEmpty( formulaString );
}
@SuppressWarnings("UnusedDeclaration")
@@ -229,7 +231,7 @@ public class AnnotatedColumn {
}
public void bind() {
- if ( StringHelper.isNotEmpty( formulaString ) ) {
+ if ( isNotEmpty( formulaString ) ) {
LOG.debugf( "Binding formula %s", formulaString );
formula = new Formula();
formula.setFormula( formulaString );
@@ -252,7 +254,7 @@ public class AnnotatedColumn {
if ( checkConstraint !=null ) {
mappingColumn.setCheckConstraint( checkConstraint );
}
- if ( StringHelper.isNotEmpty( comment ) ) {
+ if ( isNotEmpty( comment ) ) {
mappingColumn.setComment( comment );
}
if ( generatedAs != null ) {
@@ -274,22 +276,22 @@ public class AnnotatedColumn {
String sqlType,
boolean unique,
boolean applyNamingStrategy) {
- if ( StringHelper.isNotEmpty( formulaString ) ) {
- this.formula = new Formula();
- this.formula.setFormula( formulaString );
+ if ( isNotEmpty( formulaString ) ) {
+ formula = new Formula();
+ formula.setFormula( formulaString );
}
else {
- this.mappingColumn = new Column();
+ mappingColumn = new Column();
redefineColumnName( columnName, propertyName, applyNamingStrategy );
- this.mappingColumn.setLength( length );
+ mappingColumn.setLength( length );
if ( precision != null && precision > 0 ) { //relevant precision
- this.mappingColumn.setPrecision( precision );
- this.mappingColumn.setScale( scale );
+ mappingColumn.setPrecision( precision );
+ mappingColumn.setScale( scale );
}
- this.mappingColumn.setNullable( nullable );
- this.mappingColumn.setSqlType( sqlType );
- this.mappingColumn.setUnique( unique );
- this.mappingColumn.setCheckConstraint( checkConstraint );
+ mappingColumn.setNullable( nullable );
+ mappingColumn.setSqlType( sqlType );
+ mappingColumn.setUnique( unique );
+ mappingColumn.setCheckConstraint( checkConstraint );
if ( writeExpression != null ) {
final int numberOfJdbcParams = StringHelper.count( writeExpression, '?' );
@@ -301,8 +303,8 @@ public class AnnotatedColumn {
}
}
- this.mappingColumn.setResolvedCustomRead( readExpression );
- this.mappingColumn.setCustomWrite( writeExpression );
+ mappingColumn.setResolvedCustomRead( readExpression );
+ mappingColumn.setCustomWrite( writeExpression );
}
}
@@ -311,7 +313,7 @@ public class AnnotatedColumn {
}
public void redefineColumnName(String columnName, String propertyName, boolean applyNamingStrategy) {
- if ( StringHelper.isNotEmpty( columnName ) ) {
+ if ( isNotEmpty( columnName ) ) {
mappingColumn.setName( processColumnName( columnName, applyNamingStrategy ) );
}
else {
@@ -323,7 +325,7 @@ public class AnnotatedColumn {
}
private String processColumnName(String columnName, boolean applyNamingStrategy) {
- if (applyNamingStrategy) {
+ if ( applyNamingStrategy ) {
Database database = context.getMetadataCollector().getDatabase();
return context.getBuildingOptions().getPhysicalNamingStrategy()
.toPhysicalColumnName( database.toIdentifier( columnName ), database.getJdbcEnvironment() )
@@ -368,8 +370,10 @@ public class AnnotatedColumn {
// HHH-6005 magic
if ( implicitName.getText().contains( "_collection&&element_" ) ) {
- implicitName = Identifier.toIdentifier( implicitName.getText().replace( "_collection&&element_", "_" ),
- implicitName.isQuoted() );
+ implicitName = Identifier.toIdentifier(
+ implicitName.getText().replace( "_collection&&element_", "_" ),
+ implicitName.isQuoted()
+ );
}
return context.getBuildingOptions().getPhysicalNamingStrategy()
@@ -433,7 +437,7 @@ public class AnnotatedColumn {
protected void addColumnBinding(SimpleValue value) {
final String logicalColumnName;
- if ( StringHelper.isNotEmpty( this.logicalColumnName ) ) {
+ if ( isNotEmpty( this.logicalColumnName ) ) {
logicalColumnName = this.logicalColumnName;
}
else {
@@ -492,7 +496,7 @@ public class AnnotatedColumn {
throw new AssertionFailure( "Should not call getTable() on column w/o persistent class defined" );
}
- return StringHelper.isNotEmpty( explicitTableName )
+ return isNotEmpty( explicitTableName )
&& !propertyHolder.getTable().getName().equals( explicitTableName );
}
@@ -652,7 +656,7 @@ public class AnnotatedColumn {
public static AnnotatedColumn[] buildColumnsOrFormulaFromAnnotation(
jakarta.persistence.Column[] columnAnns,
org.hibernate.annotations.Formula formulaAnn,
- Comment commentAnn,
+ Comment comment,
Nullability nullability,
PropertyHolder propertyHolder,
PropertyData inferredData,
@@ -670,129 +674,153 @@ public class AnnotatedColumn {
return new AnnotatedColumn[] { formulaColumn };
}
else {
- jakarta.persistence.Column[] actualCols = columnAnns;
- jakarta.persistence.Column[] overriddenCols = propertyHolder.getOverriddenColumn(
- StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() )
- );
- if ( overriddenCols != null ) {
- //check for overridden first
- if ( columnAnns != null && overriddenCols.length != columnAnns.length ) {
- throw new AnnotationException( "AttributeOverride.column() should override all columns for now" );
- }
- actualCols = overriddenCols.length == 0 ? null : overriddenCols;
- LOG.debugf( "Column(s) overridden for property %s", inferredData.getPropertyName() );
- }
-
- AnnotatedColumn[] columns;
+ jakarta.persistence.Column[] actualCols = overrideColumns( columnAnns, propertyHolder, inferredData);
if ( actualCols == null ) {
- columns = buildImplicitColumn(
+ return buildImplicitColumn(
inferredData,
suffixForDefaultColumnName,
secondaryTables,
propertyHolder,
- commentAnn,
+ comment,
nullability,
context
);
}
else {
- final int length = actualCols.length;
- columns = new AnnotatedColumn[length];
- for (int index = 0; index < length; index++) {
+ return buildExplicitColumns(
+ comment,
+ propertyHolder,
+ inferredData,
+ suffixForDefaultColumnName,
+ secondaryTables,
+ context,
+ actualCols
+ );
+ }
+ }
+ }
- final ObjectNameNormalizer normalizer = context.getObjectNameNormalizer();
- final Database database = context.getMetadataCollector().getDatabase();
+ private static jakarta.persistence.Column[] overrideColumns(
+ jakarta.persistence.Column[] columnAnns,
+ PropertyHolder propertyHolder,
+ PropertyData inferredData ) {
+ final jakarta.persistence.Column[] overriddenCols = propertyHolder.getOverriddenColumn(
+ StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() )
+ );
+ if ( overriddenCols != null ) {
+ //check for overridden first
+ if ( columnAnns != null && overriddenCols.length != columnAnns.length ) {
+ throw new AnnotationException( "AttributeOverride.column() should override all columns for now" );
+ }
+ LOG.debugf( "Column(s) overridden for property %s", inferredData.getPropertyName() );
+ return overriddenCols.length == 0 ? null : overriddenCols;
+ }
+ else {
+ return columnAnns;
+ }
+ }
- jakarta.persistence.Column col = actualCols[index];
-
- final String sqlType;
- if ( col.columnDefinition().isEmpty() ) {
- sqlType = null;
- }
- else {
- sqlType = normalizer.applyGlobalQuoting( col.columnDefinition() );
- }
-
- final String tableName;
- if ( StringHelper.isEmpty( col.table() ) ) {
- tableName = "";
- }
- else {
- tableName = database.getJdbcEnvironment()
- .getIdentifierHelper()
- .toIdentifier( col.table() )
- .render();
+ private static AnnotatedColumn[] buildExplicitColumns(
+ Comment comment,
+ PropertyHolder propertyHolder,
+ PropertyData inferredData,
+ String suffixForDefaultColumnName,
+ Map secondaryTables,
+ MetadataBuildingContext context,
+ jakarta.persistence.Column[] actualCols) {
+ final int length = actualCols.length;
+ final AnnotatedColumn[] columns = new AnnotatedColumn[length];
+ for (int index = 0; index < length; index++) {
+ final jakarta.persistence.Column column = actualCols[index];
+ final Database database = context.getMetadataCollector().getDatabase();
+ final String sqlType = column.columnDefinition().isEmpty() ? null
+ : context.getObjectNameNormalizer().applyGlobalQuoting( column.columnDefinition() );
+ final String tableName = StringHelper.isEmpty( column.table() ) ? ""
+ : database.getJdbcEnvironment().getIdentifierHelper().toIdentifier( column.table() ).render();
// final Identifier logicalName = database.getJdbcEnvironment()
// .getIdentifierHelper()
-// .toIdentifier( col.table() );
+// .toIdentifier( column.table() );
// final Identifier physicalName = physicalNamingStrategy.toPhysicalTableName( logicalName );
// tableName = physicalName.render( database.getDialect() );
- }
-
- final String columnName;
- if ( col.name() != null && col.name().isEmpty() ) {
- columnName = null;
- }
- else {
- // NOTE : this is the logical column name, not the physical!
- columnName = database.getJdbcEnvironment()
- .getIdentifierHelper()
- .toIdentifier( col.name() )
- .render();
- }
-
- AnnotatedColumn column = new AnnotatedColumn();
-
- column.setImplicit( false );
- column.setSqlType( sqlType );
- column.setLength( (long) col.length() );
- column.setPrecision( col.precision() );
- column.setScale( col.scale() );
- if ( StringHelper.isEmpty( columnName ) && ! StringHelper.isEmpty( suffixForDefaultColumnName ) ) {
- column.setLogicalColumnName( inferredData.getPropertyName() + suffixForDefaultColumnName );
- }
- else {
- column.setLogicalColumnName( columnName );
- }
-
- column.setPropertyName(
- BinderHelper.getRelativePath( propertyHolder, inferredData.getPropertyName() )
- );
- column.setNullable(
- col.nullable()
- ); //TODO force to not null if available? This is a (bad) user choice.
- if ( commentAnn != null ) {
- column.setComment( commentAnn.value() );
- }
- column.setUnique( col.unique() );
- column.setInsertable( col.insertable() );
- column.setUpdatable( col.updatable() );
- column.setExplicitTableName( tableName );
- column.setPropertyHolder( propertyHolder );
- column.setJoins( secondaryTables );
- column.setBuildingContext( context );
- column.applyColumnDefault( inferredData, length );
- column.applyGeneratedAs( inferredData, length );
- column.applyCheckConstraint( inferredData, length );
- column.extractDataFromPropertyData(inferredData);
- column.bind();
- columns[index] = column;
- }
- }
-
- return columns;
+ columns[index] = buildColumn(
+ comment,
+ propertyHolder,
+ inferredData,
+ suffixForDefaultColumnName,
+ secondaryTables,
+ context,
+ length,
+ database,
+ column,
+ sqlType,
+ tableName
+ );
}
+ return columns;
+ }
+
+ private static AnnotatedColumn buildColumn(
+ Comment comment,
+ PropertyHolder propertyHolder,
+ PropertyData inferredData,
+ String suffixForDefaultColumnName,
+ Map secondaryTables,
+ MetadataBuildingContext context,
+ int length,
+ Database database,
+ jakarta.persistence.Column col,
+ String sqlType,
+ String tableName) {
+
+ final AnnotatedColumn column = new AnnotatedColumn();
+ column.setLogicalColumnName( getLogicalColumnName( inferredData, suffixForDefaultColumnName, database, col ) );
+ column.setImplicit( false );
+ column.setSqlType(sqlType);
+ column.setLength( (long) col.length() );
+ column.setPrecision( col.precision() );
+ column.setScale( col.scale() );
+ column.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
+ column.setNullable( col.nullable() ); //TODO force to not null if available? This is a (bad) user choice.
+ if ( comment != null ) {
+ column.setComment( comment.value() );
+ }
+ column.setUnique( col.unique() );
+ column.setInsertable( col.insertable() );
+ column.setUpdatable( col.updatable() );
+ column.setExplicitTableName( tableName );
+ column.setPropertyHolder( propertyHolder );
+ column.setJoins( secondaryTables );
+ column.setBuildingContext( context );
+ column.applyColumnDefault( inferredData, length );
+ column.applyGeneratedAs( inferredData, length );
+ column.applyCheckConstraint( inferredData, length );
+ column.extractDataFromPropertyData( inferredData );
+ column.bind();
+ return column;
+ }
+
+ private static String getLogicalColumnName(
+ PropertyData inferredData,
+ String suffixForDefaultColumnName,
+ Database database,
+ jakarta.persistence.Column column) {
+ final String columnName = column.name() != null && column.name().isEmpty() ? null
+ : database.getJdbcEnvironment().getIdentifierHelper().toIdentifier( column.name() ).render();
+ // NOTE : this is the logical column name, not the physical!
+ return StringHelper.isEmpty( columnName ) && !StringHelper.isEmpty(suffixForDefaultColumnName)
+ ? inferredData.getPropertyName() + suffixForDefaultColumnName
+ : columnName;
}
private void applyColumnDefault(PropertyData inferredData, int length) {
final XProperty xProperty = inferredData.getProperty();
if ( xProperty != null ) {
- ColumnDefault columnDefaultAnn = getOverridableAnnotation( xProperty, ColumnDefault.class, context );
- if ( columnDefaultAnn != null ) {
+ ColumnDefault columnDefault = getOverridableAnnotation( xProperty, ColumnDefault.class, context );
+ if ( columnDefault != null ) {
if (length!=1) {
throw new MappingException("@ColumnDefault may only be applied to single-column mappings");
}
- setDefaultValue( columnDefaultAnn.value() );
+ setDefaultValue( columnDefault.value() );
}
}
else {
@@ -805,12 +833,12 @@ public class AnnotatedColumn {
private void applyGeneratedAs(PropertyData inferredData, int length) {
final XProperty xProperty = inferredData.getProperty();
if ( xProperty != null ) {
- GeneratedColumn generatedAnn = getOverridableAnnotation( xProperty, GeneratedColumn.class, context );
- if ( generatedAnn != null ) {
+ GeneratedColumn generatedColumn = getOverridableAnnotation( xProperty, GeneratedColumn.class, context );
+ if ( generatedColumn != null ) {
if (length!=1) {
throw new MappingException("@GeneratedColumn may only be applied to single-column mappings");
}
- setGeneratedAs( generatedAnn.value() );
+ setGeneratedAs( generatedColumn.value() );
}
}
else {
@@ -823,12 +851,12 @@ public class AnnotatedColumn {
private void applyCheckConstraint(PropertyData inferredData, int length) {
final XProperty xProperty = inferredData.getProperty();
if ( xProperty != null ) {
- Check columnDefaultAnn = AnnotationBinder.getOverridableAnnotation( xProperty, Check.class, context );
- if ( columnDefaultAnn != null ) {
+ Check check = AnnotationBinder.getOverridableAnnotation( xProperty, Check.class, context );
+ if ( check != null ) {
if (length!=1) {
throw new MappingException("@Check may only be applied to single-column mappings (use a table-level @Check)");
}
- setCheckConstraint( columnDefaultAnn.constraints() );
+ setCheckConstraint( check.constraints() );
}
}
else {
@@ -844,33 +872,27 @@ public class AnnotatedColumn {
XProperty property = inferredData.getProperty();
if ( property != null ) {
if ( propertyHolder.isComponent() ) {
- processExpression( propertyHolder.getOverriddenColumnTransformer( logicalColumnName ) );
+ processColumnTransformerExpressions( propertyHolder.getOverriddenColumnTransformer( logicalColumnName ) );
}
- processExpression( property.getAnnotation( ColumnTransformer.class ) );
+ processColumnTransformerExpressions( property.getAnnotation( ColumnTransformer.class ) );
ColumnTransformers annotations = property.getAnnotation( ColumnTransformers.class );
if (annotations != null) {
for ( ColumnTransformer annotation : annotations.value() ) {
- processExpression( annotation );
+ processColumnTransformerExpressions( annotation );
}
}
}
}
}
- private void processExpression(ColumnTransformer annotation) {
- if ( annotation == null ) {
- return;
- }
-
- final String nonNullLogicalColumnName = logicalColumnName != null
- ? logicalColumnName
- //use the default for annotations
- : "";
-
- if ( StringHelper.isEmpty( annotation.forColumn() )
- || annotation.forColumn().equals( nonNullLogicalColumnName ) ) {
- readExpression = StringHelper.nullIfEmpty( annotation.read() );
- writeExpression = StringHelper.nullIfEmpty( annotation.write() );
+ private void processColumnTransformerExpressions(ColumnTransformer annotation) {
+ if ( annotation != null ) {
+ if ( StringHelper.isEmpty( annotation.forColumn() )
+ // "" is the default value for annotations
+ || annotation.forColumn().equals( logicalColumnName != null ? logicalColumnName : "" ) ) {
+ readExpression = StringHelper.nullIfEmpty( annotation.read() );
+ writeExpression = StringHelper.nullIfEmpty( annotation.write() );
+ }
}
}
@@ -882,14 +904,31 @@ public class AnnotatedColumn {
Comment comment,
Nullability nullability,
MetadataBuildingContext context) {
- AnnotatedColumn column = new AnnotatedColumn();
- AnnotatedColumn[] columns = new AnnotatedColumn[1];
- columns[0] = column;
+ final AnnotatedColumn[] columns = new AnnotatedColumn[1];
+ columns[0] = bindImplicitColumn(
+ inferredData,
+ suffixForDefaultColumnName,
+ secondaryTables,
+ propertyHolder,
+ comment,
+ nullability,
+ context
+ );
+ return columns;
+ }
+ private static AnnotatedColumn bindImplicitColumn(
+ PropertyData inferredData,
+ String suffixForDefaultColumnName,
+ Map secondaryTables,
+ PropertyHolder propertyHolder,
+ Comment comment,
+ Nullability nullability,
+ MetadataBuildingContext context) {
+ final AnnotatedColumn column = new AnnotatedColumn();
if ( comment != null ) {
column.setComment( comment.value() );
}
-
//not following the spec but more clean
if ( nullability != Nullability.FORCED_NULL
&& inferredData.getClassOrElement().isPrimitive()
@@ -897,13 +936,10 @@ public class AnnotatedColumn {
column.setNullable( false );
}
final String propertyName = inferredData.getPropertyName();
- column.setPropertyName(
- BinderHelper.getRelativePath( propertyHolder, propertyName )
- );
- column.setPropertyHolder( propertyHolder );
- column.setJoins( secondaryTables );
- column.setBuildingContext( context );
-
+ column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
+ column.setPropertyHolder(propertyHolder);
+ column.setJoins(secondaryTables);
+ column.setBuildingContext(context);
// property name + suffix is an "explicit" column name
boolean implicit = StringHelper.isEmpty( suffixForDefaultColumnName );
if ( !implicit ) {
@@ -915,49 +951,43 @@ public class AnnotatedColumn {
column.applyCheckConstraint( inferredData, 1 );
column.extractDataFromPropertyData( inferredData );
column.bind();
-
- return columns;
+ return column;
}
public static void checkPropertyConsistency(AnnotatedColumn[] columns, String propertyName) {
int nbrOfColumns = columns.length;
-
if ( nbrOfColumns > 1 ) {
for (int currentIndex = 1; currentIndex < nbrOfColumns; currentIndex++) {
-
- if (columns[currentIndex].isFormula() || columns[currentIndex - 1].isFormula()) {
- continue;
- }
-
- if ( columns[currentIndex].isInsertable() != columns[currentIndex - 1].isInsertable() ) {
- throw new AnnotationException(
- "Mixing insertable and non insertable columns in a property is not allowed: " + propertyName
- );
- }
- if ( columns[currentIndex].isNullable() != columns[currentIndex - 1].isNullable() ) {
- throw new AnnotationException(
- "Mixing nullable and non nullable columns in a property is not allowed: " + propertyName
- );
- }
- if ( columns[currentIndex].isUpdatable() != columns[currentIndex - 1].isUpdatable() ) {
- throw new AnnotationException(
- "Mixing updatable and non updatable columns in a property is not allowed: " + propertyName
- );
- }
- if ( !columns[currentIndex].getTable().equals( columns[currentIndex - 1].getTable() ) ) {
- throw new AnnotationException(
- "Mixing different tables in a property is not allowed: " + propertyName
- );
+ if ( !columns[currentIndex].isFormula() && !columns[currentIndex - 1].isFormula() ) {
+ if ( columns[currentIndex].isInsertable() != columns[currentIndex - 1].isInsertable() ) {
+ throw new AnnotationException(
+ "Mixing insertable and non insertable columns in a property is not allowed: " + propertyName
+ );
+ }
+ if ( columns[currentIndex].isNullable() != columns[currentIndex - 1].isNullable() ) {
+ throw new AnnotationException(
+ "Mixing nullable and non nullable columns in a property is not allowed: " + propertyName
+ );
+ }
+ if ( columns[currentIndex].isUpdatable() != columns[currentIndex - 1].isUpdatable() ) {
+ throw new AnnotationException(
+ "Mixing updatable and non updatable columns in a property is not allowed: " + propertyName
+ );
+ }
+ if ( !columns[currentIndex].getTable().equals( columns[currentIndex - 1].getTable() ) ) {
+ throw new AnnotationException(
+ "Mixing different tables in a property is not allowed: " + propertyName
+ );
+ }
}
}
}
-
}
public void addIndex(Index index, boolean inSecondPass) {
- if ( index == null ) return;
- String indexName = index.name();
- addIndex( indexName, inSecondPass );
+ if ( index != null ) {
+ addIndex( index.name(), inSecondPass );
+ }
}
void addIndex(String indexName, boolean inSecondPass) {
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java
index 2dd125723a..bf508d99b9 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java
@@ -12,6 +12,8 @@ import org.hibernate.AssertionFailure;
import org.hibernate.annotations.DiscriminatorFormula;
import org.hibernate.boot.spi.MetadataBuildingContext;
+import static org.hibernate.cfg.BinderHelper.isEmptyAnnotationValue;
+
/**
* Discriminator column
*
@@ -42,51 +44,69 @@ public class AnnotatedDiscriminatorColumn extends AnnotatedColumn {
}
public static AnnotatedDiscriminatorColumn buildDiscriminatorColumn(
- DiscriminatorType type, DiscriminatorColumn discAnn,
+ DiscriminatorType type,
+ DiscriminatorColumn discAnn,
DiscriminatorFormula discFormulaAnn,
MetadataBuildingContext context) {
- AnnotatedDiscriminatorColumn discriminatorColumn = new AnnotatedDiscriminatorColumn();
+ final AnnotatedDiscriminatorColumn discriminatorColumn = new AnnotatedDiscriminatorColumn();
discriminatorColumn.setBuildingContext( context );
- discriminatorColumn.setImplicit( true );
if ( discFormulaAnn != null ) {
discriminatorColumn.setImplicit( false );
discriminatorColumn.setFormula( discFormulaAnn.value() );
}
else if ( discAnn != null ) {
discriminatorColumn.setImplicit( false );
- if ( !BinderHelper.isEmptyAnnotationValue( discAnn.columnDefinition() ) ) {
- discriminatorColumn.setSqlType(
- discAnn.columnDefinition()
- );
+ if ( !isEmptyAnnotationValue( discAnn.columnDefinition() ) ) {
+ discriminatorColumn.setSqlType( discAnn.columnDefinition() );
}
- if ( !BinderHelper.isEmptyAnnotationValue( discAnn.name() ) ) {
+ if ( !isEmptyAnnotationValue( discAnn.name() ) ) {
discriminatorColumn.setLogicalColumnName( discAnn.name() );
}
discriminatorColumn.setNullable( false );
}
- if ( DiscriminatorType.CHAR.equals( type ) ) {
- discriminatorColumn.setDiscriminatorTypeName( "character" );
- discriminatorColumn.setImplicit( false );
- }
- else if ( DiscriminatorType.INTEGER.equals( type ) ) {
- discriminatorColumn.setDiscriminatorTypeName( "integer" );
- discriminatorColumn.setImplicit( false );
- }
- else if ( DiscriminatorType.STRING.equals( type ) || type == null ) {
- if ( discAnn != null ) discriminatorColumn.setLength( (long) discAnn.length() );
- discriminatorColumn.setDiscriminatorTypeName( "string" );
- }
else {
- throw new AssertionFailure( "Unknown discriminator type: " + type );
+ discriminatorColumn.setImplicit( true );
}
+ setDiscriminatorType( type, discAnn, discriminatorColumn );
discriminatorColumn.bind();
return discriminatorColumn;
}
+ private static void setDiscriminatorType(
+ DiscriminatorType type,
+ DiscriminatorColumn discAnn,
+ AnnotatedDiscriminatorColumn discriminatorColumn) {
+ if ( type == null ) {
+ discriminatorColumn.setDiscriminatorTypeName( "string" );
+ }
+ else {
+ switch ( type ) {
+ case CHAR:
+ discriminatorColumn.setDiscriminatorTypeName( "character" );
+ discriminatorColumn.setImplicit( false );
+ break;
+ case INTEGER:
+ discriminatorColumn.setDiscriminatorTypeName( "integer" );
+ discriminatorColumn.setImplicit( false );
+ break;
+ case STRING:
+ discriminatorColumn.setDiscriminatorTypeName( "string" );
+ if ( discAnn != null ) {
+ discriminatorColumn.setLength( (long) discAnn.length() );
+ }
+ break;
+ default:
+ throw new AssertionFailure( "Unknown discriminator type: " + type );
+ }
+ }
+ }
+
@Override
public String toString() {
- return String.format("DiscriminatorColumn{logicalColumnName'%s', discriminatorTypeName='%s'}",
- getLogicalColumnName(), discriminatorTypeName
+ return String.format(
+ "DiscriminatorColumn{logicalColumnName'%s', discriminatorTypeName='%s'}",
+ getLogicalColumnName(),
+ discriminatorTypeName
);
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java
index a73dff94b1..96c7cb24e8 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java
@@ -29,6 +29,7 @@ import org.hibernate.boot.model.naming.ObjectNameNormalizer;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.source.spi.AttributePath;
+import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Column;
@@ -40,6 +41,10 @@ import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value;
+import static org.hibernate.cfg.BinderHelper.findColumnOwner;
+import static org.hibernate.cfg.BinderHelper.getRelativePath;
+import static org.hibernate.cfg.BinderHelper.isEmptyAnnotationValue;
+
/**
* Wrap state of an EJB3 @JoinColumn annotation
* and build the Hibernate column mapping element
@@ -123,7 +128,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
setPropertyHolder( propertyHolder );
setJoins( joins );
setBuildingContext( buildingContext );
- setPropertyName( BinderHelper.getRelativePath( propertyHolder, propertyName ) );
+ setPropertyName( getRelativePath( propertyHolder, propertyName ) );
bind();
this.referencedColumn = referencedColumn;
this.mappedBy = mappedBy;
@@ -175,7 +180,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
formulaColumn.setBuildingContext( buildingContext );
formulaColumn.setPropertyHolder( propertyHolder );
formulaColumn.setJoins( joins );
- formulaColumn.setPropertyName( BinderHelper.getRelativePath( propertyHolder, propertyName ) );
+ formulaColumn.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
formulaColumn.bind();
return formulaColumn;
}
@@ -254,7 +259,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
if ( !BinderHelper.isEmptyOrNullAnnotationValue( mappedBy ) ) {
throw new AnnotationException(
"Illegal attempt to define a @JoinColumn with a mappedBy association: "
- + BinderHelper.getRelativePath( propertyHolder, propertyName )
+ + getRelativePath( propertyHolder, propertyName )
);
}
AnnotatedJoinColumn joinColumn = new AnnotatedJoinColumn();
@@ -267,7 +272,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
}
joinColumn.setJoins( joins );
joinColumn.setPropertyHolder( propertyHolder );
- joinColumn.setPropertyName( BinderHelper.getRelativePath( propertyHolder, propertyName ) );
+ joinColumn.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
joinColumn.setImplicit( false );
joinColumn.bind();
return joinColumn;
@@ -277,9 +282,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
joinColumn.setMappedBy( mappedBy );
joinColumn.setJoins( joins );
joinColumn.setPropertyHolder( propertyHolder );
- joinColumn.setPropertyName(
- BinderHelper.getRelativePath( propertyHolder, propertyName )
- );
+ joinColumn.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
// property name + suffix is an "explicit" column name
if ( !StringHelper.isEmpty( suffixForDefaultColumnName ) ) {
joinColumn.setLogicalColumnName( propertyName + suffixForDefaultColumnName );
@@ -302,10 +305,10 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
}
else {
setImplicit( false );
- if ( !BinderHelper.isEmptyAnnotationValue( annJoin.columnDefinition() ) ) {
+ if ( !isEmptyAnnotationValue( annJoin.columnDefinition() ) ) {
setSqlType( getBuildingContext().getObjectNameNormalizer().applyGlobalQuoting( annJoin.columnDefinition() ) );
}
- if ( !BinderHelper.isEmptyAnnotationValue( annJoin.name() ) ) {
+ if ( !isEmptyAnnotationValue( annJoin.name() ) ) {
setLogicalColumnName( annJoin.name() );
}
setNullable( annJoin.nullable() );
@@ -314,7 +317,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
setUpdatable( annJoin.updatable() );
setReferencedColumn( annJoin.referencedColumnName() );
- if ( BinderHelper.isEmptyAnnotationValue( annJoin.table() ) ) {
+ if ( isEmptyAnnotationValue( annJoin.table() ) ) {
setExplicitTableName( "" );
}
else {
@@ -342,13 +345,11 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
PropertyHolder propertyHolder,
MetadataBuildingContext context) {
- final ObjectNameNormalizer normalizer = context.getObjectNameNormalizer();
-
- Column col = identifier.getColumns().get(0);
- String defaultName = context.getMetadataCollector().getLogicalColumnName(
+ final String defaultName = context.getMetadataCollector().getLogicalColumnName(
identifier.getTable(),
- col.getQuotedName()
+ identifier.getColumns().get(0).getQuotedName()
);
+ final ObjectNameNormalizer normalizer = context.getObjectNameNormalizer();
if ( pkJoinAnn != null || joinAnn != null ) {
String colName;
@@ -364,25 +365,13 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
columnDefinition = joinAnn.columnDefinition();
referencedColumnName = joinAnn.referencedColumnName();
}
-
- final String sqlType;
- if ( columnDefinition.isEmpty() ) {
- sqlType = null;
- }
- else {
- sqlType = normalizer.toDatabaseIdentifierText( columnDefinition );
- }
-
- final String name;
- if ( colName != null && colName.isEmpty() ) {
- name = normalizer.normalizeIdentifierQuotingAsString( defaultName );
- }
- else {
- name = context.getObjectNameNormalizer().normalizeIdentifierQuotingAsString( colName );
- }
return new AnnotatedJoinColumn(
- sqlType,
- name,
+ columnDefinition.isEmpty()
+ ? null
+ : normalizer.toDatabaseIdentifierText( columnDefinition ),
+ colName != null && colName.isEmpty()
+ ? normalizer.normalizeIdentifierQuotingAsString( defaultName )
+ : normalizer.normalizeIdentifierQuotingAsString( colName ),
null,
false,
false,
@@ -399,10 +388,9 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
);
}
else {
- defaultName = context.getObjectNameNormalizer().normalizeIdentifierQuotingAsString( defaultName );
return new AnnotatedJoinColumn(
null,
- defaultName,
+ normalizer.normalizeIdentifierQuotingAsString( defaultName ),
null,
false,
false,
@@ -495,36 +483,26 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
}
private String buildDefaultColumnName(final PersistentClass referencedEntity, final String logicalReferencedColumn) {
- final Database database = getBuildingContext().getMetadataCollector().getDatabase();
+ final InFlightMetadataCollector metadataCollector = getBuildingContext().getMetadataCollector();
+ final Database database = metadataCollector.getDatabase();
final ImplicitNamingStrategy implicitNamingStrategy = getBuildingContext().getBuildingOptions().getImplicitNamingStrategy();
final PhysicalNamingStrategy physicalNamingStrategy = getBuildingContext().getBuildingOptions().getPhysicalNamingStrategy();
- Identifier columnIdentifier;
boolean mappedBySide = mappedByTableName != null || mappedByPropertyName != null;
boolean ownerSide = getPropertyName() != null;
-
boolean isRefColumnQuoted = StringHelper.isQuoted( logicalReferencedColumn );
+ Identifier columnIdentifier;
if ( mappedBySide ) {
// NOTE : While it is completely misleading here to allow for the combination
// of a "JPA ElementCollection" to be mappedBy, the code that uses this
// class relies on this behavior for handling the inverse side of
// many-to-many mappings
-
- final AttributePath attributePath = AttributePath.parse( mappedByPropertyName );
- final ImplicitJoinColumnNameSource.Nature implicitNamingNature;
- if ( getPropertyHolder().isEntity() ) {
- implicitNamingNature = ImplicitJoinColumnNameSource.Nature.ENTITY;
- }
- else if ( JPA2ElementCollection ) {
- implicitNamingNature = ImplicitJoinColumnNameSource.Nature.ELEMENT_COLLECTION;
- }
- else {
- implicitNamingNature = ImplicitJoinColumnNameSource.Nature.ENTITY_COLLECTION;
- }
-
columnIdentifier = implicitNamingStrategy.determineJoinColumnName(
new ImplicitJoinColumnNameSource() {
+ final AttributePath attributePath = AttributePath.parse( mappedByPropertyName );
+ final ImplicitJoinColumnNameSource.Nature implicitNamingNature = getImplicitNature();
+
private final EntityNaming entityNaming = new EntityNaming() {
@Override
public String getClassName() {
@@ -542,9 +520,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
}
};
- private final Identifier referencedTableName = getBuildingContext().getMetadataCollector()
- .getDatabase()
- .toIdentifier( mappedByTableName );
+ private final Identifier referencedTableName = database.toIdentifier( mappedByTableName );
@Override
public Nature getNature() {
@@ -569,18 +545,15 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
@Override
public Identifier getReferencedColumnName() {
if ( logicalReferencedColumn != null ) {
- return getBuildingContext().getMetadataCollector()
- .getDatabase()
- .toIdentifier( logicalReferencedColumn );
+ return database.toIdentifier( logicalReferencedColumn );
}
if ( mappedByEntityName == null || mappedByPropertyName == null ) {
return null;
}
- final PersistentClass mappedByEntityBinding = getBuildingContext().getMetadataCollector()
- .getEntityBinding( mappedByEntityName );
- final Property mappedByProperty = mappedByEntityBinding.getProperty( mappedByPropertyName );
+ final Property mappedByProperty = metadataCollector.getEntityBinding( mappedByEntityName )
+ .getProperty( mappedByPropertyName );
final SimpleValue value = (SimpleValue) mappedByProperty.getValue();
if ( value.getSelectables().isEmpty() ) {
throw new AnnotationException(
@@ -613,9 +586,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
)
);
}
- return getBuildingContext().getMetadataCollector()
- .getDatabase()
- .toIdentifier( ( (Column) selectable ).getQuotedName() );
+ return database.toIdentifier( ( (Column) selectable ).getQuotedName() );
}
@Override
@@ -631,23 +602,12 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
}
}
else if ( ownerSide ) {
- final String logicalTableName = getBuildingContext().getMetadataCollector().getLogicalTableName(
- referencedEntity.getTable()
- );
+ final String logicalTableName = metadataCollector.getLogicalTableName( referencedEntity.getTable() );
- final ImplicitJoinColumnNameSource.Nature implicitNamingNature;
- if ( JPA2ElementCollection ) {
- implicitNamingNature = ImplicitJoinColumnNameSource.Nature.ELEMENT_COLLECTION;
- }
- else if ( getPropertyHolder().isEntity() ) {
- implicitNamingNature = ImplicitJoinColumnNameSource.Nature.ENTITY;
- }
- else {
- implicitNamingNature = ImplicitJoinColumnNameSource.Nature.ENTITY_COLLECTION;
- }
-
- columnIdentifier = getBuildingContext().getBuildingOptions().getImplicitNamingStrategy().determineJoinColumnName(
+ columnIdentifier =implicitNamingStrategy.determineJoinColumnName(
new ImplicitJoinColumnNameSource() {
+ final ImplicitJoinColumnNameSource.Nature implicitNamingNature = getImplicitNature();
+
private final EntityNaming entityNaming = new EntityNaming() {
@Override
public String getClassName() {
@@ -666,12 +626,8 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
};
private final AttributePath attributePath = AttributePath.parse( getPropertyName() );
- private final Identifier referencedTableName = getBuildingContext().getMetadataCollector()
- .getDatabase()
- .toIdentifier( logicalTableName );
- private final Identifier referencedColumnName = getBuildingContext().getMetadataCollector()
- .getDatabase()
- .toIdentifier( logicalReferencedColumn );
+ private final Identifier referencedTableName = database.toIdentifier( logicalTableName );
+ private final Identifier referencedColumnName = database.toIdentifier( logicalReferencedColumn );
@Override
public Nature getNature() {
@@ -707,8 +663,10 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
// HHH-11826 magic. See Ejb3Column and the HHH-6005 comments
if ( columnIdentifier.getText().contains( "_collection&&element_" ) ) {
- columnIdentifier = Identifier.toIdentifier( columnIdentifier.getText().replace( "_collection&&element_", "_" ),
- columnIdentifier.isQuoted() );
+ columnIdentifier = Identifier.toIdentifier(
+ columnIdentifier.getText().replace( "_collection&&element_", "_" ),
+ columnIdentifier.isQuoted()
+ );
}
//one element was quoted so we quote
@@ -718,7 +676,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
}
else {
final Identifier logicalTableName = database.toIdentifier(
- getBuildingContext().getMetadataCollector().getLogicalTableName( referencedEntity.getTable() )
+ metadataCollector.getLogicalTableName( referencedEntity.getTable() )
);
// is an intra-entity hierarchy table join so copy the name by default
@@ -750,6 +708,18 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
.render( database.getJdbcEnvironment().getDialect() );
}
+ private ImplicitJoinColumnNameSource.Nature getImplicitNature() {
+ if ( getPropertyHolder().isEntity() ) {
+ return ImplicitJoinColumnNameSource.Nature.ENTITY;
+ }
+ else if ( JPA2ElementCollection ) {
+ return ImplicitJoinColumnNameSource.Nature.ELEMENT_COLLECTION;
+ }
+ else {
+ return ImplicitJoinColumnNameSource.Nature.ENTITY_COLLECTION;
+ }
+ }
+
/**
* used for mappedBy cases
*/
@@ -820,17 +790,14 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
boolean noReferencedColumn = true;
//build the list of potential tables
if ( columns.length == 0 ) return NO_REFERENCE; //shortcut
- Object columnOwner = BinderHelper.findColumnOwner(
- referencedEntity,
- columns[0].getReferencedColumn(),
- context
- );
+ Object columnOwner = findColumnOwner( referencedEntity, columns[0].getReferencedColumn(), context );
if ( columnOwner == null ) {
try {
throw new MappingException(
"Unable to find column with logical name: "
- + columns[0].getReferencedColumn() + " in " + referencedEntity.getTable() + " and its related "
- + "supertables and secondary tables"
+ + columns[0].getReferencedColumn()
+ + " in " + referencedEntity.getTable()
+ + " and its related supertables and secondary tables"
);
}
catch (MappingException e) {
@@ -889,7 +856,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
*/
public void overrideFromReferencedColumnIfNecessary(Column column) {
Column mappingColumn = getMappingColumn();
- if (mappingColumn != null) {
+ if ( mappingColumn != null ) {
// columnDefinition can also be specified using @JoinColumn, hence we have to check
// whether it is set or not
if ( StringHelper.isEmpty( sqlType ) ) {
@@ -924,16 +891,10 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
currentJoinColumn.setPropertyHolder( propertyHolder );
currentJoinColumn.setJoins( secondaryTables );
currentJoinColumn.setBuildingContext( buildingContext );
- currentJoinColumn.setPropertyName(
- BinderHelper.getRelativePath( propertyHolder, propertyName )
- );
+ currentJoinColumn.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
currentJoinColumn.setMappedBy( mappedBy );
currentJoinColumn.bind();
-
- joinColumns = new AnnotatedJoinColumn[] {
- currentJoinColumn
-
- };
+ joinColumns = new AnnotatedJoinColumn[] { currentJoinColumn };
}
else {
joinColumns = new AnnotatedJoinColumn[annJoins.length];
@@ -946,7 +907,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
currentJoinColumn.setPropertyHolder( propertyHolder );
currentJoinColumn.setJoins( secondaryTables );
currentJoinColumn.setBuildingContext( buildingContext );
- currentJoinColumn.setPropertyName( BinderHelper.getRelativePath( propertyHolder, propertyName ) );
+ currentJoinColumn.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
currentJoinColumn.setMappedBy( mappedBy );
currentJoinColumn.setJoinAnnotation( annJoin, propertyName );
currentJoinColumn.setNullable( false ); //I break the spec, but it's for good
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java
index 8fa3d44e66..8794ab8bba 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java
@@ -26,6 +26,8 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
+import jakarta.persistence.SecondaryTable;
+import jakarta.persistence.SecondaryTables;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode;
@@ -229,9 +231,7 @@ import static org.hibernate.cfg.AnnotatedColumn.buildFormulaFromAnnotation;
import static org.hibernate.cfg.AnnotatedDiscriminatorColumn.buildDiscriminatorColumn;
import static org.hibernate.cfg.AnnotatedJoinColumn.buildJoinColumnsWithDefaultColumnSuffix;
import static org.hibernate.cfg.AnnotatedJoinColumn.buildJoinTableJoinColumns;
-import static org.hibernate.cfg.BinderHelper.getMappedSuperclassOrNull;
-import static org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId;
-import static org.hibernate.cfg.BinderHelper.makeIdGenerator;
+import static org.hibernate.cfg.BinderHelper.*;
import static org.hibernate.cfg.InheritanceState.getInheritanceStateOfSuperEntity;
import static org.hibernate.cfg.InheritanceState.getSuperclassInheritanceState;
import static org.hibernate.cfg.PropertyHolderBuilder.buildPropertyHolder;
@@ -584,7 +584,7 @@ public final class AnnotationBinder {
* Bind a class having JSR175 annotations. Subclasses have to be bound after its parent class.
*
* @param clazzToProcess entity to bind as {@code XClass} instance
- * @param inheritanceStatePerClass Meta data about the inheritance relationships for all mapped classes
+ * @param inheritanceStatePerClass Metadata about the inheritance relationships for all mapped classes
*
* @throws MappingException in case there is a configuration error
*/
@@ -802,13 +802,17 @@ public final class AnnotationBinder {
}
private static void handleSecondaryTables(XClass clazzToProcess, EntityBinder entityBinder) {
- jakarta.persistence.SecondaryTable secTabAnn = clazzToProcess.getAnnotation(
- jakarta.persistence.SecondaryTable.class
- );
- jakarta.persistence.SecondaryTables secTabsAnn = clazzToProcess.getAnnotation(
- jakarta.persistence.SecondaryTables.class
- );
- entityBinder.firstLevelSecondaryTablesBinding( secTabAnn, secTabsAnn );
+ SecondaryTable secTable = clazzToProcess.getAnnotation( SecondaryTable.class );
+ SecondaryTables secTables = clazzToProcess.getAnnotation( SecondaryTables.class );
+ if ( secTables != null ) {
+ //loop through it
+ for ( SecondaryTable tab : secTables.value() ) {
+ entityBinder.addJoin( tab, null, false );
+ }
+ }
+ else if ( secTable != null ) {
+ entityBinder.addJoin( secTable, null, false );
+ }
}
private static jakarta.persistence.Table handleClassTable(
@@ -958,7 +962,7 @@ public final class AnnotationBinder {
private static void handleForeignKeys(XClass clazzToProcess, MetadataBuildingContext context, DependantValue key) {
ForeignKey foreignKey = clazzToProcess.getAnnotation( ForeignKey.class );
- if ( foreignKey != null && !BinderHelper.isEmptyAnnotationValue( foreignKey.name() ) ) {
+ if ( foreignKey != null && !isEmptyAnnotationValue( foreignKey.name() ) ) {
key.setForeignKeyName( foreignKey.name() );
}
else {
@@ -972,7 +976,7 @@ public final class AnnotationBinder {
}
else if ( pkJoinColumns != null && !StringHelper.isEmpty( pkJoinColumns.foreignKey().name() ) ) {
key.setForeignKeyName( pkJoinColumns.foreignKey().name() );
- if ( !BinderHelper.isEmptyAnnotationValue( pkJoinColumns.foreignKey().foreignKeyDefinition() ) ) {
+ if ( !isEmptyAnnotationValue( pkJoinColumns.foreignKey().foreignKeyDefinition() ) ) {
key.setForeignKeyDefinition( pkJoinColumns.foreignKey().foreignKeyDefinition() );
}
}
@@ -983,7 +987,7 @@ public final class AnnotationBinder {
}
else if ( pkJoinColumn != null && !StringHelper.isEmpty( pkJoinColumn.foreignKey().name() ) ) {
key.setForeignKeyName( pkJoinColumn.foreignKey().name() );
- if ( !BinderHelper.isEmptyAnnotationValue( pkJoinColumn.foreignKey().foreignKeyDefinition() ) ) {
+ if ( !isEmptyAnnotationValue( pkJoinColumn.foreignKey().foreignKeyDefinition() ) ) {
key.setForeignKeyDefinition( pkJoinColumn.foreignKey().foreignKeyDefinition() );
}
}
@@ -1173,8 +1177,8 @@ public final class AnnotationBinder {
final ConverterRegistrations plural = container.getAnnotation( ConverterRegistrations.class );
if ( plural != null ) {
final ConverterRegistration[] registrations = plural.value();
- for ( int i = 0; i < registrations.length; i++ ) {
- handleConverterRegistration( registrations[i], context );
+ for (ConverterRegistration registration : registrations) {
+ handleConverterRegistration(registration, context);
}
}
}
@@ -2085,7 +2089,7 @@ public final class AnnotationBinder {
else {
throw new AnnotationException(
"@Parent cannot be applied outside an embeddable object: "
- + BinderHelper.getPath( propertyHolder, inferredData )
+ + getPath( propertyHolder, inferredData )
);
}
return;
@@ -2474,7 +2478,7 @@ public final class AnnotationBinder {
&& isToManyAssociationWithinEmbeddableCollection(propertyHolder) ) {
throw new AnnotationException(
"@OneToMany, @ManyToMany or @ElementCollection cannot be used inside an @Embeddable that is also contained within an @ElementCollection: "
- + BinderHelper.getPath(propertyHolder, inferredData)
+ + getPath(propertyHolder, inferredData)
);
}
@@ -2482,7 +2486,7 @@ public final class AnnotationBinder {
&& manyToManyAnn != null && !manyToManyAnn.mappedBy().isEmpty() ) {
throw new AnnotationException(
"Explicit @OrderColumn on inverse side of @ManyToMany is illegal: "
- + BinderHelper.getPath(propertyHolder, inferredData)
+ + getPath(propertyHolder, inferredData)
);
}
@@ -2516,7 +2520,7 @@ public final class AnnotationBinder {
if ( notFound != null ) {
if ( manyToManyAnn == null ) {
throw new AnnotationException("collection annotated @NotFound is not a @ManyToMany association: "
- + BinderHelper.getPath(propertyHolder, inferredData) );
+ + getPath(propertyHolder, inferredData) );
}
collectionBinder.setNotFoundAction( notFound.action() );
}
@@ -2711,7 +2715,7 @@ public final class AnnotationBinder {
Locale.ROOT,
"@Columns not allowed on a @Any property [%s]; @Column or @Formula is used to map the discriminator" +
"and only one is allowed",
- BinderHelper.getPath(propertyHolder, inferredData)
+ getPath(propertyHolder, inferredData)
)
);
}
@@ -2747,7 +2751,7 @@ public final class AnnotationBinder {
|| property.isAnnotationPresent( Columns.class ) ) {
throw new AnnotationException(
"@Column(s) not allowed on a @OneToOne property: "
- + BinderHelper.getPath(propertyHolder, inferredData)
+ + getPath(propertyHolder, inferredData)
);
}
@@ -2817,7 +2821,7 @@ public final class AnnotationBinder {
|| property.isAnnotationPresent( Columns.class ) ) {
throw new AnnotationException(
"@Column(s) not allowed on a @ManyToOne property: "
- + BinderHelper.getPath(propertyHolder, inferredData)
+ + getPath(propertyHolder, inferredData)
);
}
@@ -2896,7 +2900,7 @@ public final class AnnotationBinder {
if ( property.isAnnotationPresent( MapKeyJoinColumn.class ) ) {
throw new AnnotationException(
"@MapKeyJoinColumn and @MapKeyJoinColumns used on the same property: "
- + BinderHelper.getPath(propertyHolder, inferredData)
+ + getPath(propertyHolder, inferredData)
);
}
}
@@ -3077,7 +3081,7 @@ public final class AnnotationBinder {
if ( isIdentifierMapper ) {
throw new AnnotationException(
"@IdClass class should not have @Id nor @EmbeddedId properties: "
- + BinderHelper.getPath( propertyHolder, inferredData )
+ + getPath( propertyHolder, inferredData )
);
}
XClass entityXClass = inferredData.getClassOrElement();
@@ -3216,13 +3220,13 @@ public final class AnnotationBinder {
if ( jpaIndexes != null && jpaIndexes.length > 0 ) {
associationTableBinder.setJpaIndex( jpaIndexes );
}
- if ( !BinderHelper.isEmptyAnnotationValue( schema ) ) {
+ if ( !isEmptyAnnotationValue( schema ) ) {
associationTableBinder.setSchema( schema );
}
- if ( !BinderHelper.isEmptyAnnotationValue( catalog ) ) {
+ if ( !isEmptyAnnotationValue( catalog ) ) {
associationTableBinder.setCatalog( catalog );
}
- if ( !BinderHelper.isEmptyAnnotationValue( tableName ) ) {
+ if ( !isEmptyAnnotationValue( tableName ) ) {
associationTableBinder.setName( tableName );
}
associationTableBinder.setUniqueConstraints( uniqueConstraints );
@@ -3311,14 +3315,14 @@ public final class AnnotationBinder {
throw new AnnotationException(
comp.getComponentClassName()
+ " must not have @Id properties when used as an @EmbeddedId: "
- + BinderHelper.getPath( propertyHolder, inferredData )
+ + getPath( propertyHolder, inferredData )
);
}
if ( referencedEntityName == null && comp.getPropertySpan() == 0 ) {
throw new AnnotationException(
comp.getComponentClassName()
+ " has no persistent id property: "
- + BinderHelper.getPath( propertyHolder, inferredData )
+ + getPath( propertyHolder, inferredData )
);
}
}
@@ -3396,7 +3400,7 @@ public final class AnnotationBinder {
buildingContext
);
- String subpath = BinderHelper.getPath( propertyHolder, inferredData );
+ String subpath = getPath( propertyHolder, inferredData );
LOG.tracev( "Binding component with path: {0}", subpath );
PropertyHolder subHolder = buildPropertyHolder(
comp,
@@ -3738,7 +3742,7 @@ public final class AnnotationBinder {
}
if ( property.isAnnotationPresent( ManyToOne.class ) && joinColumn != null
- && ! BinderHelper.isEmptyAnnotationValue( joinColumn.name() )
+ && ! isEmptyAnnotationValue( joinColumn.name() )
&& joinColumn.name().equals( columnName )
&& !property.isAnnotationPresent( MapsId.class ) ) {
hasSpecjManyToOne = true;
@@ -3823,31 +3827,16 @@ public final class AnnotationBinder {
}
static void defineFetchingStrategy(ToOne toOne, XProperty property) {
+ final FetchType fetchType = getJpaFetchType( property );
+
LazyToOne lazy = property.getAnnotation( LazyToOne.class );
- Fetch fetch = property.getAnnotation( Fetch.class );
- ManyToOne manyToOne = property.getAnnotation( ManyToOne.class );
- OneToOne oneToOne = property.getAnnotation( OneToOne.class );
NotFound notFound = property.getAnnotation( NotFound.class );
-
- FetchType fetchType;
- if ( manyToOne != null ) {
- fetchType = manyToOne.fetch();
- }
- else if ( oneToOne != null ) {
- fetchType = oneToOne.fetch();
- }
- else {
- throw new AssertionFailure(
- "Define fetch strategy on a property not annotated with @OneToMany nor @OneToOne"
- );
- }
-
if ( notFound != null ) {
toOne.setLazy( false );
toOne.setUnwrapProxy( true );
}
else if ( lazy != null ) {
- toOne.setLazy( !( lazy.value() == LazyToOneOption.FALSE ) );
+ toOne.setLazy( lazy.value() != LazyToOneOption.FALSE );
toOne.setUnwrapProxy( ( lazy.value() == LazyToOneOption.NO_PROXY ) );
}
else {
@@ -3856,7 +3845,9 @@ public final class AnnotationBinder {
toOne.setUnwrapProxyImplicit( true );
}
+ Fetch fetch = property.getAnnotation( Fetch.class );
if ( fetch != null ) {
+ // Hibernate @Fetch annotation takes precedence
if ( fetch.value() == org.hibernate.annotations.FetchMode.JOIN ) {
toOne.setFetchMode( FetchMode.JOIN );
toOne.setLazy( false );
@@ -3866,7 +3857,8 @@ public final class AnnotationBinder {
toOne.setFetchMode( FetchMode.SELECT );
}
else if ( fetch.value() == org.hibernate.annotations.FetchMode.SUBSELECT ) {
- throw new AnnotationException( "Use of FetchMode.SUBSELECT not allowed on ToOne associations" );
+ throw new AnnotationException( "Use of FetchMode.SUBSELECT not allowed for to-one associations: "
+ + property.getName() );
}
else {
throw new AssertionFailure( "Unknown FetchMode: " + fetch.value() );
@@ -3877,6 +3869,20 @@ public final class AnnotationBinder {
}
}
+ private static FetchType getJpaFetchType(XProperty property) {
+ ManyToOne manyToOne = property.getAnnotation( ManyToOne.class );
+ OneToOne oneToOne = property.getAnnotation( OneToOne.class );
+ if ( manyToOne != null ) {
+ return manyToOne.fetch();
+ }
+ else if ( oneToOne != null ) {
+ return oneToOne.fetch();
+ }
+ else {
+ throw new AssertionFailure("Define fetch strategy on a property not annotated with @OneToMany nor @OneToOne");
+ }
+ }
+
private static void bindOneToOne(
String cascadeStrategy,
AnnotatedJoinColumn[] joinColumns,
@@ -3896,34 +3902,7 @@ public final class AnnotationBinder {
//column.getTable() => persistentClass.getTable()
final String propertyName = inferredData.getPropertyName();
LOG.tracev( "Fetching {0} with {1}", propertyName, fetchMode );
- boolean mapToPK = true;
- if ( !trueOneToOne ) {
- //try to find a hidden true one to one (FK == PK columns)
- KeyValue identifier = propertyHolder.getIdentifier();
- if ( identifier == null ) {
- //this is a @OneToOne in an @EmbeddedId (the persistentClass.identifier is not set yet, it's being built)
- //by definition the PK cannot refer to itself so it cannot map to itself
- mapToPK = false;
- }
- else {
- List idColumnNames = new ArrayList<>();
- if ( identifier.getColumnSpan() != joinColumns.length ) {
- mapToPK = false;
- }
- else {
- for ( org.hibernate.mapping.Column currentColumn : identifier.getColumns() ) {
- idColumnNames.add( currentColumn.getName() );
- }
- for ( AnnotatedJoinColumn col : joinColumns ) {
- if ( !idColumnNames.contains( col.getMappingColumn().getName() ) ) {
- mapToPK = false;
- break;
- }
- }
- }
- }
- }
- if ( trueOneToOne || mapToPK || !BinderHelper.isEmptyAnnotationValue( mappedBy ) ) {
+ if ( isMapToPK( joinColumns, propertyHolder, trueOneToOne ) || !isEmptyAnnotationValue( mappedBy ) ) {
//is a true one-to-one
//FIXME referencedColumnName ignored => ordering may fail.
OneToOneSecondPass secondPass = new OneToOneSecondPass(
@@ -3944,10 +3923,7 @@ public final class AnnotationBinder {
secondPass.doSecondPass( context.getMetadataCollector().getEntityBindingMap() );
}
else {
- context.getMetadataCollector().addSecondPass(
- secondPass,
- BinderHelper.isEmptyAnnotationValue( mappedBy )
- );
+ context.getMetadataCollector().addSecondPass( secondPass, isEmptyAnnotationValue( mappedBy ) );
}
}
else {
@@ -3961,6 +3937,38 @@ public final class AnnotationBinder {
}
}
+ private static boolean isMapToPK(AnnotatedJoinColumn[] joinColumns, PropertyHolder propertyHolder, boolean trueOneToOne) {
+ if ( trueOneToOne ) {
+ return true;
+ }
+ else {
+ //try to find a hidden true one to one (FK == PK columns)
+ KeyValue identifier = propertyHolder.getIdentifier();
+ if ( identifier == null ) {
+ //this is a @OneToOne in an @EmbeddedId (the persistentClass.identifier is not set yet, it's being built)
+ //by definition the PK cannot refer to itself so it cannot map to itself
+ return false;
+ }
+ else {
+ List idColumnNames = new ArrayList<>();
+ if ( identifier.getColumnSpan() != joinColumns.length ) {
+ return false;
+ }
+ else {
+ for ( org.hibernate.mapping.Column currentColumn: identifier.getColumns() ) {
+ idColumnNames.add( currentColumn.getName() );
+ }
+ for ( AnnotatedJoinColumn col: joinColumns) {
+ if ( !idColumnNames.contains( col.getMappingColumn().getName() ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ }
+ }
+
private static void bindAny(
String cascadeStrategy,
AnnotatedJoinColumn[] columns,
@@ -3971,23 +3979,16 @@ public final class AnnotationBinder {
EntityBinder entityBinder,
boolean isIdentifierMapper,
MetadataBuildingContext buildingContext) {
- XProperty property = inferredData.getProperty();
- org.hibernate.annotations.Any anyAnn = property
- .getAnnotation( org.hibernate.annotations.Any.class );
- if ( anyAnn == null ) {
- throw new AssertionFailure(
- "Missing @Any annotation: "
- + BinderHelper.getPath( propertyHolder, inferredData )
- );
+ final XProperty property = inferredData.getProperty();
+ final org.hibernate.annotations.Any any = property.getAnnotation( org.hibernate.annotations.Any.class );
+ if ( any == null ) {
+ throw new AssertionFailure( "Missing @Any annotation: " + getPath( propertyHolder, inferredData ) );
}
- final Column discriminatorColumnAnn = property.getAnnotation( Column.class );
- final Formula discriminatorFormulaAnn = getOverridableAnnotation( property, Formula.class, buildingContext );
-
- boolean lazy = ( anyAnn.fetch() == FetchType.LAZY );
- Any value = BinderHelper.buildAnyValue(
- discriminatorColumnAnn,
- discriminatorFormulaAnn,
+ final boolean lazy = any.fetch() == FetchType.LAZY;
+ final Any value = BinderHelper.buildAnyValue(
+ property.getAnnotation( Column.class ),
+ getOverridableAnnotation( property, Formula.class, buildingContext ),
columns,
inferredData,
cascadeOnDelete,
@@ -3995,11 +3996,11 @@ public final class AnnotationBinder {
nullability,
propertyHolder,
entityBinder,
- anyAnn.optional(),
+ any.optional(),
buildingContext
);
- PropertyBinder binder = new PropertyBinder();
+ final PropertyBinder binder = new PropertyBinder();
binder.setName( inferredData.getPropertyName() );
binder.setValue( value );
@@ -4021,33 +4022,32 @@ public final class AnnotationBinder {
}
private static EnumSet convertToHibernateCascadeType(jakarta.persistence.CascadeType[] ejbCascades) {
- EnumSet hibernateCascadeSet = EnumSet.noneOf( CascadeType.class );
+ final EnumSet cascadeTypes = EnumSet.noneOf( CascadeType.class );
if ( ejbCascades != null && ejbCascades.length > 0 ) {
- for ( jakarta.persistence.CascadeType cascade : ejbCascades ) {
- switch ( cascade ) {
- case ALL:
- hibernateCascadeSet.add( CascadeType.ALL );
- break;
- case PERSIST:
- hibernateCascadeSet.add( CascadeType.PERSIST );
- break;
- case MERGE:
- hibernateCascadeSet.add( CascadeType.MERGE );
- break;
- case REMOVE:
- hibernateCascadeSet.add( CascadeType.REMOVE );
- break;
- case REFRESH:
- hibernateCascadeSet.add( CascadeType.REFRESH );
- break;
- case DETACH:
- hibernateCascadeSet.add( CascadeType.DETACH );
- break;
- }
+ for ( jakarta.persistence.CascadeType cascade: ejbCascades ) {
+ cascadeTypes.add( convertCascadeType( cascade ) );
}
}
+ return cascadeTypes;
+ }
- return hibernateCascadeSet;
+ private static CascadeType convertCascadeType(jakarta.persistence.CascadeType cascade) {
+ switch (cascade) {
+ case ALL:
+ return CascadeType.ALL;
+ case PERSIST:
+ return CascadeType.PERSIST;
+ case MERGE:
+ return CascadeType.MERGE;
+ case REMOVE:
+ return CascadeType.REMOVE;
+ case REFRESH:
+ return CascadeType.REFRESH;
+ case DETACH:
+ return CascadeType.DETACH;
+ default:
+ throw new AssertionFailure("unknown cascade type: " + cascade);
+ }
}
private static String getCascadeStrategy(
@@ -4055,26 +4055,25 @@ public final class AnnotationBinder {
Cascade hibernateCascadeAnnotation,
boolean orphanRemoval,
boolean forcePersist) {
- EnumSet hibernateCascadeSet = convertToHibernateCascadeType( ejbCascades );
- CascadeType[] hibernateCascades = hibernateCascadeAnnotation == null ?
- null :
- hibernateCascadeAnnotation.value();
-
+ EnumSet cascadeTypes = convertToHibernateCascadeType( ejbCascades );
+ CascadeType[] hibernateCascades = hibernateCascadeAnnotation == null ? null : hibernateCascadeAnnotation.value();
if ( hibernateCascades != null && hibernateCascades.length > 0 ) {
- hibernateCascadeSet.addAll( Arrays.asList( hibernateCascades ) );
+ cascadeTypes.addAll( Arrays.asList( hibernateCascades ) );
}
-
if ( orphanRemoval ) {
- hibernateCascadeSet.add( CascadeType.DELETE_ORPHAN );
- hibernateCascadeSet.add( CascadeType.REMOVE );
+ cascadeTypes.add( CascadeType.DELETE_ORPHAN );
+ cascadeTypes.add( CascadeType.REMOVE );
}
if ( forcePersist ) {
- hibernateCascadeSet.add( CascadeType.PERSIST );
+ cascadeTypes.add( CascadeType.PERSIST );
}
+ return renderCascadeTypeList( cascadeTypes );
+ }
+ private static String renderCascadeTypeList(EnumSet cascadeTypes) {
StringBuilder cascade = new StringBuilder();
- for ( CascadeType aHibernateCascadeSet : hibernateCascadeSet ) {
- switch ( aHibernateCascadeSet ) {
+ for ( CascadeType cascadeType : cascadeTypes) {
+ switch ( cascadeType ) {
case ALL:
cascade.append( "," ).append( "all" );
break;
@@ -4108,9 +4107,7 @@ public final class AnnotationBinder {
break;
}
}
- return cascade.length() > 0 ?
- cascade.substring( 1 ) :
- "none";
+ return cascade.length() > 0 ? cascade.substring( 1 ) : "none";
}
public static FetchMode getFetchMode(FetchType fetch) {
@@ -4124,55 +4121,54 @@ public final class AnnotationBinder {
JoinColumn joinColumn,
JoinColumns joinColumns,
MetadataBuildingContext context) {
- final boolean noConstraintByDefault = context.getBuildingOptions().isNoConstraintByDefault();
- final NotFound notFoundAnn= property.getAnnotation( NotFound.class );
-
- if ( notFoundAnn != null ) {
+ if ( property.getAnnotation( NotFound.class ) != null ) {
// supersedes all others
value.disableForeignKey();
}
- else if ( joinColumn != null && (
- joinColumn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
- || ( joinColumn.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) ) {
- value.disableForeignKey();
- }
- else if ( joinColumns != null && (
- joinColumns.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
- || ( joinColumns.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) ) {
- value.disableForeignKey();
- }
else {
- final ForeignKey fk = property.getAnnotation( ForeignKey.class );
- if ( fk != null && StringHelper.isNotEmpty( fk.name() ) ) {
- value.setForeignKeyName( fk.name() );
+ if ( joinColumn!=null && noConstraint( joinColumn.foreignKey(), context )
+ || joinColumns!=null && noConstraint( joinColumns.foreignKey(), context ) ) {
+ value.disableForeignKey();
}
else {
- if ( fkOverride != null && ( fkOverride.value() == ConstraintMode.NO_CONSTRAINT
- || fkOverride.value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) {
- value.disableForeignKey();
+ final ForeignKey fk = property.getAnnotation( ForeignKey.class );
+ if ( fk != null && StringHelper.isNotEmpty( fk.name() ) ) {
+ value.setForeignKeyName( fk.name() );
}
- else if ( fkOverride != null ) {
- value.setForeignKeyName( nullIfEmpty( fkOverride.name() ) );
- value.setForeignKeyDefinition( nullIfEmpty( fkOverride.foreignKeyDefinition() ) );
- }
- else if ( joinColumns != null ) {
- value.setForeignKeyName( nullIfEmpty( joinColumns.foreignKey().name() ) );
- value.setForeignKeyDefinition( nullIfEmpty( joinColumns.foreignKey().foreignKeyDefinition() ) );
- }
- else if ( joinColumn != null ) {
- value.setForeignKeyName( nullIfEmpty( joinColumn.foreignKey().name() ) );
- value.setForeignKeyDefinition( nullIfEmpty( joinColumn.foreignKey().foreignKeyDefinition() ) );
+ else {
+ if ( noConstraint( fkOverride, context) ) {
+ value.disableForeignKey();
+ }
+ else if ( fkOverride != null ) {
+ value.setForeignKeyName( nullIfEmpty( fkOverride.name() ) );
+ value.setForeignKeyDefinition( nullIfEmpty( fkOverride.foreignKeyDefinition() ) );
+ }
+ else if ( joinColumns != null ) {
+ value.setForeignKeyName( nullIfEmpty( joinColumns.foreignKey().name() ) );
+ value.setForeignKeyDefinition( nullIfEmpty( joinColumns.foreignKey().foreignKeyDefinition() ) );
+ }
+ else if ( joinColumn != null ) {
+ value.setForeignKeyName( nullIfEmpty( joinColumn.foreignKey().name() ) );
+ value.setForeignKeyDefinition( nullIfEmpty( joinColumn.foreignKey().foreignKeyDefinition() ) );
+ }
}
}
}
}
+ private static boolean noConstraint(jakarta.persistence.ForeignKey joinColumns, MetadataBuildingContext context) {
+ return joinColumns != null
+ && ( joinColumns.value() == ConstraintMode.NO_CONSTRAINT
+ || joinColumns.value() == ConstraintMode.PROVIDER_DEFAULT
+ && context.getBuildingOptions().isNoConstraintByDefault() );
+ }
+
private static HashMap buildGenerators(
XAnnotatedElement annElt,
MetadataBuildingContext context) {
- InFlightMetadataCollector metadataCollector = context.getMetadataCollector();
- HashMap generators = new HashMap<>();
+ final InFlightMetadataCollector metadataCollector = context.getMetadataCollector();
+ final HashMap generators = new HashMap<>();
TableGenerators tableGenerators = annElt.getAnnotation( TableGenerators.class );
if ( tableGenerators != null ) {
@@ -4205,24 +4201,27 @@ public final class AnnotationBinder {
}
TableGenerator tabGen = annElt.getAnnotation( TableGenerator.class );
- SequenceGenerator seqGen = annElt.getAnnotation( SequenceGenerator.class );
- GenericGenerator genGen = annElt.getAnnotation( GenericGenerator.class );
if ( tabGen != null ) {
IdentifierGeneratorDefinition idGen = buildIdGenerator( tabGen, context );
generators.put( idGen.getName(), idGen );
metadataCollector.addIdentifierGenerator( idGen );
}
+
+ SequenceGenerator seqGen = annElt.getAnnotation( SequenceGenerator.class );
if ( seqGen != null ) {
IdentifierGeneratorDefinition idGen = buildIdGenerator( seqGen, context );
generators.put( idGen.getName(), idGen );
metadataCollector.addIdentifierGenerator( idGen );
}
+
+ GenericGenerator genGen = annElt.getAnnotation( GenericGenerator.class );
if ( genGen != null ) {
IdentifierGeneratorDefinition idGen = buildIdGenerator( genGen, context );
generators.put( idGen.getName(), idGen );
metadataCollector.addIdentifierGenerator( idGen );
}
+
return generators;
}
@@ -4243,8 +4242,8 @@ public final class AnnotationBinder {
MetadataBuildingContext buildingContext) {
Map inheritanceStatePerClass = new HashMap<>( orderedClasses.size() );
for ( XClass clazz : orderedClasses ) {
- InheritanceState superclassState = getSuperclassInheritanceState( clazz, inheritanceStatePerClass );
- InheritanceState state = new InheritanceState( clazz, inheritanceStatePerClass, buildingContext );
+ final InheritanceState superclassState = getSuperclassInheritanceState( clazz, inheritanceStatePerClass );
+ final InheritanceState state = new InheritanceState( clazz, inheritanceStatePerClass, buildingContext );
if ( superclassState != null ) {
//the classes are ordered thus preventing an NPE
//FIXME if an entity has subclasses annotated @MappedSuperclass wo sub @Entity this is wrong
@@ -4272,9 +4271,6 @@ public final class AnnotationBinder {
}
private static boolean hasAnnotationsOnIdClass(XClass idClass) {
-// if(idClass.getAnnotation(Embeddable.class) != null)
-// return true;
-
for ( XProperty property : idClass.getDeclaredProperties( XClass.ACCESS_FIELD ) ) {
if ( hasTriggeringAnnotation(property) ) {
return true;
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java b/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java
index f038dbca93..e71b6d6ba8 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java
@@ -152,7 +152,7 @@ public class BinderHelper {
embeddedComp.setEmbedded( true );
embeddedComp.setComponentClassName( embeddedComp.getOwner().getClassName() );
for (Property property : properties) {
- Property clone = BinderHelper.shallowCopy( property );
+ Property clone = shallowCopy( property );
clone.setInsertable( false );
clone.setUpdateable( false );
clone.setNaturalIdentifier( false );
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java
index a6ec2b89f6..3365c19e86 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java
@@ -30,12 +30,12 @@ public abstract class CollectionSecondPass implements SecondPass {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, CollectionSecondPass.class.getName());
- MetadataBuildingContext buildingContext;
- Collection collection;
+// MetadataBuildingContext buildingContext;
+ private final Collection collection;
public CollectionSecondPass(MetadataBuildingContext buildingContext, Collection collection) {
this.collection = collection;
- this.buildingContext = buildingContext;
+// this.buildingContext = buildingContext;
}
public void doSecondPass(Map persistentClasses)
@@ -49,8 +49,9 @@ public abstract class CollectionSecondPass implements SecondPass {
if ( LOG.isDebugEnabled() ) {
String msg = "Mapped collection key: " + columns( collection.getKey() );
- if ( collection.isIndexed() )
+ if ( collection.isIndexed() ) {
msg += ", index: " + columns( ( (IndexedCollection) collection ).getIndex() );
+ }
if ( collection.isOneToMany() ) {
msg += ", one-to-many: "
+ ( (OneToMany) collection.getElement() ).getReferencedEntityName();
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java b/hibernate-core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java
index a800a826f6..b801b29bfa 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java
@@ -33,6 +33,8 @@ import static org.hibernate.cfg.AnnotatedColumn.buildColumnFromNoAnnotation;
import static org.hibernate.cfg.AnnotatedColumn.buildColumnsFromAnnotations;
import static org.hibernate.cfg.AnnotatedColumn.buildFormulaFromAnnotation;
import static org.hibernate.cfg.AnnotationBinder.getOverridableAnnotation;
+import static org.hibernate.cfg.BinderHelper.getPath;
+import static org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId;
/**
* Do the initial discovery of columns metadata and apply defaults.
@@ -139,7 +141,7 @@ class ColumnsBuilder {
}
else if ( joinColumns == null && property.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
throw new AnnotationException( "@Any requires an explicit @JoinColumn(s): "
- + BinderHelper.getPath( propertyHolder, inferredData ) );
+ + getPath( propertyHolder, inferredData ) );
}
if ( columns == null && !property.isAnnotationPresent( ManyToMany.class ) ) {
//useful for collection of embedded elements
@@ -179,7 +181,7 @@ class ColumnsBuilder {
if ( StringHelper.isEmpty( joinTableAnn.name() ) ) {
throw new AnnotationException(
"JoinTable.name() on a @ToOne association has to be explicit: "
- + BinderHelper.getPath( propertyHolder, inferredData )
+ + getPath( propertyHolder, inferredData )
);
}
}
@@ -275,7 +277,7 @@ class ColumnsBuilder {
AnnotatedColumn[] overrideColumnFromMapperOrMapsIdProperty(boolean isId) {
AnnotatedColumn[] result = columns;
- final PropertyData overridingProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(
+ final PropertyData overridingProperty = getPropertyOverriddenByMapperOrMapsId(
isId,
propertyHolder,
property.getName(),
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java
index b335c07621..7117bd695b 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java
@@ -28,6 +28,9 @@ import org.hibernate.mapping.SimpleValue;
import org.jboss.logging.Logger;
+import static org.hibernate.cfg.BinderHelper.isEmptyAnnotationValue;
+import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize;
+
/**
* @author Emmanuel Bernard
*/
@@ -79,13 +82,13 @@ public class CopyIdentifierComponentSecondPass extends FkSecondPass {
//prepare column name structure
boolean isExplicitReference = true;
- Map columnByReferencedName = CollectionHelper.mapOfSize( joinColumns.length);
+ Map columnByReferencedName = mapOfSize( joinColumns.length);
for (AnnotatedJoinColumn joinColumn : joinColumns) {
final String referencedColumnName = joinColumn.getReferencedColumn();
- if ( referencedColumnName == null || BinderHelper.isEmptyAnnotationValue( referencedColumnName ) ) {
+ if ( referencedColumnName == null || isEmptyAnnotationValue( referencedColumnName ) ) {
break;
}
- //JPA 2 requires referencedColumnNames to be case insensitive
+ //JPA 2 requires referencedColumnNames to be case-insensitive
columnByReferencedName.put( referencedColumnName.toLowerCase(Locale.ROOT), joinColumn );
}
//try default column orientation
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/IdGeneratorResolverSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/IdGeneratorResolverSecondPass.java
index 0e6f4a537b..0e1e54f61e 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/IdGeneratorResolverSecondPass.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/IdGeneratorResolverSecondPass.java
@@ -15,6 +15,8 @@ import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.SimpleValue;
+import static org.hibernate.cfg.BinderHelper.makeIdGenerator;
+
/**
* @author Andrea Boriero
*/
@@ -52,6 +54,6 @@ public class IdGeneratorResolverSecondPass implements SecondPass {
@Override
public void doSecondPass(Map idGeneratorDefinitionMap) throws MappingException {
- BinderHelper.makeIdGenerator( id, idXProperty, generatorType, generatorName, buildingContext, localIdentifierGeneratorDefinition );
+ makeIdGenerator( id, idXProperty, generatorType, generatorName, buildingContext, localIdentifierGeneratorDefinition );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/IndexColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/IndexColumn.java
index 38a68f6ed0..27cfdbbd94 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/IndexColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/IndexColumn.java
@@ -12,6 +12,8 @@ import org.hibernate.annotations.ListIndexBase;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.mapping.Join;
+import static org.hibernate.cfg.BinderHelper.isEmptyAnnotationValue;
+
/**
* index column
*
@@ -134,8 +136,8 @@ public class IndexColumn extends AnnotatedColumn {
MetadataBuildingContext buildingContext) {
final IndexColumn column;
if ( ann != null ) {
- final String sqlType = BinderHelper.isEmptyAnnotationValue( ann.columnDefinition() ) ? null : ann.columnDefinition();
- final String name = BinderHelper.isEmptyAnnotationValue( ann.name() ) ? inferredData.getPropertyName() + "_ORDER" : ann.name();
+ final String sqlType = isEmptyAnnotationValue( ann.columnDefinition() ) ? null : ann.columnDefinition();
+ final String name = isEmptyAnnotationValue( ann.name() ) ? inferredData.getPropertyName() + "_ORDER" : ann.name();
//TODO move it to a getter based system and remove the constructor
// The JPA OrderColumn annotation defines no table element...
// column = new IndexColumn(
@@ -198,8 +200,8 @@ public class IndexColumn extends AnnotatedColumn {
MetadataBuildingContext buildingContext) {
final IndexColumn column;
if ( ann != null ) {
- final String sqlType = BinderHelper.isEmptyAnnotationValue( ann.columnDefinition() ) ? null : ann.columnDefinition();
- final String name = BinderHelper.isEmptyAnnotationValue( ann.name() ) ? inferredData.getPropertyName() : ann.name();
+ final String sqlType = isEmptyAnnotationValue( ann.columnDefinition() ) ? null : ann.columnDefinition();
+ final String name = isEmptyAnnotationValue( ann.name() ) ? inferredData.getPropertyName() : ann.name();
//TODO move it to a getter based system and remove the constructor
column = new IndexColumn(
false,
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
index 8123af8b78..467bf2b79c 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
@@ -30,6 +30,10 @@ import org.hibernate.mapping.Property;
import org.hibernate.mapping.SortableValue;
import org.hibernate.type.ForeignKeyDirection;
+import static org.hibernate.cfg.BinderHelper.findPropertyByName;
+import static org.hibernate.cfg.BinderHelper.isEmptyAnnotationValue;
+import static org.hibernate.internal.util.StringHelper.qualify;
+
/**
* We have to handle OneToOne in a second pass because:
* -
@@ -93,7 +97,7 @@ public class OneToOneSecondPass implements SecondPass {
//value.setLazy( fetchMode != FetchMode.JOIN );
value.setConstrained( !optional );
- final ForeignKeyDirection foreignKeyDirection = !BinderHelper.isEmptyAnnotationValue( mappedBy )
+ final ForeignKeyDirection foreignKeyDirection = !isEmptyAnnotationValue( mappedBy )
? ForeignKeyDirection.TO_PARENT
: ForeignKeyDirection.FROM_PARENT;
value.setForeignKeyType(foreignKeyDirection);
@@ -120,7 +124,7 @@ public class OneToOneSecondPass implements SecondPass {
Property prop = binder.makeProperty();
prop.setOptional( optional );
- if ( BinderHelper.isEmptyAnnotationValue( mappedBy ) ) {
+ if ( isEmptyAnnotationValue( mappedBy ) ) {
/*
* we need to check if the columns are in the right order
* if not, then we need to create a many to one and formula
@@ -130,7 +134,7 @@ public class OneToOneSecondPass implements SecondPass {
boolean rightOrder = true;
if ( rightOrder ) {
- String path = StringHelper.qualify( propertyHolder.getPath(), propertyName );
+ String path = qualify( propertyHolder.getPath(), propertyName );
final ToOneFkSecondPass secondPass = new ToOneFkSecondPass(
value,
joinColumns,
@@ -155,20 +159,20 @@ public class OneToOneSecondPass implements SecondPass {
if ( otherSide == null ) {
throw new MappingException( "Unable to find entity: " + value.getReferencedEntityName() );
}
- otherSideProperty = BinderHelper.findPropertyByName( otherSide, mappedBy );
+ otherSideProperty = findPropertyByName( otherSide, mappedBy );
}
catch (MappingException e) {
throw new AnnotationException(
- "Unknown mappedBy in: " + StringHelper.qualify( ownerEntity, ownerProperty )
+ "Unknown mappedBy in: " + qualify( ownerEntity, ownerProperty )
+ ", referenced property unknown: "
- + StringHelper.qualify( value.getReferencedEntityName(), mappedBy )
+ + qualify( value.getReferencedEntityName(), mappedBy )
);
}
if ( otherSideProperty == null ) {
throw new AnnotationException(
- "Unknown mappedBy in: " + StringHelper.qualify( ownerEntity, ownerProperty )
+ "Unknown mappedBy in: " + qualify( ownerEntity, ownerProperty )
+ ", referenced property unknown: "
- + StringHelper.qualify( value.getReferencedEntityName(), mappedBy )
+ + qualify( value.getReferencedEntityName(), mappedBy )
);
}
if ( otherSideProperty.getValue() instanceof OneToOne ) {
@@ -238,11 +242,11 @@ public class OneToOneSecondPass implements SecondPass {
else {
throw new AnnotationException(
"Referenced property not a (One|Many)ToOne: "
- + StringHelper.qualify(
+ + qualify(
otherSide.getEntityName(), mappedBy
)
+ " in mappedBy of "
- + StringHelper.qualify( ownerEntity, ownerProperty )
+ + qualify( ownerEntity, ownerProperty )
);
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java
index 9881446753..3268b9080b 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java
@@ -20,6 +20,8 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.ToOne;
+import static org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference;
+
/**
* Enable a proper set of the FK columns in respect with the id column order
* Allow the correct implementation of the default EJB3 values which needs both
@@ -99,7 +101,7 @@ public class ToOneFkSecondPass extends FkSecondPass {
);
}
manyToOne.setPropertyName( path );
- BinderHelper.createSyntheticPropertyReference( columns, ref, null, manyToOne, false, buildingContext );
+ createSyntheticPropertyReference( columns, ref, null, manyToOne, false, buildingContext );
TableBinder.bindFk( ref, null, columns, manyToOne, unique, buildingContext );
/*
* HbmMetadataSourceProcessorImpl does this only when property-ref != null, but IMO, it makes sense event if it is null
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
index bd738675f1..f0d664e0a3 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
@@ -19,7 +19,6 @@ import jakarta.persistence.AttributeOverrides;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.ConstraintMode;
import jakarta.persistence.ElementCollection;
-import jakarta.persistence.Embeddable;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinColumns;
@@ -90,7 +89,6 @@ import org.hibernate.cfg.AnnotatedColumn;
import org.hibernate.cfg.AnnotatedJoinColumn;
import org.hibernate.cfg.AnnotationBinder;
import org.hibernate.cfg.AvailableSettings;
-import org.hibernate.cfg.BinderHelper;
import org.hibernate.cfg.CollectionPropertyHolder;
import org.hibernate.cfg.CollectionSecondPass;
import org.hibernate.cfg.IndexColumn;
@@ -104,7 +102,6 @@ import org.hibernate.cfg.SecondPass;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.CoreMessageLogger;
-import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.mapping.Any;
@@ -136,10 +133,18 @@ import static jakarta.persistence.AccessType.PROPERTY;
import static org.hibernate.cfg.AnnotatedColumn.checkPropertyConsistency;
import static org.hibernate.cfg.AnnotationBinder.fillComponent;
import static org.hibernate.cfg.AnnotationBinder.getOverridableAnnotation;
+import static org.hibernate.cfg.BinderHelper.PRIMITIVE_NAMES;
+import static org.hibernate.cfg.BinderHelper.buildAnyValue;
+import static org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference;
import static org.hibernate.cfg.BinderHelper.isEmptyAnnotationValue;
import static org.hibernate.cfg.BinderHelper.toAliasEntityMap;
import static org.hibernate.cfg.BinderHelper.toAliasTableMap;
import static org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle.fromExternalName;
+import static org.hibernate.internal.util.StringHelper.getNonEmptyOrConjunctionIfBothNonEmpty;
+import static org.hibernate.internal.util.StringHelper.isEmpty;
+import static org.hibernate.internal.util.StringHelper.isNotEmpty;
+import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
+import static org.hibernate.internal.util.StringHelper.qualify;
/**
* Base class for binding different types of collections to Hibernate configuration objects.
@@ -295,12 +300,11 @@ public abstract class CollectionBinder {
XProperty property,
boolean isHibernateExtensionMapping,
MetadataBuildingContext buildingContext) {
- final CollectionType typeAnnotation = HCANNHelper.findAnnotation( property, CollectionType.class );
final CollectionBinder binder;
+ final CollectionType typeAnnotation = HCANNHelper.findAnnotation( property, CollectionType.class );
if ( typeAnnotation != null ) {
binder = createBinderFromCustomTypeAnnotation( property, typeAnnotation, buildingContext );
-
// todo (6.0) - technically, these should no longer be needed
binder.explicitType = typeAnnotation.type().getName();
for ( Parameter param : typeAnnotation.parameters() ) {
@@ -308,23 +312,21 @@ public abstract class CollectionBinder {
}
}
else {
- final CollectionClassification classification = determineCollectionClassification( property, buildingContext );
- final CollectionTypeRegistrationDescriptor typeRegistration = buildingContext
- .getMetadataCollector()
- .findCollectionTypeRegistration( classification );
- if ( typeRegistration != null ) {
- binder = createBinderFromTypeRegistration( property, classification, typeRegistration, buildingContext );
- }
- else {
- binder = createBinderFromProperty( property, buildingContext );
- }
+ binder = createBinderAutomatically( property, buildingContext );
}
-
binder.setIsHibernateExtensionMapping( isHibernateExtensionMapping );
-
return binder;
}
+ private static CollectionBinder createBinderAutomatically(XProperty property, MetadataBuildingContext buildingContext) {
+ final CollectionClassification classification = determineCollectionClassification( property, buildingContext );
+ final CollectionTypeRegistrationDescriptor typeRegistration = buildingContext.getMetadataCollector()
+ .findCollectionTypeRegistration( classification );
+ return typeRegistration != null
+ ? createBinderFromTypeRegistration( property, classification, typeRegistration, buildingContext )
+ : createBinderFromProperty( property, buildingContext );
+ }
+
private static CollectionBinder createBinderFromTypeRegistration(
XProperty property,
CollectionClassification classification,
@@ -390,8 +392,8 @@ public abstract class CollectionBinder {
CollectionType typeAnnotation,
MetadataBuildingContext buildingContext) {
determineSemanticJavaType( property );
-
- final ManagedBean extends UserCollectionType> customTypeBean = resolveCustomType( property, typeAnnotation, buildingContext );
+ final ManagedBean extends UserCollectionType> customTypeBean
+ = resolveCustomType( property, typeAnnotation, buildingContext );
return createBinder(
property,
() -> customTypeBean,
@@ -455,48 +457,37 @@ public abstract class CollectionBinder {
CollectionClassification classification,
MetadataBuildingContext buildingContext) {
switch ( classification ) {
- case ARRAY: {
- if ( property.getElementClass().isPrimitive() ) {
- return new PrimitiveArrayBinder( customTypeBeanAccess, buildingContext );
- }
- return new ArrayBinder( customTypeBeanAccess, buildingContext );
- }
- case BAG: {
+ case ARRAY:
+ return property.getElementClass().isPrimitive()
+ ? new PrimitiveArrayBinder( customTypeBeanAccess, buildingContext )
+ : new ArrayBinder( customTypeBeanAccess, buildingContext );
+ case BAG:
return new BagBinder( customTypeBeanAccess, buildingContext );
- }
- case ID_BAG: {
+ case ID_BAG:
return new IdBagBinder( customTypeBeanAccess, buildingContext );
- }
- case LIST: {
+ case LIST:
return new ListBinder( customTypeBeanAccess, buildingContext );
- }
case MAP:
- case ORDERED_MAP: {
+ case ORDERED_MAP:
return new MapBinder( customTypeBeanAccess, false, buildingContext );
- }
- case SORTED_MAP: {
+ case SORTED_MAP:
return new MapBinder( customTypeBeanAccess, true, buildingContext );
- }
case SET:
- case ORDERED_SET: {
+ case ORDERED_SET:
return new SetBinder( customTypeBeanAccess, false, buildingContext );
- }
- case SORTED_SET: {
+ case SORTED_SET:
return new SetBinder( customTypeBeanAccess, true, buildingContext );
- }
+ default:
+ throw new AnnotationException(
+ String.format(
+ Locale.ROOT,
+ "Unable to determine proper CollectionBinder (`%s) : %s.%s",
+ classification,
+ property.getDeclaringClass().getName(),
+ property.getName()
+ )
+ );
}
-
- final XClass declaringClass = property.getDeclaringClass();
-
- throw new AnnotationException(
- String.format(
- Locale.ROOT,
- "Unable to determine proper CollectionBinder (`%s) : %s.%s",
- classification,
- declaringClass.getName(),
- property.getName()
- )
- );
}
private static CollectionClassification determineCollectionClassification(
@@ -505,31 +496,29 @@ public abstract class CollectionBinder {
if ( property.isArray() ) {
return CollectionClassification.ARRAY;
}
-
- final Bag bagAnnotation = HCANNHelper.findAnnotation( property, Bag.class );
- if ( bagAnnotation != null ) {
+ else if ( HCANNHelper.findAnnotation( property, Bag.class ) == null ) {
+ return determineCollectionClassification( determineSemanticJavaType( property ), property, buildingContext );
+ }
+ else {
final Class> collectionJavaType = property.getCollectionClass();
- if ( java.util.List.class.equals( collectionJavaType ) || java.util.Collection.class.equals( collectionJavaType ) ) {
+ if ( java.util.List.class.equals( collectionJavaType )
+ || java.util.Collection.class.equals( collectionJavaType ) ) {
return CollectionClassification.BAG;
}
- throw new MappingException(
- String.format(
- Locale.ROOT,
- "@Bag annotation encountered on an attribute `%s#%s` of type `%s`; only `%s` and `%s` are supported",
- property.getDeclaringClass().getName(),
- property.getName(),
- collectionJavaType.getName(),
- java.util.List.class.getName(),
- java.util.Collection.class.getName()
- )
- );
+ else {
+ throw new MappingException(
+ String.format(
+ Locale.ROOT,
+ "@Bag annotation encountered on an attribute `%s#%s` of type `%s`; only `%s` and `%s` are supported",
+ property.getDeclaringClass().getName(),
+ property.getName(),
+ collectionJavaType.getName(),
+ java.util.List.class.getName(),
+ java.util.Collection.class.getName()
+ )
+ );
+ }
}
-
- return determineCollectionClassification(
- determineSemanticJavaType( property ),
- property,
- buildingContext
- );
}
private static CollectionClassification determineCollectionClassification(
@@ -561,12 +550,12 @@ public abstract class CollectionBinder {
return CollectionClassification.BAG;
}
ManyToMany manyToMany = property.getAnnotation( ManyToMany.class );
- if ( manyToMany != null && ! StringHelper.isEmpty( manyToMany.mappedBy() ) ) {
+ if ( manyToMany != null && ! isEmpty( manyToMany.mappedBy() ) ) {
// We don't support @OrderColumn on the non-owning side of a many-to-many association.
return CollectionClassification.BAG;
}
OneToMany oneToMany = property.getAnnotation( OneToMany.class );
- if ( oneToMany != null && ! StringHelper.isEmpty( oneToMany.mappedBy() ) ) {
+ if ( oneToMany != null && ! isEmpty( oneToMany.mappedBy() ) ) {
// Unowned to-many mappings are always considered BAG by default
return CollectionClassification.BAG;
}
@@ -599,8 +588,12 @@ public abstract class CollectionBinder {
}
private static Class> determineSemanticJavaType(XProperty property) {
- final Class> returnedJavaType = property.getCollectionClass();
- if ( returnedJavaType == null ) {
+ @SuppressWarnings("rawtypes")
+ Class extends java.util.Collection> collectionClass = property.getCollectionClass();
+ if ( collectionClass != null ) {
+ return inferCollectionClassFromSubclass( collectionClass );
+ }
+ else {
throw new AnnotationException(
String.format(
Locale.ROOT,
@@ -610,8 +603,6 @@ public abstract class CollectionBinder {
)
);
}
-
- return inferCollectionClassFromSubclass( returnedJavaType );
}
private static Class> inferCollectionClassFromSubclass(Class> clazz) {
@@ -658,7 +649,7 @@ public abstract class CollectionBinder {
public void bind() {
this.collection = createCollection( propertyHolder.getPersistentClass() );
- String role = StringHelper.qualify( propertyHolder.getPath(), propertyName );
+ String role = qualify( propertyHolder.getPath(), propertyName );
LOG.debugf( "Collection role: %s", role );
collection.setRole( role );
collection.setMappedByProperty( mappedBy );
@@ -667,7 +658,7 @@ public abstract class CollectionBinder {
&& mapKeyPropertyName != null ) {
throw new AnnotationException(
"Cannot mix @jakarta.persistence.MapKey and @MapKeyColumn or @org.hibernate.annotations.MapKey "
- + "on the same collection: " + StringHelper.qualify(
+ + "on the same collection: " + qualify(
propertyHolder.getPath(), propertyName
)
);
@@ -700,54 +691,52 @@ public abstract class CollectionBinder {
final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector();
- //many to many may need some second pass information
- if ( !oneToMany && isMappedBy ) {
- metadataCollector.addMappedBy( getCollectionType().getName(), mappedBy, propertyName );
- }
//TODO reduce tableBinder != null and oneToMany
- XClass collectionType = getCollectionType();
- if ( inheritanceStatePerClass == null) {
- throw new AssertionFailure( "inheritanceStatePerClass not set" );
- }
- SecondPass sp = getSecondPass(
- fkJoinColumns,
- joinColumns,
- inverseJoinColumns,
- elementColumns,
- mapKeyColumns,
- mapKeyManyToManyColumns,
- isEmbedded,
- property,
- collectionType,
- notFoundAction,
- oneToMany,
- tableBinder,
- buildingContext
- );
- if ( collectionType.isAnnotationPresent( Embeddable.class )
- || property.isAnnotationPresent( ElementCollection.class ) //JPA 2
- ) {
- // do it right away, otherwise @ManyToOne on composite element call addSecondPass
- // and raise a ConcurrentModificationException
- //sp.doSecondPass( CollectionHelper.EMPTY_MAP );
- metadataCollector.addSecondPass( sp, !isMappedBy );
- }
- else {
- metadataCollector.addSecondPass( sp, !isMappedBy );
- }
+ scheduleSecondPass( isMappedBy, metadataCollector );
metadataCollector.addCollectionBinding( collection );
bindProperty();
}
+ private void scheduleSecondPass(boolean isMappedBy, InFlightMetadataCollector metadataCollector) {
+ //many to many may need some second pass information
+ if ( !oneToMany && isMappedBy ) {
+ metadataCollector.addMappedBy( getCollectionType().getName(), mappedBy, propertyName );
+ }
+
+ if ( inheritanceStatePerClass == null) {
+ throw new AssertionFailure( "inheritanceStatePerClass not set" );
+ }
+ metadataCollector.addSecondPass(
+ getSecondPass(
+ fkJoinColumns,
+ joinColumns,
+ inverseJoinColumns,
+ elementColumns,
+ mapKeyColumns,
+ mapKeyManyToManyColumns,
+ isEmbedded,
+ property,
+ getCollectionType(),
+ notFoundAction,
+ oneToMany,
+ tableBinder,
+ buildingContext
+ ),
+ !isMappedBy
+ );
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
private void bindCustomPersister() {
Persister persisterAnn = property.getAnnotation( Persister.class );
if ( persisterAnn != null ) {
- //noinspection unchecked
- Class extends CollectionPersister> persister =
- (Class extends CollectionPersister>) persisterAnn.impl();
- collection.setCollectionPersisterClass( persister );
+ Class clazz = persisterAnn.impl();
+ if ( !CollectionPersister.class.isAssignableFrom(clazz) ) {
+ throw new AnnotationException( "persister class does not implement CollectionPersister: " + clazz.getName() );
+ }
+ collection.setCollectionPersisterClass( clazz );
}
}
@@ -759,7 +748,7 @@ public abstract class CollectionBinder {
private void bindCache() {
//set cache
- if ( StringHelper.isNotEmpty( cacheConcurrencyStrategy ) ) {
+ if ( isNotEmpty( cacheConcurrencyStrategy ) ) {
collection.setCacheConcurrencyStrategy( cacheConcurrencyStrategy );
collection.setCacheRegionName( cacheRegionName );
}
@@ -787,7 +776,7 @@ public abstract class CollectionBinder {
|| property.isAnnotationPresent( JoinColumns.class )
|| propertyHolder.getJoinTable( property ) != null ) ) {
String message = "Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: ";
- message += StringHelper.qualify( propertyHolder.getPath(), propertyName );
+ message += qualify( propertyHolder.getPath(), propertyName );
throw new AnnotationException( message );
}
@@ -796,7 +785,7 @@ public abstract class CollectionBinder {
&& property.isAnnotationPresent( OnDelete.class )
&& !property.isAnnotationPresent( JoinColumn.class )) {
String message = "Unidirectional one-to-many associations annotated with @OnDelete must define @JoinColumn: ";
- message += StringHelper.qualify( propertyHolder.getPath(), propertyName );
+ message += qualify( propertyHolder.getPath(), propertyName );
throw new AnnotationException( message );
}
}
@@ -829,11 +818,8 @@ public abstract class CollectionBinder {
private void bindLoader() {
//SQL overriding
+
SQLInsert sqlInsert = property.getAnnotation( SQLInsert.class );
- SQLUpdate sqlUpdate = property.getAnnotation( SQLUpdate.class );
- SQLDelete sqlDelete = property.getAnnotation( SQLDelete.class );
- SQLDeleteAll sqlDeleteAll = property.getAnnotation( SQLDeleteAll.class );
- Loader loader = property.getAnnotation( Loader.class );
if ( sqlInsert != null ) {
collection.setCustomSQLInsert(
sqlInsert.sql().trim(),
@@ -842,6 +828,7 @@ public abstract class CollectionBinder {
);
}
+ SQLUpdate sqlUpdate = property.getAnnotation( SQLUpdate.class );
if ( sqlUpdate != null ) {
collection.setCustomSQLUpdate(
sqlUpdate.sql(),
@@ -849,6 +836,8 @@ public abstract class CollectionBinder {
fromExternalName( sqlUpdate.check().toString().toLowerCase(Locale.ROOT) )
);
}
+
+ SQLDelete sqlDelete = property.getAnnotation( SQLDelete.class );
if ( sqlDelete != null ) {
collection.setCustomSQLDelete(
sqlDelete.sql(),
@@ -856,6 +845,8 @@ public abstract class CollectionBinder {
fromExternalName( sqlDelete.check().toString().toLowerCase(Locale.ROOT) )
);
}
+
+ SQLDeleteAll sqlDeleteAll = property.getAnnotation( SQLDeleteAll.class );
if ( sqlDeleteAll != null ) {
collection.setCustomSQLDeleteAll(
sqlDeleteAll.sql(),
@@ -863,53 +854,50 @@ public abstract class CollectionBinder {
fromExternalName( sqlDeleteAll.check().toString().toLowerCase(Locale.ROOT) )
);
}
+
+ Loader loader = property.getAnnotation( Loader.class );
if ( loader != null ) {
collection.setLoaderName( loader.namedQuery() );
}
}
private void applySortingAndOrdering(Collection collection) {
- final boolean hadExplicitSort;
- final Class extends Comparator>> comparatorClass;
+ if ( naturalSort != null && comparatorSort != null ) {
+ throw buildIllegalSortCombination();
+ }
+ final boolean sorted = naturalSort != null || comparatorSort != null;
+ final Class extends Comparator>> comparatorClass;
if ( naturalSort != null ) {
- if ( comparatorSort != null ) {
- throw buildIllegalSortCombination();
- }
- hadExplicitSort = true;
comparatorClass = null;
}
else if ( comparatorSort != null ) {
- hadExplicitSort = true;
comparatorClass = comparatorSort.value();
}
else {
- hadExplicitSort = false;
comparatorClass = null;
}
- boolean hadOrderBy = false;
- if ( jpaOrderBy != null || sqlOrderBy != null ) {
- if ( jpaOrderBy != null && sqlOrderBy != null ) {
- throw buildIllegalOrderCombination();
- }
-
- hadOrderBy = true;
-
+ if ( jpaOrderBy != null && sqlOrderBy != null ) {
+ throw buildIllegalOrderCombination();
+ }
+ boolean ordered = jpaOrderBy != null || sqlOrderBy != null;
+ if ( ordered ) {
// we can only apply the sql-based order by up front. The jpa order by has to wait for second pass
if ( sqlOrderBy != null ) {
collection.setOrderBy( sqlOrderBy.clause() );
}
}
- final boolean isSorted = isSortedCollection || hadExplicitSort;
-
- if ( isSorted && hadOrderBy ) {
+ final boolean isSorted = isSortedCollection || sorted;
+ if ( isSorted && ordered ) {
throw buildIllegalOrderAndSortCombination();
}
-
collection.setSorted( isSorted );
+ instantiateComparator( collection, comparatorClass );
+ }
+ private void instantiateComparator(Collection collection, Class extends Comparator>> comparatorClass) {
if ( comparatorClass != null ) {
try {
collection.setComparator( comparatorClass.newInstance() );
@@ -964,42 +952,21 @@ public abstract class CollectionBinder {
}
private void defineFetchingStrategy() {
+ final FetchType jpaFetchType = getJpaFetchType();
+
LazyCollection lazy = property.getAnnotation( LazyCollection.class );
- Fetch fetch = property.getAnnotation( Fetch.class );
- OneToMany oneToMany = property.getAnnotation( OneToMany.class );
- ManyToMany manyToMany = property.getAnnotation( ManyToMany.class );
- ElementCollection elementCollection = property.getAnnotation( ElementCollection.class );
- ManyToAny manyToAny = property.getAnnotation( ManyToAny.class );
-
- FetchType fetchType;
- if ( oneToMany != null ) {
- fetchType = oneToMany.fetch();
- }
- else if ( manyToMany != null ) {
- fetchType = manyToMany.fetch();
- }
- else if ( elementCollection != null ) {
- fetchType = elementCollection.fetch();
- }
- else if ( manyToAny != null ) {
- fetchType = FetchType.LAZY;
- }
- else {
- throw new AssertionFailure(
- "Define fetch strategy on a property not annotated with @ManyToOne nor @OneToMany nor @CollectionOfElements"
- );
- }
-
if ( lazy != null ) {
- collection.setLazy( !( lazy.value() == LazyCollectionOption.FALSE ) );
+ collection.setLazy( lazy.value() != LazyCollectionOption.FALSE );
collection.setExtraLazy( lazy.value() == LazyCollectionOption.EXTRA );
}
else {
- collection.setLazy( fetchType == FetchType.LAZY );
+ collection.setLazy( jpaFetchType == FetchType.LAZY );
collection.setExtraLazy( false );
}
+ Fetch fetch = property.getAnnotation( Fetch.class );
if ( fetch != null ) {
+ // Hibernate @Fetch annotation takes precedence
if ( fetch.value() == org.hibernate.annotations.FetchMode.JOIN ) {
collection.setFetchMode( FetchMode.JOIN );
collection.setLazy( false );
@@ -1017,7 +984,31 @@ public abstract class CollectionBinder {
}
}
else {
- collection.setFetchMode( AnnotationBinder.getFetchMode( fetchType ) );
+ collection.setFetchMode( AnnotationBinder.getFetchMode( jpaFetchType ) );
+ }
+ }
+
+ private FetchType getJpaFetchType() {
+ OneToMany oneToMany = property.getAnnotation( OneToMany.class );
+ ManyToMany manyToMany = property.getAnnotation( ManyToMany.class );
+ ElementCollection elementCollection = property.getAnnotation( ElementCollection.class );
+ ManyToAny manyToAny = property.getAnnotation( ManyToAny.class );
+ if ( oneToMany != null ) {
+ return oneToMany.fetch();
+ }
+ else if ( manyToMany != null ) {
+ return manyToMany.fetch();
+ }
+ else if ( elementCollection != null ) {
+ return elementCollection.fetch();
+ }
+ else if ( manyToAny != null ) {
+ return FetchType.LAZY;
+ }
+ else {
+ throw new AssertionFailure(
+ "Define fetch strategy on a property not annotated with @ManyToOne nor @OneToMany nor @CollectionOfElements"
+ );
}
}
@@ -1090,7 +1081,7 @@ public abstract class CollectionBinder {
MetadataBuildingContext buildingContext) {
PersistentClass persistentClass = persistentClasses.get( collType.getName() );
boolean reversePropertyInJoin = false;
- if ( persistentClass != null && StringHelper.isNotEmpty( mappedBy ) ) {
+ if ( persistentClass != null && isNotEmpty( mappedBy ) ) {
try {
reversePropertyInJoin = 0 != persistentClass.getJoinNumber(
persistentClass.getRecursiveProperty( mappedBy )
@@ -1224,7 +1215,7 @@ public abstract class CollectionBinder {
private void handleJpaOrderBy(Collection collection, PersistentClass associatedClass) {
if ( jpaOrderBy != null ) {
final String orderByFragment = buildOrderByClauseFromHql( jpaOrderBy.value(), associatedClass );
- if ( StringHelper.isNotEmpty( orderByFragment ) ) {
+ if ( isNotEmpty( orderByFragment ) ) {
collection.setOrderBy( orderByFragment );
}
}
@@ -1307,7 +1298,7 @@ public abstract class CollectionBinder {
if ( whereOnCollection != null ) {
whereOnCollectionClause = whereOnCollection.clause();
}
- final String whereClause = StringHelper.getNonEmptyOrConjunctionIfBothNonEmpty(
+ final String whereClause = getNonEmptyOrConjunctionIfBothNonEmpty(
whereOnClassClause,
whereOnCollectionClause
);
@@ -1326,7 +1317,7 @@ public abstract class CollectionBinder {
WhereJoinTable whereJoinTable = property.getAnnotation( WhereJoinTable.class );
String whereJoinTableClause = whereJoinTable == null ? null : whereJoinTable.clause();
- if ( StringHelper.isNotEmpty( whereJoinTableClause ) ) {
+ if ( isNotEmpty( whereJoinTableClause ) ) {
if (hasAssociationTable) {
// This is a many-to-many association.
// Collection#setWhere is used to set the "where" clause that applies to the collection table
@@ -1336,7 +1327,7 @@ public abstract class CollectionBinder {
else {
throw new AnnotationException(
"Illegal use of @WhereJoinTable on an association without join table: "
- + StringHelper.qualify( propertyHolder.getPath(), propertyName )
+ + qualify( propertyHolder.getPath(), propertyName )
);
}
}
@@ -1345,13 +1336,13 @@ public abstract class CollectionBinder {
private void addFilter(boolean hasAssociationTable, FilterJoinTable filter) {
if ( hasAssociationTable ) {
final String condition;
- if ( StringHelper.isEmpty( filter.condition() ) ) {
+ if ( isEmpty( filter.condition() ) ) {
final FilterDefinition filterDefinition = buildingContext.getMetadataCollector()
.getFilterDefinition( filter.name() );
if ( filterDefinition == null ) {
throw new AnnotationException(
"@FilterJoinTable on an association without condition attribute and without an any @FilterDef with a default condition"
- + StringHelper.qualify( propertyHolder.getPath(), propertyName )
+ + qualify( propertyHolder.getPath(), propertyName )
);
}
condition = filterDefinition.getDefaultFilterCondition();
@@ -1370,7 +1361,7 @@ public abstract class CollectionBinder {
else {
throw new AnnotationException(
"Illegal use of @FilterJoinTable on an association without join table: "
- + StringHelper.qualify( propertyHolder.getPath(), propertyName )
+ + qualify( propertyHolder.getPath(), propertyName )
);
}
}
@@ -1385,10 +1376,10 @@ public abstract class CollectionBinder {
private String getCondition(String cond, String name) {
if ( isEmptyAnnotationValue( cond ) ) {
cond = buildingContext.getMetadataCollector().getFilterDefinition( name ).getDefaultFilterCondition();
- if ( StringHelper.isEmpty( cond ) ) {
+ if ( isEmpty( cond ) ) {
throw new AnnotationException(
"no filter condition found for filter " + name + " in "
- + StringHelper.qualify( propertyHolder.getPath(), propertyName )
+ + qualify( propertyHolder.getPath(), propertyName )
);
}
}
@@ -1480,7 +1471,7 @@ public abstract class CollectionBinder {
//give a chance to override the referenced property name
//has to do that here because the referencedProperty creation happens in a FKSecondPass for Many to one yuk!
- if ( joinColumns.length > 0 && StringHelper.isNotEmpty( joinColumns[0].getMappedBy() ) ) {
+ if ( joinColumns.length > 0 && isNotEmpty( joinColumns[0].getMappedBy() ) ) {
String entityName = joinColumns[0].getManyToManyOwnerSideEntityName() != null ?
"inverse__" + joinColumns[0].getManyToManyOwnerSideEntityName() :
joinColumns[0].getPropertyHolder().getEntityName();
@@ -1522,14 +1513,14 @@ public abstract class CollectionBinder {
key.disableForeignKey();
}
else {
- key.setForeignKeyName( StringHelper.nullIfEmpty( collectionTableAnn.foreignKey().name() ) );
- key.setForeignKeyDefinition( StringHelper.nullIfEmpty( collectionTableAnn.foreignKey().foreignKeyDefinition() ) );
+ key.setForeignKeyName( nullIfEmpty( collectionTableAnn.foreignKey().name() ) );
+ key.setForeignKeyDefinition( nullIfEmpty( collectionTableAnn.foreignKey().foreignKeyDefinition() ) );
if ( key.getForeignKeyName() == null &&
key.getForeignKeyDefinition() == null &&
collectionTableAnn.joinColumns().length == 1 ) {
JoinColumn joinColumn = collectionTableAnn.joinColumns()[0];
- key.setForeignKeyName( StringHelper.nullIfEmpty( joinColumn.foreignKey().name() ) );
- key.setForeignKeyDefinition( StringHelper.nullIfEmpty( joinColumn.foreignKey().foreignKeyDefinition() ) );
+ key.setForeignKeyName( nullIfEmpty( joinColumn.foreignKey().name() ) );
+ key.setForeignKeyDefinition( nullIfEmpty( joinColumn.foreignKey().foreignKeyDefinition() ) );
}
}
}
@@ -1554,21 +1545,21 @@ public abstract class CollectionBinder {
key.disableForeignKey();
}
else {
- key.setForeignKeyName( StringHelper.nullIfEmpty( foreignKeyName ) );
- key.setForeignKeyDefinition( StringHelper.nullIfEmpty( foreignKeyDefinition ) );
+ key.setForeignKeyName( nullIfEmpty( foreignKeyName ) );
+ key.setForeignKeyDefinition( nullIfEmpty( foreignKeyDefinition ) );
}
}
else {
final jakarta.persistence.ForeignKey fkOverride = propertyHolder.getOverriddenForeignKey(
- StringHelper.qualify( propertyHolder.getPath(), property.getName() )
+ qualify( propertyHolder.getPath(), property.getName() )
);
if ( fkOverride != null && ( fkOverride.value() == ConstraintMode.NO_CONSTRAINT ||
fkOverride.value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) {
key.disableForeignKey();
}
else if ( fkOverride != null ) {
- key.setForeignKeyName( StringHelper.nullIfEmpty( fkOverride.name() ) );
- key.setForeignKeyDefinition( StringHelper.nullIfEmpty( fkOverride.foreignKeyDefinition() ) );
+ key.setForeignKeyName( nullIfEmpty( fkOverride.name() ) );
+ key.setForeignKeyDefinition( nullIfEmpty( fkOverride.foreignKeyDefinition() ) );
}
else {
final OneToMany oneToManyAnn = property.getAnnotation( OneToMany.class );
@@ -1587,8 +1578,8 @@ public abstract class CollectionBinder {
key.disableForeignKey();
}
else {
- key.setForeignKeyName( StringHelper.nullIfEmpty( joinColumnAnn.foreignKey().name() ) );
- key.setForeignKeyDefinition( StringHelper.nullIfEmpty( joinColumnAnn.foreignKey().foreignKeyDefinition() ) );
+ key.setForeignKeyName( nullIfEmpty( joinColumnAnn.foreignKey().name() ) );
+ key.setForeignKeyDefinition( nullIfEmpty( joinColumnAnn.foreignKey().foreignKeyDefinition() ) );
}
}
}
@@ -1720,7 +1711,7 @@ public abstract class CollectionBinder {
AnnotatedClassType classType;
CollectionPropertyHolder holder;
- if ( BinderHelper.PRIMITIVE_NAMES.contains( collType.getName() ) ) {
+ if ( PRIMITIVE_NAMES.contains( collType.getName() ) ) {
classType = AnnotatedClassType.NONE;
elementClass = null;
@@ -1815,7 +1806,7 @@ public abstract class CollectionBinder {
collValue.setElement( component );
- if ( StringHelper.isNotEmpty(hqlOrderBy) ) {
+ if ( isNotEmpty(hqlOrderBy) ) {
String orderBy = adjustUserSuppliedValueCollectionOrderingFragment(hqlOrderBy);
if ( orderBy != null ) {
collValue.setOrderBy( orderBy );
@@ -1909,8 +1900,8 @@ public abstract class CollectionBinder {
element.disableForeignKey();
}
else {
- element.setForeignKeyName( StringHelper.nullIfEmpty( foreignKeyName ) );
- element.setForeignKeyDefinition( StringHelper.nullIfEmpty( foreignKeyDefinition ) );
+ element.setForeignKeyName( nullIfEmpty( foreignKeyName ) );
+ element.setForeignKeyDefinition( nullIfEmpty( foreignKeyDefinition ) );
}
}
}
@@ -1937,7 +1928,7 @@ public abstract class CollectionBinder {
}
ManyToAny anyAnn = property.getAnnotation( ManyToAny.class );
- final Any any = BinderHelper.buildAnyValue(
+ final Any any = buildAnyValue(
discriminatorColumnAnn,
discriminatorFormulaAnn,
inverseJoinColumns,
@@ -1998,13 +1989,14 @@ public abstract class CollectionBinder {
// String header = ( mappedByProperty == null ) ? mappings.getLogicalTableName( ownerTable ) : mappedByProperty;
// column.setDefaultColumnHeader( header );
}
- if ( StringHelper.isEmpty( associationTableBinder.getName() ) ) {
+ if ( isEmpty( associationTableBinder.getName() ) ) {
//default value
+ PersistentClass owner = collValue.getOwner();
associationTableBinder.setDefaultName(
- collValue.getOwner().getClassName(),
- collValue.getOwner().getEntityName(),
- collValue.getOwner().getJpaEntityName(),
- buildingContext.getMetadataCollector().getLogicalTableName( collValue.getOwner().getTable() ),
+ owner.getClassName(),
+ owner.getEntityName(),
+ owner.getJpaEntityName(),
+ buildingContext.getMetadataCollector().getLogicalTableName( owner.getTable() ),
collectionEntity != null ? collectionEntity.getClassName() : null,
collectionEntity != null ? collectionEntity.getEntityName() : null,
collectionEntity != null ? collectionEntity.getJpaEntityName() : null,
@@ -2047,15 +2039,11 @@ public abstract class CollectionBinder {
+ collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName()
);
}
- Table table;
- if ( otherSideProperty.getValue() instanceof Collection ) {
- //this is a collection on the other side
- table = ( (Collection) otherSideProperty.getValue() ).getCollectionTable();
- }
- else {
- //This is a ToOne with a @JoinTable or a regular property
- table = otherSideProperty.getValue().getTable();
- }
+ Table table = otherSideProperty.getValue() instanceof Collection
+ ? ((Collection) otherSideProperty.getValue()).getCollectionTable()
+ : otherSideProperty.getValue().getTable();
+ //this is a collection on the other side
+ //This is a ToOne with a @JoinTable or a regular property
collValue.setCollectionTable( table );
String entityName = collectionEntity.getEntityName();
for (AnnotatedJoinColumn column : joinColumns) {
@@ -2128,12 +2116,14 @@ public abstract class CollectionBinder {
XProperty property,
XClass propertyClass,
MetadataBuildingContext context) {
- final org.hibernate.annotations.EmbeddableInstantiator propertyAnnotation = property.getAnnotation( org.hibernate.annotations.EmbeddableInstantiator.class );
+ final org.hibernate.annotations.EmbeddableInstantiator propertyAnnotation
+ = property.getAnnotation( org.hibernate.annotations.EmbeddableInstantiator.class );
if ( propertyAnnotation != null ) {
return propertyAnnotation.value();
}
- final org.hibernate.annotations.EmbeddableInstantiator classAnnotation = propertyClass.getAnnotation( org.hibernate.annotations.EmbeddableInstantiator.class );
+ final org.hibernate.annotations.EmbeddableInstantiator classAnnotation
+ = propertyClass.getAnnotation( org.hibernate.annotations.EmbeddableInstantiator.class );
if ( classAnnotation != null ) {
return classAnnotation.value();
}
@@ -2176,7 +2166,7 @@ public abstract class CollectionBinder {
private static void checkFilterConditions(Collection collValue) {
//for now it can't happen, but sometime soon...
- if ( ( collValue.getFilters().size() != 0 || StringHelper.isNotEmpty( collValue.getWhere() ) ) &&
+ if ( ( collValue.getFilters().size() != 0 || isNotEmpty( collValue.getWhere() ) ) &&
collValue.getFetchMode() == FetchMode.JOIN &&
!( collValue.getElement() instanceof SimpleValue ) && //SimpleValue (CollectionOfElements) are always SELECT but it does not matter
collValue.getElement().getFetchMode() != FetchMode.JOIN ) {
@@ -2196,7 +2186,7 @@ public abstract class CollectionBinder {
PropertyHolder propertyHolder,
MetadataBuildingContext buildingContext) {
try {
- BinderHelper.createSyntheticPropertyReference(
+ createSyntheticPropertyReference(
joinColumns,
collValue.getOwner(),
collectionEntity,
@@ -2239,7 +2229,7 @@ public abstract class CollectionBinder {
boolean unique,
MetadataBuildingContext buildingContext) {
final String mappedBy = columns[0].getMappedBy();
- if ( StringHelper.isNotEmpty( mappedBy ) ) {
+ if ( isNotEmpty( mappedBy ) ) {
final Property property = referencedEntity.getRecursiveProperty( mappedBy );
List mappedByColumns;
if ( property.getValue() instanceof Collection ) {
@@ -2279,7 +2269,7 @@ public abstract class CollectionBinder {
value.createForeignKey();
}
else {
- BinderHelper.createSyntheticPropertyReference( columns, referencedEntity, null, value, true, buildingContext );
+ createSyntheticPropertyReference( columns, referencedEntity, null, value, true, buildingContext );
if ( notFoundAction == NotFoundAction.IGNORE ) {
value.disableForeignKey();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
index 71d9d16b72..db03f9e89c 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
@@ -69,16 +69,13 @@ import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.cfg.AccessType;
import org.hibernate.cfg.AnnotationBinder;
-import org.hibernate.cfg.BinderHelper;
import org.hibernate.cfg.AnnotatedJoinColumn;
import org.hibernate.cfg.PropertyHolder;
import org.hibernate.cfg.UniqueConstraintHolder;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
-import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.CoreMessageLogger;
-import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.PersistentClass;
@@ -92,8 +89,15 @@ import org.hibernate.mapping.Value;
import org.hibernate.persister.entity.EntityPersister;
import org.jboss.logging.Logger;
+import static org.hibernate.cfg.AnnotatedJoinColumn.buildJoinColumn;
+import static org.hibernate.cfg.BinderHelper.isEmptyAnnotationValue;
import static org.hibernate.cfg.BinderHelper.toAliasEntityMap;
import static org.hibernate.cfg.BinderHelper.toAliasTableMap;
+import static org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle.fromExternalName;
+import static org.hibernate.internal.util.StringHelper.isEmpty;
+import static org.hibernate.internal.util.StringHelper.isNotEmpty;
+import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
+import static org.hibernate.internal.util.StringHelper.unqualify;
/**
@@ -159,7 +163,7 @@ public class EntityBinder {
this.context = context;
this.persistentClass = persistentClass;
this.annotatedClass = annotatedClass;
- bindEntityAnnotation( annotatedClass.getAnnotation( Entity.class ) );
+ bindEntityAnnotation();
bindHibernateAnnotation();
}
@@ -174,54 +178,28 @@ public class EntityBinder {
public boolean isPropertyDefinedInSuperHierarchy(String name) {
// Yes, yes... persistentClass can be null because EntityBinder can be used
// to bind components as well, of course...
- return persistentClass != null && persistentClass.isPropertyDefinedInSuperHierarchy( name );
+ return persistentClass != null && persistentClass.isPropertyDefinedInSuperHierarchy( name );
}
- @SuppressWarnings("SimplifiableConditionalExpression")
private void bindHibernateAnnotation() {
- {
- final DynamicInsert dynamicInsertAnn = annotatedClass.getAnnotation( DynamicInsert.class );
- this.dynamicInsert = dynamicInsertAnn == null
- ? false
- : dynamicInsertAnn.value();
- }
-
- {
- final DynamicUpdate dynamicUpdateAnn = annotatedClass.getAnnotation( DynamicUpdate.class );
- this.dynamicUpdate = dynamicUpdateAnn == null
- ? false
- : dynamicUpdateAnn.value();
- }
-
- {
- final SelectBeforeUpdate selectBeforeUpdateAnn = annotatedClass.getAnnotation( SelectBeforeUpdate.class );
- this.selectBeforeUpdate = selectBeforeUpdateAnn == null
- ? false
- : selectBeforeUpdateAnn.value();
- }
-
- {
- final OptimisticLocking optimisticLockingAnn = annotatedClass.getAnnotation( OptimisticLocking.class );
- this.optimisticLockType = optimisticLockingAnn == null
- ? OptimisticLockType.VERSION
- : optimisticLockingAnn.type();
- }
-
- {
- final Polymorphism polymorphismAnn = annotatedClass.getAnnotation( Polymorphism.class );
- this.polymorphismType = polymorphismAnn == null
- ? PolymorphismType.IMPLICIT
- : polymorphismAnn.type();
- }
+ final DynamicInsert dynamicInsertAnn = annotatedClass.getAnnotation( DynamicInsert.class );
+ dynamicInsert = dynamicInsertAnn != null && dynamicInsertAnn.value();
+ final DynamicUpdate dynamicUpdateAnn = annotatedClass.getAnnotation( DynamicUpdate.class );
+ dynamicUpdate = dynamicUpdateAnn != null && dynamicUpdateAnn.value();
+ final SelectBeforeUpdate selectBeforeUpdateAnn = annotatedClass.getAnnotation( SelectBeforeUpdate.class );
+ selectBeforeUpdate = selectBeforeUpdateAnn != null && selectBeforeUpdateAnn.value();
+ final OptimisticLocking optimisticLockingAnn = annotatedClass.getAnnotation( OptimisticLocking.class );
+ optimisticLockType = optimisticLockingAnn == null ? OptimisticLockType.VERSION : optimisticLockingAnn.type();
+ final Polymorphism polymorphismAnn = annotatedClass.getAnnotation( Polymorphism.class );
+ polymorphismType = polymorphismAnn == null ? PolymorphismType.IMPLICIT : polymorphismAnn.type();
}
- private void bindEntityAnnotation(Entity ejb3Ann) {
- if ( ejb3Ann == null ) {
+ private void bindEntityAnnotation() {
+ Entity entity = annotatedClass.getAnnotation( Entity.class );
+ if ( entity == null ) {
throw new AssertionFailure( "@Entity should never be missing" );
}
- name = BinderHelper.isEmptyAnnotationValue( ejb3Ann.name() )
- ? StringHelper.unqualify(annotatedClass.getName())
- : ejb3Ann.name();
+ name = isEmptyAnnotationValue( entity.name() ) ? unqualify( annotatedClass.getName() ) : entity.name();
}
public boolean isRootEntity() {
@@ -258,12 +236,12 @@ public class EntityBinder {
if ( persistentClass instanceof RootClass ) {
RootClass rootClass = (RootClass) persistentClass;
- boolean mutable = !annotatedClass.isAnnotationPresent( Immutable.class );
+ boolean mutable = !annotatedClass.isAnnotationPresent( Immutable.class );
rootClass.setMutable( mutable );
rootClass.setExplicitPolymorphism( isExplicitPolymorphism( polymorphismType ) );
- if ( StringHelper.isNotEmpty( where ) ) {
+ if ( isNotEmpty( where ) ) {
rootClass.setWhere( where );
}
@@ -286,8 +264,8 @@ public class EntityBinder {
}
}
else {
- if (annotatedClass.isAnnotationPresent(Immutable.class)) {
- LOG.immutableAnnotationOnNonRoot(annotatedClass.getName());
+ if ( annotatedClass.isAnnotationPresent(Immutable.class) ) {
+ LOG.immutableAnnotationOnNonRoot( annotatedClass.getName() );
}
}
@@ -296,83 +274,14 @@ public class EntityBinder {
persistentClass.setOptimisticLockStyle( getVersioning( optimisticLockType ) );
persistentClass.setSelectBeforeUpdate( selectBeforeUpdate );
- //set persister if needed
- Persister persisterAnn = annotatedClass.getAnnotation( Persister.class );
- if ( persisterAnn != null ) {
- //TODO: throw an error if the class doesn't inherit EntityPersister
- Class extends EntityPersister> persister = (Class extends EntityPersister>) persisterAnn.impl();
- persistentClass.setEntityPersisterClass( persister );
- }
+ bindCustomPersister();
persistentClass.setBatchSize( batchSize );
- //SQL overriding
- SQLInsert sqlInsert = annotatedClass.getAnnotation( SQLInsert.class );
- SQLUpdate sqlUpdate = annotatedClass.getAnnotation( SQLUpdate.class );
- SQLDelete sqlDelete = annotatedClass.getAnnotation( SQLDelete.class );
- SQLDeleteAll sqlDeleteAll = annotatedClass.getAnnotation( SQLDeleteAll.class );
- Loader loader = annotatedClass.getAnnotation( Loader.class );
+ bindCustomSql();
+ bindSynchronize();
+ bindhandleFilters();
- if ( sqlInsert != null ) {
- persistentClass.setCustomSQLInsert( sqlInsert.sql().trim(), sqlInsert.callable(),
- ExecuteUpdateResultCheckStyle.fromExternalName( sqlInsert.check().toString().toLowerCase(Locale.ROOT) )
- );
-
- }
- if ( sqlUpdate != null ) {
- persistentClass.setCustomSQLUpdate( sqlUpdate.sql(), sqlUpdate.callable(),
- ExecuteUpdateResultCheckStyle.fromExternalName( sqlUpdate.check().toString().toLowerCase(Locale.ROOT) )
- );
- }
- if ( sqlDelete != null ) {
- persistentClass.setCustomSQLDelete( sqlDelete.sql(), sqlDelete.callable(),
- ExecuteUpdateResultCheckStyle.fromExternalName( sqlDelete.check().toString().toLowerCase(Locale.ROOT) )
- );
- }
- if ( sqlDeleteAll != null ) {
- persistentClass.setCustomSQLDelete( sqlDeleteAll.sql(), sqlDeleteAll.callable(),
- ExecuteUpdateResultCheckStyle.fromExternalName( sqlDeleteAll.check().toString().toLowerCase(Locale.ROOT) )
- );
- }
- if ( loader != null ) {
- persistentClass.setLoaderName( loader.namedQuery() );
- }
-
- final JdbcEnvironment jdbcEnvironment = context.getMetadataCollector().getDatabase().getJdbcEnvironment();
- if ( annotatedClass.isAnnotationPresent( Synchronize.class )) {
- Synchronize synchronizedWith = annotatedClass.getAnnotation(Synchronize.class);
-
- String [] tables = synchronizedWith.value();
- for (String table : tables) {
- persistentClass.addSynchronizedTable(
- context.getBuildingOptions().getPhysicalNamingStrategy().toPhysicalTableName(
- jdbcEnvironment.getIdentifierHelper().toIdentifier( table ),
- jdbcEnvironment
- ).render( jdbcEnvironment.getDialect() )
- );
- }
- }
-
- if ( annotatedClass.isAnnotationPresent(Subselect.class )) {
- Subselect subselect = annotatedClass.getAnnotation(Subselect.class);
- this.subselect = subselect.value();
- }
-
- for ( Filter filter : filters ) {
- String filterName = filter.name();
- String cond = filter.condition();
- if ( BinderHelper.isEmptyAnnotationValue( cond ) ) {
- FilterDefinition definition = context.getMetadataCollector().getFilterDefinition( filterName );
- cond = definition == null ? null : definition.getDefaultFilterCondition();
- if ( StringHelper.isEmpty( cond ) ) {
- throw new AnnotationException(
- "no filter condition found for filter " + filterName + " in " + this.name
- );
- }
- }
- persistentClass.addFilter(filterName, cond, filter.deduceAliasInjectionPoints(),
- toAliasTableMap(filter.aliases()), toAliasEntityMap(filter.aliases()));
- }
LOG.debugf( "Import with entity name %s", name );
try {
context.getMetadataCollector().addImport( name, persistentClass.getEntityName() );
@@ -388,6 +297,105 @@ public class EntityBinder {
processNamedEntityGraphs();
}
+ private void bindCustomSql() {
+ //SQL overriding
+ SQLInsert sqlInsert = annotatedClass.getAnnotation( SQLInsert.class );
+ if ( sqlInsert != null ) {
+ persistentClass.setCustomSQLInsert(
+ sqlInsert.sql().trim(),
+ sqlInsert.callable(),
+ fromExternalName( sqlInsert.check().toString().toLowerCase(Locale.ROOT) )
+ );
+
+ }
+
+ SQLUpdate sqlUpdate = annotatedClass.getAnnotation( SQLUpdate.class );
+ if ( sqlUpdate != null ) {
+ persistentClass.setCustomSQLUpdate(
+ sqlUpdate.sql().trim(),
+ sqlUpdate.callable(),
+ fromExternalName( sqlUpdate.check().toString().toLowerCase(Locale.ROOT) )
+ );
+ }
+
+ SQLDelete sqlDelete = annotatedClass.getAnnotation( SQLDelete.class );
+ if ( sqlDelete != null ) {
+ persistentClass.setCustomSQLDelete(
+ sqlDelete.sql().trim(),
+ sqlDelete.callable(),
+ fromExternalName( sqlDelete.check().toString().toLowerCase(Locale.ROOT) )
+ );
+ }
+
+ SQLDeleteAll sqlDeleteAll = annotatedClass.getAnnotation( SQLDeleteAll.class );
+ if ( sqlDeleteAll != null ) {
+ persistentClass.setCustomSQLDelete(
+ sqlDeleteAll.sql().trim(),
+ sqlDeleteAll.callable(),
+ fromExternalName( sqlDeleteAll.check().toString().toLowerCase(Locale.ROOT) )
+ );
+ }
+
+ Loader loader = annotatedClass.getAnnotation( Loader.class );
+ if ( loader != null ) {
+ persistentClass.setLoaderName( loader.namedQuery() );
+ }
+
+ Subselect subselect = annotatedClass.getAnnotation( Subselect.class );
+ if ( subselect != null ) {
+ this.subselect = subselect.value();
+ }
+ }
+
+ private void bindhandleFilters() {
+ for ( Filter filter : filters ) {
+ final String filterName = filter.name();
+ String condition = filter.condition();
+ if ( isEmptyAnnotationValue( condition ) ) {
+ final FilterDefinition definition = context.getMetadataCollector().getFilterDefinition( filterName );
+ condition = definition == null ? null : definition.getDefaultFilterCondition();
+ if ( isEmpty( condition ) ) {
+ throw new AnnotationException( "no filter condition found for filter "
+ + filterName + " in " + this.name );
+ }
+ }
+ persistentClass.addFilter(
+ filterName,
+ condition,
+ filter.deduceAliasInjectionPoints(),
+ toAliasTableMap( filter.aliases() ),
+ toAliasEntityMap( filter.aliases() )
+ );
+ }
+ }
+
+ private void bindSynchronize() {
+ if ( annotatedClass.isAnnotationPresent( Synchronize.class ) ) {
+ final JdbcEnvironment jdbcEnvironment = context.getMetadataCollector().getDatabase().getJdbcEnvironment();
+ for ( String table : annotatedClass.getAnnotation(Synchronize.class).value() ) {
+ persistentClass.addSynchronizedTable(
+ context.getBuildingOptions().getPhysicalNamingStrategy().toPhysicalTableName(
+ jdbcEnvironment.getIdentifierHelper().toIdentifier( table ),
+ jdbcEnvironment
+ ).render( jdbcEnvironment.getDialect() )
+ );
+ }
+ }
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ private void bindCustomPersister() {
+ //set persister if needed
+ Persister persisterAnn = annotatedClass.getAnnotation( Persister.class );
+ if ( persisterAnn != null ) {
+ Class clazz = persisterAnn.impl();
+ if ( !EntityPersister.class.isAssignableFrom(clazz) ) {
+ throw new AnnotationException( "persister class does not implement EntityPersister: " + clazz.getName() );
+ }
+ persistentClass.setEntityPersisterClass( clazz );
+ }
+ }
+
public PersistentClass getPersistentClass() {
return persistentClass;
}
@@ -412,7 +420,7 @@ public class EntityBinder {
}
public void bindDiscriminatorValue() {
- if ( StringHelper.isEmpty( discriminatorValue ) ) {
+ if ( isEmpty( discriminatorValue ) ) {
Value discriminator = persistentClass.getDiscriminator();
if ( discriminator == null ) {
persistentClass.setDiscriminatorValue( name );
@@ -506,122 +514,19 @@ public class EntityBinder {
XClass clazzToProcess,
SharedCacheMode sharedCacheMode,
MetadataBuildingContext context) {
+ bindCache( clazzToProcess, sharedCacheMode, context );
+ bindNaturalIdCache( clazzToProcess );
+ }
- final Cache explicitCacheAnn = clazzToProcess.getAnnotation( Cache.class );
- final Cacheable explicitCacheableAnn = clazzToProcess.getAnnotation( Cacheable.class );
-
- isCached = false;
- cacheConcurrentStrategy = null;
- cacheRegion = null;
- cacheLazyProperty = true;
-
- if ( persistentClass instanceof RootClass ) {
- Cache effectiveCacheAnn = explicitCacheAnn;
-
- if ( explicitCacheAnn != null ) {
- // preserve legacy behavior of circumventing SharedCacheMode when Hibernate's @Cache is used.
- isCached = true;
- }
- else {
- effectiveCacheAnn = buildCacheMock( clazzToProcess.getName(), context );
-
- switch ( sharedCacheMode ) {
- case ALL: {
- // all entities should be cached
- isCached = true;
- break;
- }
- case ENABLE_SELECTIVE: {
- if ( explicitCacheableAnn != null && explicitCacheableAnn.value() ) {
- isCached = true;
- }
- break;
- }
- case DISABLE_SELECTIVE: {
- if ( explicitCacheableAnn == null || explicitCacheableAnn.value() ) {
- isCached = true;
- }
- break;
- }
- default: {
- // treat both NONE and UNSPECIFIED the same
- isCached = false;
- break;
- }
- }
- }
-
- cacheConcurrentStrategy = resolveCacheConcurrencyStrategy( effectiveCacheAnn.usage() );
- cacheRegion = effectiveCacheAnn.region();
- switch ( effectiveCacheAnn.include().toLowerCase( Locale.ROOT ) ) {
- case "all": {
- cacheLazyProperty = true;
- break;
- }
- case "non-lazy": {
- cacheLazyProperty = false;
- break;
- }
- default: {
- throw new AnnotationException(
- "Unknown @Cache.include value [" + effectiveCacheAnn.include() + "] : "
- + annotatedClass.getName()
- );
- }
- }
- }
- else {
- if ( explicitCacheAnn != null ) {
- LOG.cacheOrCacheableAnnotationOnNonRoot(
- persistentClass.getClassName() == null
- ? annotatedClass.getName()
- : persistentClass.getClassName()
- );
- }
- else if ( explicitCacheableAnn == null && persistentClass.getSuperclass() != null ) {
- // we should inherit our super's caching config
- isCached = persistentClass.getSuperclass().isCached();
- }
- else {
- switch ( sharedCacheMode ) {
- case ALL: {
- // all entities should be cached
- isCached = true;
- break;
- }
- case ENABLE_SELECTIVE: {
- // only entities with @Cacheable(true) should be cached
- if ( explicitCacheableAnn != null && explicitCacheableAnn.value() ) {
- isCached = true;
- }
- break;
- }
- case DISABLE_SELECTIVE: {
- if ( explicitCacheableAnn == null || !explicitCacheableAnn.value() ) {
- isCached = true;
- }
- break;
- }
- default: {
- // treat both NONE and UNSPECIFIED the same
- isCached = false;
- break;
- }
- }
- }
- }
-
+ private void bindNaturalIdCache(XClass clazzToProcess) {
naturalIdCacheRegion = null;
-
final NaturalIdCache naturalIdCacheAnn = clazzToProcess.getAnnotation( NaturalIdCache.class );
if ( naturalIdCacheAnn != null ) {
- if ( BinderHelper.isEmptyAnnotationValue( naturalIdCacheAnn.region() ) ) {
- if ( explicitCacheAnn != null && StringHelper.isNotEmpty( explicitCacheAnn.region() ) ) {
- naturalIdCacheRegion = explicitCacheAnn.region() + NATURAL_ID_CACHE_SUFFIX;
- }
- else {
- naturalIdCacheRegion = clazzToProcess.getName() + NATURAL_ID_CACHE_SUFFIX;
- }
+ if ( isEmptyAnnotationValue( naturalIdCacheAnn.region() ) ) {
+ final Cache explicitCacheAnn = clazzToProcess.getAnnotation( Cache.class );
+ naturalIdCacheRegion = explicitCacheAnn != null && isNotEmpty( explicitCacheAnn.region() )
+ ? explicitCacheAnn.region() + NATURAL_ID_CACHE_SUFFIX
+ : clazzToProcess.getName() + NATURAL_ID_CACHE_SUFFIX;
}
else {
naturalIdCacheRegion = naturalIdCacheAnn.region();
@@ -629,6 +534,86 @@ public class EntityBinder {
}
}
+ private void bindCache(XClass clazzToProcess, SharedCacheMode sharedCacheMode, MetadataBuildingContext context) {
+ isCached = false;
+ cacheConcurrentStrategy = null;
+ cacheRegion = null;
+ cacheLazyProperty = true;
+ if ( persistentClass instanceof RootClass ) {
+ bindRootClassCache( clazzToProcess, sharedCacheMode, context );
+ }
+ else {
+ bindSubclassCache( clazzToProcess, sharedCacheMode );
+ }
+ }
+
+ private void bindSubclassCache(XClass clazzToProcess, SharedCacheMode sharedCacheMode) {
+ final Cache cache = clazzToProcess.getAnnotation( Cache.class );
+ final Cacheable cacheable = clazzToProcess.getAnnotation( Cacheable.class );
+ if ( cache != null ) {
+ LOG.cacheOrCacheableAnnotationOnNonRoot(
+ persistentClass.getClassName() == null
+ ? annotatedClass.getName()
+ : persistentClass.getClassName()
+ );
+ }
+ else if ( cacheable == null && persistentClass.getSuperclass() != null ) {
+ // we should inherit our super's caching config
+ isCached = persistentClass.getSuperclass().isCached();
+ }
+ else {
+ isCached = isCacheable( sharedCacheMode, cacheable );
+ }
+ }
+
+ private void bindRootClassCache(XClass clazzToProcess, SharedCacheMode sharedCacheMode, MetadataBuildingContext context) {
+ final Cache cache = clazzToProcess.getAnnotation( Cache.class );
+ final Cacheable cacheable = clazzToProcess.getAnnotation( Cacheable.class );
+ final Cache effectiveCache;
+ if ( cache != null ) {
+ // preserve legacy behavior of circumventing SharedCacheMode when Hibernate's @Cache is used.
+ isCached = true;
+ effectiveCache = cache;
+ }
+ else {
+ effectiveCache = buildCacheMock( clazzToProcess.getName(), context );
+ isCached = isCacheable( sharedCacheMode, cacheable );
+ }
+ cacheConcurrentStrategy = resolveCacheConcurrencyStrategy( effectiveCache.usage() );
+ cacheRegion = effectiveCache.region();
+ cacheLazyProperty = isCacheLazy( effectiveCache, annotatedClass );
+ }
+
+ private static boolean isCacheLazy(Cache effectiveCache, XClass annotatedClass) {
+ switch ( effectiveCache.include().toLowerCase( Locale.ROOT ) ) {
+ case "all":
+ return true;
+ case "non-lazy":
+ return false;
+ default:
+ throw new AnnotationException( "Unknown @Cache.include value [" + effectiveCache.include() + "] : "
+ + annotatedClass.getName()
+ );
+ }
+ }
+
+ private static boolean isCacheable(SharedCacheMode sharedCacheMode, Cacheable explicitCacheableAnn) {
+ switch (sharedCacheMode) {
+ case ALL:
+ // all entities should be cached
+ return true;
+ case ENABLE_SELECTIVE:
+ // only entities with @Cacheable(true) should be cached
+ return explicitCacheableAnn != null && explicitCacheableAnn.value();
+ case DISABLE_SELECTIVE:
+ // only entities with @Cacheable(false) should not be cached
+ return explicitCacheableAnn == null || explicitCacheableAnn.value();
+ default:
+ // treat both NONE and UNSPECIFIED the same
+ return false;
+ }
+ }
+
private static String resolveCacheConcurrencyStrategy(CacheConcurrencyStrategy strategy) {
final org.hibernate.cache.spi.access.AccessType accessType = strategy.toAccessType();
return accessType == null ? null : accessType.getExternalName();
@@ -638,7 +623,7 @@ public class EntityBinder {
return new LocalCacheAnnotationStub( region, determineCacheConcurrencyStrategy( context ) );
}
- @SuppressWarnings({ "ClassExplicitlyAnnotation" })
+ @SuppressWarnings("ClassExplicitlyAnnotation")
private static class LocalCacheAnnotationStub implements Cache {
private final String region;
private final CacheConcurrencyStrategy usage;
@@ -666,9 +651,7 @@ public class EntityBinder {
}
private static CacheConcurrencyStrategy determineCacheConcurrencyStrategy(MetadataBuildingContext context) {
- return CacheConcurrencyStrategy.fromAccessType(
- context.getBuildingOptions().getImplicitCacheAccessType()
- );
+ return CacheConcurrencyStrategy.fromAccessType( context.getBuildingOptions().getImplicitCacheAccessType() );
}
private static class EntityTableNamingStrategyHelper implements NamingStrategyHelper {
@@ -745,9 +728,7 @@ public class EntityBinder {
context.getMetadataCollector().addEntityTableXref(
persistentClass.getEntityName(),
context.getMetadataCollector().getDatabase().toIdentifier(
- context.getMetadataCollector().getLogicalTableName(
- superTableXref.getPrimaryTable()
- )
+ context.getMetadataCollector().getLogicalTableName( superTableXref.getPrimaryTable() )
),
superTableXref.getPrimaryTable(),
superTableXref
@@ -761,19 +742,15 @@ public class EntityBinder {
List uniqueConstraints,
String constraints,
InFlightMetadataCollector.EntityTableXref denormalizedSuperTableXref) {
- EntityTableNamingStrategyHelper namingStrategyHelper = new EntityTableNamingStrategyHelper(
+
+ final EntityTableNamingStrategyHelper namingStrategyHelper = new EntityTableNamingStrategyHelper(
persistentClass.getClassName(),
persistentClass.getEntityName(),
name
);
-
- final Identifier logicalName;
- if ( StringHelper.isNotEmpty( tableName ) ) {
- logicalName = namingStrategyHelper.handleExplicitName( tableName, context );
- }
- else {
- logicalName = namingStrategyHelper.determineImplicitName( context );
- }
+ final Identifier logicalName = isNotEmpty( tableName )
+ ? namingStrategyHelper.handleExplicitName( tableName, context )
+ : namingStrategyHelper.determineImplicitName( context );
final Table table = TableBinder.buildAndFillTable(
schema,
@@ -784,14 +761,13 @@ public class EntityBinder {
null,
constraints,
context,
- this.subselect,
+ subselect,
denormalizedSuperTableXref
);
final RowId rowId = annotatedClass.getAnnotation( RowId.class );
if ( rowId != null ) {
table.setRowId( rowId.value() );
}
-
final Comment comment = annotatedClass.getAnnotation( Comment.class );
if ( comment != null ) {
table.setComment( comment.value() );
@@ -814,104 +790,82 @@ public class EntityBinder {
}
public void finalSecondaryTableBinding(PropertyHolder propertyHolder) {
- /*
- * Those operations has to be done after the id definition of the persistence class.
- * ie after the properties parsing
- */
+ // This operation has to be done after the id definition of the persistence class.
+ // ie after the properties parsing
Iterator