diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java index 57b5e0bedb..78631bd16a 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java @@ -99,7 +99,7 @@ class DatabaseSnapshotExecutor { final List domainResults = new ArrayList<>(); entityDescriptor.getIdentifierMapping().visitColumns( - (tab, col, jdbcMapping) -> { + (tab, col, isColFormula, jdbcMapping) -> { final TableReference tableReference = rootTableGroup.resolveTableReference( tab ); final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping ); @@ -111,6 +111,7 @@ class DatabaseSnapshotExecutor { s -> new ColumnReference( tableReference, col, + isColFormula, jdbcMapping, sessionFactory ) @@ -145,7 +146,7 @@ class DatabaseSnapshotExecutor { contributorMapping -> { rootPath.append( contributorMapping.getAttributeName() ); contributorMapping.visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { final TableReference tableReference = rootTableGroup.resolveTableReference( containingTableExpression ); @@ -158,6 +159,7 @@ class DatabaseSnapshotExecutor { s -> new ColumnReference( tableReference, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java index 0f811e332e..f8f7c4d92e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java @@ -327,6 +327,7 @@ public class LoaderSelectBuilder { p -> new ColumnReference( tableReference, columnExpression, + false, jdbcMapping, creationContext.getSessionFactory() ) @@ -356,7 +357,7 @@ public class LoaderSelectBuilder { final List columnReferences = new ArrayList<>( numberOfKeyColumns ); keyPart.visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { final TableReference tableReference = rootTableGroup.resolveTableReference( containingTableExpression ); columnReferences.add( (ColumnReference) sqlExpressionResolver.resolveSqlExpression( @@ -364,6 +365,7 @@ public class LoaderSelectBuilder { p -> new ColumnReference( tableReference, columnExpression, + isColumnExpressionFormula, jdbcMapping, creationContext.getSessionFactory() ) @@ -683,6 +685,7 @@ public class LoaderSelectBuilder { sqlAstProcessingState -> new ColumnReference( rootTableGroup.resolveTableReference( simpleFkDescriptor.getContainingTableExpression() ), simpleFkDescriptor.getMappedColumnExpression(), + false, simpleFkDescriptor.getJdbcMapping(), this.creationContext.getSessionFactory() ) @@ -691,13 +694,14 @@ public class LoaderSelectBuilder { else { final List columnReferences = new ArrayList<>( jdbcTypeCount ); fkDescriptor.visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> columnReferences.add( (ColumnReference) sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression( createColumnReferenceKey( containingTableExpression, columnExpression ), sqlAstProcessingState -> new ColumnReference( rootTableGroup.resolveTableReference( containingTableExpression ), columnExpression, + isColumnExpressionFormula, jdbcMapping, this.creationContext.getSessionFactory() ) @@ -747,7 +751,7 @@ public class LoaderSelectBuilder { final MutableInteger count = new MutableInteger(); fkDescriptor.visitTargetColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { // for each column, resolve a SqlSelection and add it to the sub-query select-clause final TableReference tableReference = ownerTableGroup.resolveTableReference( containingTableExpression ); final Expression expression = sqlExpressionResolver.resolveSqlExpression( @@ -755,6 +759,7 @@ public class LoaderSelectBuilder { sqlAstProcessingState -> new ColumnReference( tableReference, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/BasicValuedModelPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/BasicValuedModelPart.java index c44702e36a..08eb0660fe 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/BasicValuedModelPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/BasicValuedModelPart.java @@ -24,6 +24,10 @@ public interface BasicValuedModelPart extends BasicValuedMapping, ModelPart, Fet */ String getMappedColumnExpression(); + default boolean isMappedColumnExpressionFormula() { + return false; + } + @Override default MappingType getPartMappingType() { return this::getJavaTypeDescriptor; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ColumnConsumer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ColumnConsumer.java index ad9ff28586..4fdb312641 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ColumnConsumer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ColumnConsumer.java @@ -15,5 +15,6 @@ public interface ColumnConsumer { void accept( String containingTableExpression, String columnExpression, + boolean isColumnExpressionFormula, JdbcMapping jdbcMapping); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java index d741ad4842..d81ec4b681 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java @@ -177,6 +177,7 @@ public class EmbeddableMappingType implements ManagedMappingType { (BasicType) subtype, containingTableExpression, mappedColumnExpressions.get( columnPosition++ ), + false, representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ), compositeType.getCascadeStyle( attributeIndex ), creationProcess diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/MappingModelHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/MappingModelHelper.java index a3c7821c25..0d6090677f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/MappingModelHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/MappingModelHelper.java @@ -34,6 +34,7 @@ public class MappingModelHelper { return new ColumnReference( basicPart.getContainingTableExpression(), basicPart.getMappedColumnExpression(), + basicPart.isMappedColumnExpressionFormula(), basicPart.getJdbcMapping(), sessionFactory ); @@ -44,6 +45,7 @@ public class MappingModelHelper { sqlAstProcessingState -> new ColumnReference( basicPart.getContainingTableExpression(), basicPart.getMappedColumnExpression(), + basicPart.isMappedColumnExpressionFormula(), basicPart.getJdbcMapping(), sessionFactory ) @@ -53,12 +55,13 @@ public class MappingModelHelper { else { final List columnReferences = new ArrayList<>( jdbcTypeCount ); modelPart.visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { final ColumnReference colRef; if ( sqlExpressionResolver == null ) { colRef = new ColumnReference( containingTableExpression, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ); @@ -69,6 +72,7 @@ public class MappingModelHelper { sqlAstProcessingState -> new ColumnReference( containingTableExpression, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicEntityIdentifierMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicEntityIdentifierMappingImpl.java index c8280850f1..8f5bb8c131 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicEntityIdentifierMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicEntityIdentifierMappingImpl.java @@ -125,7 +125,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa @Override public void visitColumns(ColumnConsumer consumer) { - consumer.accept( getContainingTableExpression(), getMappedColumnExpression(), getJdbcMapping() ); + consumer.accept( getContainingTableExpression(), getMappedColumnExpression(), false, getJdbcMapping() ); } @Override @@ -190,6 +190,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa sqlAstProcessingState -> new ColumnReference( rootTableReference.getIdentificationVariable(), pkColumnName, + false, ( (BasicValuedMapping) entityPersister.getIdentifierType() ).getJdbcMapping(), sessionFactory ) @@ -224,6 +225,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa sqlAstProcessingState -> new ColumnReference( rootTable, pkColumnName, + false, ( (BasicValuedModelPart) entityPersister.getIdentifierType() ).getJdbcMapping(), sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java index de57b8b362..2dfd7f6491 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedCollectionPart.java @@ -131,6 +131,7 @@ public class BasicValuedCollectionPart sqlAstProcessingState -> new ColumnReference( tableGroup.getPrimaryTableReference().getIdentificationVariable(), columnExpression, + false, mapper, creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedSingularAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedSingularAttributeMapping.java index 2e1cb85666..fca5198f96 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedSingularAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicValuedSingularAttributeMapping.java @@ -9,9 +9,11 @@ package org.hibernate.metamodel.mapping.internal; import java.util.function.Consumer; import org.hibernate.LockMode; +import org.hibernate.MappingException; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.FetchTiming; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.ColumnConsumer; import org.hibernate.metamodel.mapping.ConvertibleModelPart; @@ -24,6 +26,7 @@ import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.query.NavigablePath; +import org.hibernate.sql.Template; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlExpressionResolver; @@ -50,6 +53,7 @@ public class BasicValuedSingularAttributeMapping private final NavigableRole navigableRole; private final String tableExpression; private final String mappedColumnExpression; + private final boolean isMappedColumnExpressionFormula; private final JdbcMapping jdbcMapping; private final BasicValueConverter valueConverter; @@ -65,6 +69,7 @@ public class BasicValuedSingularAttributeMapping FetchStrategy mappedFetchStrategy, String tableExpression, String mappedColumnExpression, + boolean isMappedColumnExpressionFormula, BasicValueConverter valueConverter, JdbcMapping jdbcMapping, ManagedMappingType declaringType, @@ -73,6 +78,7 @@ public class BasicValuedSingularAttributeMapping this.navigableRole = navigableRole; this.tableExpression = tableExpression; this.mappedColumnExpression = mappedColumnExpression; + this.isMappedColumnExpressionFormula = isMappedColumnExpressionFormula; this.valueConverter = valueConverter; this.jdbcMapping = jdbcMapping; @@ -104,6 +110,11 @@ public class BasicValuedSingularAttributeMapping return mappedColumnExpression; } + @Override + public boolean isMappedColumnExpressionFormula() { + return isMappedColumnExpressionFormula; + } + @Override public String getContainingTableExpression() { return tableExpression; @@ -142,15 +153,18 @@ public class BasicValuedSingularAttributeMapping final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() ); + final String tableAlias = tableReference.getIdentificationVariable(); + final String columnExpression = getMappedColumnExpression(); return expressionResolver.resolveSqlSelection( expressionResolver.resolveSqlExpression( SqlExpressionResolver.createColumnReferenceKey( tableReference, - getMappedColumnExpression() + columnExpression ), sqlAstProcessingState -> new ColumnReference( - tableReference.getIdentificationVariable(), - getMappedColumnExpression(), + tableAlias, + columnExpression, + isMappedColumnExpressionFormula(), jdbcMapping, creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() ) @@ -179,6 +193,7 @@ public class BasicValuedSingularAttributeMapping sqlAstProcessingState -> new ColumnReference( tableReference.getIdentificationVariable(), getMappedColumnExpression(), + isMappedColumnExpressionFormula(), jdbcMapping, creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() ) @@ -246,6 +261,6 @@ public class BasicValuedSingularAttributeMapping @Override public void visitColumns(ColumnConsumer consumer) { - consumer.accept( tableExpression, mappedColumnExpression, jdbcMapping ); + consumer.accept( tableExpression, mappedColumnExpression, isMappedColumnExpressionFormula, jdbcMapping ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java index 62502cf4dd..4107965757 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CollectionIdentifierDescriptorImpl.java @@ -138,6 +138,7 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD p -> new ColumnReference( tableGroup.getPrimaryTableReference().getIdentificationVariable(), columnName, + false, type, sessionFactory ) @@ -176,6 +177,7 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD p -> new ColumnReference( tableGroup.getPrimaryTableReference().getIdentificationVariable(), columnName, + false, type, sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java index 779b89eb13..859a336948 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java @@ -217,6 +217,7 @@ public class EmbeddedAttributeMapping sqlAstProcessingState -> new ColumnReference( tableReference.getIdentificationVariable(), attrColumnExpr, + false, jdbcMapping, sqlAstCreationState.getCreationContext().getSessionFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java index 96d7394a7b..c099668af0 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedCollectionPart.java @@ -177,7 +177,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF final List expressions = new ArrayList<>(); getEmbeddableTypeDescriptor().visitColumns( - (tableExpression, columnExpression, jdbcMapping) ->{ + (tableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) ->{ assert containingTableExpression.equals( tableExpression ); assert columnExpressions.contains( columnExpression ); expressions.add( @@ -186,6 +186,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF sqlAstProcessingState -> new ColumnReference( tableGroup.resolveTableReference( tableExpression ), columnExpression, + isColumnExpressionFormula, jdbcMapping, sqlAstCreationState.getCreationContext().getSessionFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java index 24a533f972..e8ddcda7ea 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedForeignKeyDescriptor.java @@ -118,6 +118,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model new ColumnReference( identificationVariable, columnExpression, + false, jdbcMapping, creationState.getSqlAstCreationState() .getCreationContext() @@ -169,6 +170,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model new ColumnReference( identificationVariable, columnExpression, + false, jdbcMapping, creationState.getSqlAstCreationState() .getCreationContext() @@ -260,6 +262,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model new ColumnReference( lhs, lhsExpressions.get( i ), + false, jdbcMapping, creationContext.getSessionFactory() ), @@ -267,6 +270,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model new ColumnReference( rhs, rhsColumnExpressions.get( i ), + false, jdbcMapping, creationContext.getSessionFactory() ) @@ -312,14 +316,14 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model @Override public void visitReferringColumns(ColumnConsumer consumer) { for ( int i = 0; i < keyColumnExpressions.size(); i++ ) { - consumer.accept( keyColumnContainingTable, keyColumnExpressions.get( i ), jdbcMappings.get( i ) ); + consumer.accept( keyColumnContainingTable, keyColumnExpressions.get( i ), false, jdbcMappings.get( i ) ); } } @Override public void visitTargetColumns(ColumnConsumer consumer) { for ( int i = 0; i < keyColumnExpressions.size(); i++ ) { - consumer.accept( targetColumnContainingTable, targetColumnExpressions.get( i ), jdbcMappings.get( i ) ); + consumer.accept( targetColumnContainingTable, targetColumnExpressions.get( i ), false, jdbcMappings.get( i ) ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedIdentifierMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedIdentifierMappingImpl.java index 7358b0b633..9df22ff928 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedIdentifierMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedIdentifierMappingImpl.java @@ -227,6 +227,7 @@ public class EmbeddedIdentifierMappingImpl sqlAstProcessingState -> new ColumnReference( tableReference.getIdentificationVariable(), attrColumnExpr, + false, jdbcMapping, sqlAstCreationState.getCreationContext().getSessionFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityDiscriminatorMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityDiscriminatorMappingImpl.java index 16ab580763..ace599d4b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityDiscriminatorMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityDiscriminatorMappingImpl.java @@ -49,6 +49,7 @@ public class EntityDiscriminatorMappingImpl extends AbstractEntityDiscriminatorM sqlAstProcessingState -> new ColumnReference( tableReference.getIdentificationVariable(), getMappedColumnExpression(), + false, getJdbcMapping(), creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityRowIdMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityRowIdMappingImpl.java index 34f5706416..cde3708c74 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityRowIdMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityRowIdMappingImpl.java @@ -87,6 +87,7 @@ public class EntityRowIdMappingImpl implements EntityRowIdMapping { sqlAstProcessingState -> new ColumnReference( columnTableReference, rowIdName, + false, JavaObjectType.INSTANCE, sqlAstCreationState.getCreationContext().getSessionFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityVersionMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityVersionMappingImpl.java index 0b275f7065..77d7818008 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityVersionMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityVersionMappingImpl.java @@ -142,6 +142,7 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti sqlAstProcessingState -> new ColumnReference( columnTableReference, columnExpression, + false, versionBasicType, sqlAstCreationState.getCreationContext().getSessionFactory() ) @@ -179,6 +180,7 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti sqlAstProcessingState -> new ColumnReference( columnTableReference, columnExpression, + false, versionBasicType, sqlAstCreationState.getCreationContext().getSessionFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java index 13cd6b5e10..4c52f33737 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java @@ -204,6 +204,7 @@ public class MappingModelCreationHelper { (BasicType) idSubPropertyType, rootTableName, rootTableKeyColumnNames[columnsConsumedSoFar], + false, entityPersister.getRepresentationStrategy().resolvePropertyAccess( bootIdSubProperty ), CascadeStyles.ALL, creationProcess @@ -272,6 +273,7 @@ public class MappingModelCreationHelper { BasicType attrType, String tableExpression, String attrColumnName, + boolean isAttrFormula, PropertyAccess propertyAccess, CascadeStyle cascadeStyle, MappingModelCreationProcess creationProcess) { @@ -333,6 +335,15 @@ public class MappingModelCreationHelper { : FetchStrategy.IMMEDIATE_JOIN; if ( valueConverter != null ) { + + if ( isAttrFormula ) { + throw new MappingException( String.format( + "Value converter should not be set for column [%s] annotated with @Formula [%s]", + attrName, + attrColumnName + ) ); + } + // we want to "decompose" the "type" into its various pieces as expected by the mapping assert valueConverter.getRelationalJavaDescriptor() == resolution.getRelationalJavaDescriptor(); @@ -354,6 +365,7 @@ public class MappingModelCreationHelper { fetchStrategy, tableExpression, attrColumnName, + false, valueConverter, mappingBasicType.getJdbcMapping(), declaringType, @@ -369,6 +381,7 @@ public class MappingModelCreationHelper { fetchStrategy, tableExpression, attrColumnName, + isAttrFormula, null, attrType, declaringType, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java index 774104679a..da5ad6ac08 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java @@ -89,6 +89,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa new ColumnReference( identificationVariable, targetColumnExpression, + false, jdbcMapping, creationState.getSqlAstCreationState() .getCreationContext() @@ -139,6 +140,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa new ColumnReference( identificationVariable, keyColumnExpression, + false, jdbcMapping, creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() ) @@ -167,6 +169,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa new ColumnReference( lhs, keyColumnExpression, + false, jdbcMapping, creationContext.getSessionFactory() ), @@ -174,6 +177,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa new ColumnReference( rhs, targetColumnExpression, + false, jdbcMapping, creationContext.getSessionFactory() ) @@ -184,6 +188,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa new ColumnReference( lhs, targetColumnExpression, + false, jdbcMapping, creationContext.getSessionFactory() ), @@ -191,6 +196,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa new ColumnReference( rhs, keyColumnExpression, + false, jdbcMapping, creationContext.getSessionFactory() ) @@ -285,12 +291,12 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa @Override public void visitReferringColumns(ColumnConsumer consumer) { - consumer.accept( keyColumnContainingTable, keyColumnExpression, jdbcMapping ); + consumer.accept( keyColumnContainingTable, keyColumnExpression, false, jdbcMapping ); } @Override public void visitTargetColumns(ColumnConsumer consumer) { - consumer.accept( targetColumnContainingTable, targetColumnExpression, jdbcMapping ); + consumer.accept( targetColumnContainingTable, targetColumnExpression, false, jdbcMapping ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/ColumnReference.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/ColumnReference.java index ba9329054a..7fe73a0754 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/ColumnReference.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/ColumnReference.java @@ -26,10 +26,12 @@ import org.hibernate.sql.ast.tree.select.SortSpecification; */ public class ColumnReference implements OrderingExpression, SequencePart { private final String columnExpression; + private final boolean isColumnExpressionFormula; private final NavigablePath rootPath; - public ColumnReference(String columnExpression, NavigablePath rootPath) { + public ColumnReference(String columnExpression, boolean isColumnExpressionFormula, NavigablePath rootPath) { this.columnExpression = columnExpression; + this.isColumnExpressionFormula = isColumnExpressionFormula; this.rootPath = rootPath; } @@ -37,6 +39,10 @@ public class ColumnReference implements OrderingExpression, SequencePart { return columnExpression; } + public boolean isColumnExpressionFormula() { + return isColumnExpressionFormula; + } + @Override public SequencePart resolvePathPart( String name, @@ -63,6 +69,7 @@ public class ColumnReference implements OrderingExpression, SequencePart { sqlAstProcessingState -> new org.hibernate.sql.ast.tree.expression.ColumnReference( tableGroup.getPrimaryTableReference(), columnExpression, + isColumnExpressionFormula, // because these ordering fragments are only ever part of the order-by clause, there // is no need for the JdbcMapping null, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/DomainPath.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/DomainPath.java index ac2dee6396..ff91a98a5a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/DomainPath.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/DomainPath.java @@ -58,6 +58,7 @@ public interface DomainPath extends OrderingExpression, SequencePart { new ColumnReference( tableReference, basicValuedPart.getMappedColumnExpression(), + basicValuedPart.isMappedColumnExpressionFormula(), basicValuedPart.getJdbcMapping(), creationState.getCreationContext().getSessionFactory() ), @@ -68,7 +69,7 @@ public interface DomainPath extends OrderingExpression, SequencePart { } else { getReferenceModelPart().visitColumns( - (tableExpression, columnExpression, jdbcMapping) -> { + (tableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { final TableReference tableReference = tableGroup.resolveTableReference( tableExpression ); ast.addSortSpecification( new SortSpecification( @@ -80,6 +81,7 @@ public interface DomainPath extends OrderingExpression, SequencePart { sqlAstProcessingState -> new ColumnReference( tableReference, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/RootSequencePart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/RootSequencePart.java index 485539ecd1..e31249a901 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/RootSequencePart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ordering/ast/RootSequencePart.java @@ -37,7 +37,7 @@ public class RootSequencePart implements SequencePart { if ( isTerminal ) { // assume a column-reference - return new ColumnReference( name, pluralAttributePath.getNavigablePath() ); + return new ColumnReference( name, false, pluralAttributePath.getNavigablePath() ); } throw new PathResolutionException( diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 1ee9a1de40..bbc22e6c11 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -122,7 +122,6 @@ import org.hibernate.loader.entity.CacheEntityLoaderHelper; import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.Column; import org.hibernate.mapping.Component; -import org.hibernate.mapping.Formula; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.RootClass; @@ -824,7 +823,8 @@ public abstract class AbstractEntityPersister colAliases[k] = thing.getAlias( dialect, prop.getValue().getTable() ); if ( thing.isFormula() ) { foundFormula = true; - ( (Formula) thing ).setFormula( substituteBrackets( ( (Formula) thing ).getFormula() ) ); + // ( (Formula) thing ).setFormula( substituteBrackets( ( (Formula) thing ).getFormula() ) ); + // TODO: uncomment the above statement when this#substituteBrackets(String) is implemented formulaTemplates[k] = thing.getTemplate( dialect, factory.getQueryEngine().getSqmFunctionRegistry() ); } else { @@ -1406,6 +1406,7 @@ public abstract class AbstractEntityPersister sqlAstProcessingState -> new ColumnReference( rootTableReference.getIdentificationVariable(), rootPkColumnName, + false, jdbcMapping, getFactory() ) @@ -1420,6 +1421,7 @@ public abstract class AbstractEntityPersister sqlAstProcessingState -> new ColumnReference( joinedTableReference.getIdentificationVariable(), fkColumnName, + false, jdbcMapping, getFactory() ) @@ -6143,6 +6145,7 @@ public abstract class AbstractEntityPersister (BasicType) attrType, tableExpression, attrColumnNames[0], + false, propertyAccess, tupleAttrDefinition.getCascadeStyle(), creationProcess @@ -6150,6 +6153,17 @@ public abstract class AbstractEntityPersister } if ( attrType instanceof BasicType ) { + final String attrColumnExpression; + final boolean isAttrColumnExpressionFormula; + if ( attrColumnNames[0] != null ) { + attrColumnExpression = attrColumnNames[0]; + isAttrColumnExpressionFormula = false; + } + else { + final String[] attrColumnFormulaTemplate = propertyColumnFormulaTemplates[ propertyIndex ]; + attrColumnExpression = attrColumnFormulaTemplate[0]; + isAttrColumnExpressionFormula = true; + } return MappingModelCreationHelper.buildBasicAttributeMapping( attrName, getNavigableRole().append( bootProperty.getName() ), @@ -6158,7 +6172,8 @@ public abstract class AbstractEntityPersister this, (BasicType) attrType, tableExpression, - attrColumnNames[0], + attrColumnExpression, + isAttrColumnExpressionFormula, propertyAccess, tupleAttrDefinition.getCascadeStyle(), creationProcess diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java index 74c9f4f6eb..bc4ee61e64 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java @@ -33,6 +33,7 @@ import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.DynamicFilterAliasGenerator; import org.hibernate.internal.FilterAliasGenerator; +import org.hibernate.internal.TableGroupFilterAliasGenerator; import org.hibernate.internal.util.MarkerObject; import org.hibernate.internal.util.MutableInteger; import org.hibernate.internal.util.StringHelper; @@ -1272,7 +1273,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { () -> columnConsumer -> { final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition]; for ( String column : keyColumnNames ) { - columnConsumer.accept( tableName, column, null ); + columnConsumer.accept( tableName, column, false, null ); } } ); @@ -1343,6 +1344,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { return new ColumnReference( tableReference.getIdentificationVariable(), discriminatorColumnNameByTableName.get( tableReference.getTableExpression() ), + false, jdbcMappings.get( 0 ), getFactory() ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java index d05021f6a0..feb8c862b9 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java @@ -928,6 +928,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { sqlAstProcessingState -> new ColumnReference( tableGroup.getPrimaryTableReference().getIdentificationVariable(), getDiscriminatorColumnName(), + false, ( (BasicType) getDiscriminatorType() ).getJdbcMapping(), getFactory() ) @@ -952,7 +953,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { () -> columnConsumer -> { final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition]; for ( String column : keyColumnNames ) { - columnConsumer.accept( tableName, column, null ); + columnConsumer.accept( tableName, column, false,null ); } } ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java index 1fccf4f814..1b23606845 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java @@ -389,7 +389,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister { () -> columnConsumer -> { final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition]; for ( String column : keyColumnNames ) { - columnConsumer.accept( tableName, column, null ); + columnConsumer.accept( tableName, column, false, null ); } } ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java index 150cdde8b7..408e12a834 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java @@ -80,7 +80,7 @@ public class MatchingIdSelectionHelper { final List domainResults = new ArrayList<>(); final MutableInteger i = new MutableInteger(); targetEntityDescriptor.getIdentifierMapping().visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { final int position = i.getAndIncrement(); final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression ); final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression( @@ -88,6 +88,7 @@ public class MatchingIdSelectionHelper { sqlAstProcessingState -> new ColumnReference( tableReference, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) @@ -141,7 +142,7 @@ public class MatchingIdSelectionHelper { final MutableInteger i = new MutableInteger(); targetEntityDescriptor.getIdentifierMapping().visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { final int position = i.getAndIncrement(); final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression ); final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression( @@ -149,6 +150,7 @@ public class MatchingIdSelectionHelper { sqlAstProcessingState -> new ColumnReference( tableReference, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java index aeeecbe474..5ca730e849 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java @@ -221,10 +221,11 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele final List columnsToMatchReferences = new ArrayList<>(); columnsToMatchVisitationSupplier.get().accept( - (containingTableExpression, columnExpression, jdbcMapping) -> columnsToMatchReferences.add( + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> columnsToMatchReferences.add( new ColumnReference( targetTableReference, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithIdTableHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithIdTableHelper.java index d664ed5a57..b47cc87e2a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithIdTableHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithIdTableHelper.java @@ -76,7 +76,7 @@ public final class ExecuteWithIdTableHelper { for ( int i = 0; i < idTable.getIdTableColumns().size(); i++ ) { final IdTableColumn column = idTable.getIdTableColumns().get( i ); idTableInsert.addTargetColumnReferences( - new ColumnReference( idTableReference, column.getColumnName(), column.getJdbcMapping(), factory ) + new ColumnReference( idTableReference, column.getColumnName(), false, column.getJdbcMapping(), factory ) ); } @@ -88,7 +88,7 @@ public final class ExecuteWithIdTableHelper { final MutableInteger positionWrapper = new MutableInteger(); mutatingEntityDescriptor.getIdentifierMapping().visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { final int jdbcPosition = positionWrapper.getAndIncrement(); final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression ); matchingIdSelection.getSelectClause().addSqlSelection( @@ -100,6 +100,7 @@ public final class ExecuteWithIdTableHelper { sqlAstProcessingState -> new ColumnReference( tableReference, columnExpression, + isColumnExpressionFormula, jdbcMapping, factory ) @@ -190,6 +191,7 @@ public final class ExecuteWithIdTableHelper { new ColumnReference( tableReference, idTableColumn.getColumnName(), + false, idTableColumn.getJdbcMapping(), executionContext.getSession().getFactory() ) @@ -211,6 +213,7 @@ public final class ExecuteWithIdTableHelper { new ColumnReference( idTableReference, idTable.getSessionUidColumn().getColumnName(), + false, idTable.getSessionUidColumn().getJdbcMapping(), executionContext.getSession().getFactory() ), diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithoutIdTableHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithoutIdTableHelper.java index d42da9cc42..664682bced 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithoutIdTableHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/ExecuteWithoutIdTableHelper.java @@ -53,12 +53,13 @@ public final class ExecuteWithoutIdTableHelper { matchingIdSelect.getFromClause().addRoot( matchingIdSelectTableGroup ); rootEntityPersister.getIdentifierMapping().visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { final ColumnReference columnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression( SqlExpressionResolver.createColumnReferenceKey( rootTableReference, columnExpression ), sqlAstProcessingState -> new ColumnReference( rootTableReference, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/IdTable.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/IdTable.java index 92970784dd..ce599601fe 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/IdTable.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/IdTable.java @@ -34,7 +34,7 @@ public class IdTable implements Exportable { ); entityDescriptor.getIdentifierMapping().visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> columns.add( + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> columns.add( new IdTableColumn( this, columnExpression, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/RestrictedDeleteExecutionDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/RestrictedDeleteExecutionDelegate.java index fe2df77444..53b3e346d3 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/RestrictedDeleteExecutionDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/RestrictedDeleteExecutionDelegate.java @@ -285,7 +285,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle */ final List deletingTableColumnRefs = new ArrayList<>(); tableKeyColumnVisitationSupplier.get().accept( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { assert targetTableReference.getTableExpression().equals( containingTableExpression ); final Expression expression = sqlExpressionResolver.resolveSqlExpression( @@ -293,6 +293,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle sqlAstProcessingState -> new ColumnReference( rootTableGroup.getPrimaryTableReference(), columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) @@ -456,12 +457,13 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector( entityDescriptor ); tableKeyColumnVisitationSupplier.get().accept( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { assert containingTableExpression.equals( tableExpression ); keyColumnCollector.apply( new ColumnReference( (String) null, columnExpression, + isColumnExpressionFormula, jdbcMapping, factory ) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/UpdateExecutionDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/UpdateExecutionDelegate.java index d0660800d5..3302e6a39e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/UpdateExecutionDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/UpdateExecutionDelegate.java @@ -236,12 +236,13 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector( entityDescriptor ); tableKeyColumnVisitationSupplier.get().accept( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { assert containingTableExpression.equals( tableExpression ); keyColumnCollector.apply( new ColumnReference( (String) null, columnExpression, + isColumnExpressionFormula, jdbcMapping, sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/DisjunctionRestrictionProducer.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/DisjunctionRestrictionProducer.java index 1411978558..f5c44c805d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/DisjunctionRestrictionProducer.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/DisjunctionRestrictionProducer.java @@ -67,6 +67,7 @@ public class DisjunctionRestrictionProducer implements MatchingIdRestrictionProd final ColumnReference idColumnReference = new ColumnReference( mutatingTableReference, idColumn, + false, basicIdMapping.getJdbcMapping(), sessionFactory ); @@ -88,8 +89,8 @@ public class DisjunctionRestrictionProducer implements MatchingIdRestrictionProd final List columnReferences = new ArrayList<>( idColumnCount ); final List jdbcMappings = new ArrayList<>( idColumnCount ); identifierMapping.visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { - columnReferences.add( new ColumnReference( mutatingTableReference, columnExpression, jdbcMapping, sessionFactory ) ); + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { + columnReferences.add( new ColumnReference( mutatingTableReference, columnExpression, isColumnExpressionFormula, jdbcMapping, sessionFactory ) ); jdbcMappings.add( jdbcMapping ); } ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/InPredicateRestrictionProducer.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/InPredicateRestrictionProducer.java index 3e004fe3c7..cb57a1e7f1 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/InPredicateRestrictionProducer.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/inline/InPredicateRestrictionProducer.java @@ -69,6 +69,7 @@ public class InPredicateRestrictionProducer implements MatchingIdRestrictionProd final Expression inFixture = new ColumnReference( mutatingTableReference, idColumn, + false, basicIdMapping.getJdbcMapping(), sessionFactory ); @@ -83,8 +84,8 @@ public class InPredicateRestrictionProducer implements MatchingIdRestrictionProd final List columnReferences = new ArrayList<>( idColumnCount ); final List jdbcMappings = new ArrayList<>( idColumnCount ); identifierMapping.visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { - columnReferences.add( new ColumnReference( mutatingTableReference, columnExpression, jdbcMapping, sessionFactory ) ); + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { + columnReferences.add( new ColumnReference( mutatingTableReference, columnExpression, isColumnExpressionFormula, jdbcMapping, sessionFactory ) ); jdbcMappings.add( jdbcMapping ); } ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java index d0247320a2..8117fc1efb 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java @@ -62,6 +62,7 @@ public class BasicValuedPathInterpretation implements AssignableSqmPathInterp sacs -> new ColumnReference( tableReference.getIdentificationVariable(), mapping.getMappedColumnExpression(), + mapping.isMappedColumnExpressionFormula(), mapping.getJdbcMapping(), sqlAstCreationState.getCreationContext().getSessionFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmUpdateTranslator.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmUpdateTranslator.java index 537362c14f..9328d9c571 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmUpdateTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/StandardSqmUpdateTranslator.java @@ -237,7 +237,7 @@ public class StandardSqmUpdateTranslator // create one JdbcParameter for each column in the assigned path assignedPathInterpretation.getExpressionType().visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> { + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> { final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping ); jdbcParametersForSqm.add( jdbcParameter ); assignments.add( @@ -246,6 +246,7 @@ public class StandardSqmUpdateTranslator // we do not want a qualifier (table alias) here (String) null, columnExpression, + isColumnExpressionFormula, jdbcMapping, getCreationContext().getSessionFactory() ), diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java index d3de9af42e..c3a9c90767 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java @@ -277,6 +277,9 @@ public class SqmSelectStatement extends AbstractSqmSelectQuery implements @Override public SqmSelectStatement orderBy(Order... orders) { + if ( getQuerySpec().getOrderByClause() == null ) { + getQuerySpec().setOrderByClause( new SqmOrderByClause() ); + } for ( Order order : orders ) { getQuerySpec().getOrderByClause().addSortSpecification( (SqmSortSpecification) order ); } @@ -285,6 +288,9 @@ public class SqmSelectStatement extends AbstractSqmSelectQuery implements @Override public SqmSelectStatement orderBy(List orders) { + if ( getQuerySpec().getOrderByClause() == null ) { + getQuerySpec().setOrderByClause( new SqmOrderByClause() ); + } for ( Order order : orders ) { getQuerySpec().getOrderByClause().addSortSpecification( (SqmSortSpecification) order ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java index 7f9cb599fe..3dca43b543 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java @@ -492,11 +492,7 @@ public abstract class AbstractSqlAstWalker @Override public void visitColumnReference(ColumnReference columnReference) { - if ( columnReference.getQualifier() != null ) { - appendSql( columnReference.getQualifier() ); - appendSql( "." ); - } - appendSql( columnReference.getColumnExpression() ); + appendSql( columnReference.getExpressionText() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java index 5fc46cb7d4..b0ca145056 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/cte/CteTable.java @@ -46,7 +46,7 @@ public class CteTable { final int numberOfColumns = entityDescriptor.getIdentifierMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() ); cteColumns = new ArrayList<>( numberOfColumns ); entityDescriptor.getIdentifierMapping().visitColumns( - (containingTableExpression, columnExpression, jdbcMapping) -> cteColumns.add( + (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> cteColumns.add( new CteColumn( "cte_" + columnExpression, jdbcMapping @@ -183,6 +183,7 @@ public class CteTable { new ColumnReference( tableReference, cteColumn.getColumnExpression(), + false, cteColumn.getJdbcMapping(), sessionFactory ) diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java index ecb7bd2cf1..4e672f949e 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java @@ -4,19 +4,18 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html */ - package org.hibernate.sql.ast.tree.expression; import java.util.Collections; import java.util.List; import java.util.Locale; -import java.util.Objects; import java.util.function.Consumer; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.MappingModelExpressable; +import org.hibernate.sql.Template; import org.hibernate.sql.ast.SqlAstWalker; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.update.Assignable; @@ -25,32 +24,43 @@ import org.hibernate.sql.ast.tree.update.Assignable; * Models a reference to a Column in a SQL AST * * @author Steve Ebersole + * @author Nathan Xu */ public class ColumnReference implements Expression, Assignable { private final String qualifier; private final String columnExpression; + private final boolean isColumnExpressionFormula; private final String referenceExpression; private final JdbcMapping jdbcMapping; public ColumnReference( String qualifier, String columnExpression, + boolean isColumnExpressionFormula, JdbcMapping jdbcMapping, SessionFactoryImplementor sessionFactory) { this.qualifier = StringHelper.nullIfEmpty( qualifier ); - this.columnExpression = columnExpression; - this.referenceExpression = this.qualifier == null - ? columnExpression - : this.qualifier + "." + columnExpression; + if ( isColumnExpressionFormula ) { + assert qualifier != null; + this.columnExpression = StringHelper.replace( columnExpression, Template.TEMPLATE, qualifier ); + } + else { + this.columnExpression = columnExpression; + } + this.isColumnExpressionFormula = isColumnExpressionFormula; + this.referenceExpression = this.qualifier == null || isColumnExpressionFormula + ? this.columnExpression + : this.qualifier + "." + this.columnExpression; this.jdbcMapping = jdbcMapping; } public ColumnReference( TableReference tableReference, String columnExpression, + boolean isColumnExpressionFormula, JdbcMapping jdbcMapping, SessionFactoryImplementor sessionFactory) { - this( tableReference.getIdentificationVariable(), columnExpression, jdbcMapping, sessionFactory ); + this( tableReference.getIdentificationVariable(), columnExpression, isColumnExpressionFormula, jdbcMapping, sessionFactory ); } public String getQualifier() { @@ -61,6 +71,10 @@ public class ColumnReference implements Expression, Assignable { return columnExpression; } + public boolean isColumnExpressionFormula() { + return isColumnExpressionFormula; + } + public String getExpressionText() { return referenceExpression; } @@ -103,7 +117,7 @@ public class ColumnReference implements Expression, Assignable { } final ColumnReference that = (ColumnReference) o; - return Objects.equals( referenceExpression, that.referenceExpression ); + return referenceExpression.equals( that.referenceExpression ); } @Override diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaBasicsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaBasicsTest.java new file mode 100644 index 0000000000..28f42ad442 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaBasicsTest.java @@ -0,0 +1,131 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.orm.test.formula; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + +import org.hibernate.annotations.Formula; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +/** + * @author Nathan Xu + */ +@DomainModel( + annotatedClasses = { + FormulaBasicsTest.Account.class + } +) +@SessionFactory +public class FormulaBasicsTest { + + @BeforeEach + void setUp(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final Account account = new Account( ); + account.setId( 1L ); + account.setCredit( 5000d ); + account.setRate( 1.25 / 100 ); + session.persist( account ); + } ); + } + + @Test + void testLoader(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final Account account = session.find( Account.class, 1L ); + assertThat( account.getInterest(), is( 62.5d )); + } ); + } + + @Test + void testHQL(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final Account account = session.createQuery( "select a from Account a where a.id = :id", Account.class ) + .setParameter( "id", 1L ).uniqueResult(); + assertThat( account.getInterest(), is( 62.5d )); + } ); + } + + @Test + void testCriteria(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final CriteriaBuilder criteriaBuilder = scope.getSessionFactory().getCriteriaBuilder(); + final CriteriaQuery criteria = criteriaBuilder.createQuery( Account.class ); + final Root root = criteria.from( Account.class ); + criteria.select( root ); + criteria.where( criteriaBuilder.equal( root.get( "id" ), criteriaBuilder.literal( 1L ) ) ); + final Account account = session.createQuery( criteria ).uniqueResult(); + assertThat( account.getInterest(), is( 62.5d )); + } ); + } + + @AfterEach + void tearDown(SessionFactoryScope scope) { + scope.inTransaction( session -> { + session.createQuery( "delete from Account" ).executeUpdate(); + } ); + } + + @Entity(name = "Account") + public static class Account { + + @Id + private Long id; + + private Double credit; + + private Double rate; + + @Formula(value = "credit * rate") + private Double interest; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Double getCredit() { + return credit; + } + + public void setCredit(Double credit) { + this.credit = credit; + } + + public Double getRate() { + return rate; + } + + public void setRate(Double rate) { + this.rate = rate; + } + + public Double getInterest() { + return interest; + } + + public void setInterest(Double interest) { + this.interest = interest; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaNativeQueryTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaNativeQueryTest.java new file mode 100644 index 0000000000..b0cc47ef99 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaNativeQueryTest.java @@ -0,0 +1,122 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.orm.test.formula; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.Formula; +import org.hibernate.query.Query; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.FailureExpected; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hibernate.testing.hamcrest.CollectionMatchers.hasSize; +import static org.junit.Assert.assertThat; + +/** + * @author Алексей Макаров + * @author Gail Badner + * @author Nathan Xu + */ +@DomainModel( annotatedClasses = FormulaNativeQueryTest.Foo.class ) +@SessionFactory +@TestForIssue(jiraKey = "HHH-7525") +public class FormulaNativeQueryTest { + + @BeforeEach + void setUp(SessionFactoryScope scope) { + scope.inTransaction( session -> { + session.persist( new Foo( 1, 1 ) ); + session.persist( new Foo( 1, 2 ) ); + session.persist( new Foo( 2, 1 ) ); + } ); + } + + @AfterEach + void tearDown(SessionFactoryScope scope) { + scope.inTransaction( session -> session.createQuery( "delete from Foo" ).executeUpdate() ); + } + + @Test + @FailureExpected( jiraKey = "HHH-7525", reason = "native query not implemented yet") + void testNativeQuery(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final Query query = session.createNativeQuery( "SELECT ft.* FROM foo_table ft", Foo.class ); + final List list = query.getResultList(); + assertThat( list, hasSize( 3 ) ); + } ); + } + + @Test + void testHql(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final Query query = session.createQuery( "SELECT ft FROM Foo ft", Foo.class ); + final List list = query.getResultList(); + assertThat( list, hasSize( 3 ) ); + } ); + } + + @Entity(name = "Foo") + @Table(name = "foo_table") + public static class Foo { + + private int id; + private int locationStart; + private int locationEnd; + private int distance; + + public Foo() { + } + + public Foo(int locationStart, int locationEnd) { + this.locationStart = locationStart; + this.locationEnd = locationEnd; + } + + @Id + @GeneratedValue + public int getId() { + return id; + } + private void setId(int id) { + this.id = id; + } + + public int getLocationStart() { + return locationStart; + } + public void setLocationStart(int locationStart) { + this.locationStart = locationStart; + } + + public int getLocationEnd() { + return locationEnd; + } + public void setLocationEnd(int locationEnd) { + this.locationEnd = locationEnd; + } + + @Formula("abs(locationEnd - locationStart)") + public int getDistance() { + return distance; + } + + public void setDistance(int distance) { + this.distance = distance; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaWithAliasTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaWithAliasTest.java similarity index 59% rename from hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaWithAliasTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaWithAliasTest.java index 45ffc2b17b..19b86b3743 100755 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaWithAliasTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaWithAliasTest.java @@ -4,80 +4,70 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.annotations.formula; - -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; -import static org.junit.Assert.assertEquals; +package org.hibernate.orm.test.formula; import java.io.Serializable; import java.math.BigDecimal; import java.util.List; - import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import org.hibernate.Session; -import org.hibernate.Transaction; import org.hibernate.annotations.Formula; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.cfg.Configuration; -import org.hibernate.cfg.Environment; import org.hibernate.dialect.H2Dialect; -import org.hibernate.query.Query; -import org.hibernate.test.annotations.formula.FormulaWithColumnTypesTest.ExtendedDialect; -import org.hibernate.test.locking.A; -import org.hibernate.testing.RequiresDialect; + import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.RequiresDialect; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertEquals; /** - * @author Yanming Zhou* + * @author Yanming Zhou + * @author Nathan Xu */ +@DomainModel( annotatedClasses = FormulaWithAliasTest.Customer.class ) +@SessionFactory @RequiresDialect(H2Dialect.class) -public class FormulaWithAliasTest extends BaseCoreFunctionalTestCase { +public class FormulaWithAliasTest { - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { Customer.class }; - } - - @Override - protected void configure(Configuration configuration) { - configuration.setProperty( - Environment.DIALECT, - ExtendedDialect.class.getName() - ); - } - - @Test - @TestForIssue(jiraKey = "HHH-12280") - public void testFormulaWithAlias() throws Exception { - doInHibernate( this::sessionFactory, session -> { - Customer company1 = new Customer(); + @BeforeEach + void setUp(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final Customer company1 = new Customer(); company1.setBalance(new BigDecimal(100)); company1.setVip(true); session.persist(company1); - Customer company2 = new Customer(); + final Customer company2 = new Customer(); company2.setBalance(new BigDecimal(1000)); company2.setVip(false); session.persist(company2); } ); - - doInHibernate( this::sessionFactory, session -> { - List customers = session.createQuery( - "select c " + - "from Customer c ", Customer.class) - .getResultList(); + } + @Test + @TestForIssue(jiraKey = "HHH-12280") + void testFormulaWithAlias(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final List customers = session.createQuery( "select c from Customer c ", Customer.class ).getResultList(); assertEquals(2, customers.size()); assertEquals(1d, customers.get(0).getPercentage().doubleValue(), 0); assertEquals(1d, customers.get(1).getPercentage().doubleValue(), 0); } ); } + + @AfterEach + void tearDown(SessionFactoryScope scope) { + scope.inTransaction( session -> session.createQuery( "delete from Customer" ).executeUpdate() ); + } @Entity(name = "Customer") public static class Customer implements Serializable{ diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaWithColumnTypesTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaWithColumnTypesTest.java similarity index 60% rename from hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaWithColumnTypesTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaWithColumnTypesTest.java index ffb34e11bb..cb260a3ecb 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaWithColumnTypesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaWithColumnTypesTest.java @@ -4,7 +4,7 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.annotations.formula; +package org.hibernate.orm.test.formula; import java.io.Serializable; import java.util.List; @@ -49,89 +49,89 @@ public class FormulaWithColumnTypesTest extends BaseCoreFunctionalTestCase { @TestForIssue(jiraKey = "HHH-9951") public void testFormulaAnnotationWithTypeNames() { - inTransaction( - session -> { - DisplayItem displayItem20 = new DisplayItem(); - displayItem20.setDisplayCode( "20" ); + inTransaction( session -> { + session.getSessionFactory().getQueryEngine().getInterpretationCache().close(); - DisplayItem displayItem03 = new DisplayItem(); - displayItem03.setDisplayCode( "03" ); + final DisplayItem displayItem20 = new DisplayItem(); + displayItem20.setDisplayCode( "20" ); - DisplayItem displayItem100 = new DisplayItem(); - displayItem100.setDisplayCode( "100" ); + final DisplayItem displayItem03 = new DisplayItem(); + displayItem03.setDisplayCode( "03" ); - session.persist( displayItem20 ); - session.persist( displayItem03 ); - session.persist( displayItem100 ); - } - ); + final DisplayItem displayItem100 = new DisplayItem(); + displayItem100.setDisplayCode( "100" ); + + session.persist( displayItem20 ); + session.persist( displayItem03 ); + session.persist( displayItem100 ); + } ); // 1. Default sorting by display code natural ordering (resulting in 3-100-20). - inTransaction( - session -> { - CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); - CriteriaQuery criteria = criteriaBuilder.createQuery( DisplayItem.class ); - Root root = criteria.from( DisplayItem.class ); - criteria.orderBy( criteriaBuilder.asc( root.get( "displayCode" ) ) ); + inTransaction( session -> { + session.getSessionFactory().getQueryEngine().getInterpretationCache().close(); - List displayItems = session.createQuery( criteria ).list(); + final CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); + final CriteriaQuery criteria = criteriaBuilder.createQuery( DisplayItem.class ); + final Root root = criteria.from( DisplayItem.class ); + criteria.orderBy( criteriaBuilder.asc( root.get( "displayCode" ) ) ); + + final List displayItems = session.createQuery( criteria ).getResultList(); // List displayItems = session.createCriteria( DisplayItem.class ) // .addOrder( Order.asc( "displayCode" ) ) // .list(); - assertNotNull( displayItems ); - assertEquals( displayItems.size(), 3 ); - assertEquals( - "03", - ( (DisplayItem) displayItems.get( 0 ) ).getDisplayCode() - ); - assertEquals( - "100", - ( (DisplayItem) displayItems.get( 1 ) ).getDisplayCode() - ); - assertEquals( - "20", - ( (DisplayItem) displayItems.get( 2 ) ).getDisplayCode() - ); - } - ); + assertNotNull( displayItems ); + assertEquals( 3, displayItems.size() ); + assertEquals( + "03", + displayItems.get( 0 ).getDisplayCode() + ); + assertEquals( + "100", + displayItems.get( 1 ).getDisplayCode() + ); + assertEquals( + "20", + displayItems.get( 2 ).getDisplayCode() + ); + } ); // 2. Sorting by the casted type (resulting in 3-20-100). - inTransaction( - session -> { - CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); - CriteriaQuery criteria = criteriaBuilder.createQuery( DisplayItem.class ); - Root root = criteria.from( DisplayItem.class ); - criteria.orderBy( criteriaBuilder.asc( root.get( "displayCodeAsInteger" ) ) ); + inTransaction( session -> { + session.getSessionFactory().getQueryEngine().getInterpretationCache().close(); - List displayItemsSortedByInteger = session.createQuery( criteria ).list(); + final CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); + final CriteriaQuery criteria = criteriaBuilder.createQuery( DisplayItem.class ); + final Root root = criteria.from( DisplayItem.class ); + criteria.orderBy( criteriaBuilder.asc( root.get( "displayCodeAsInteger" ) ) ); + + final List displayItemsSortedByInteger = session.createQuery( criteria ).getResultList(); // List displayItemsSortedByInteger = session.createCriteria( DisplayItem.class ) // .addOrder( Order.asc( "displayCodeAsInteger" ) ) // .list(); - assertNotNull( displayItemsSortedByInteger ); - assertEquals( displayItemsSortedByInteger.size(), 3 ); - assertEquals( - "03", - ( (DisplayItem) displayItemsSortedByInteger.get( 0 ) ).getDisplayCode() - ); - assertEquals( - "20", - ( (DisplayItem) displayItemsSortedByInteger.get( 1 ) ).getDisplayCode() - ); - assertEquals( - "100", - ( (DisplayItem) displayItemsSortedByInteger.get( 2 ) ).getDisplayCode() - ); - } - ); + assertNotNull( displayItemsSortedByInteger ); + assertEquals( 3, displayItemsSortedByInteger.size() ); + assertEquals( + "03", + displayItemsSortedByInteger.get( 0 ).getDisplayCode() + ); + assertEquals( + "20", + displayItemsSortedByInteger.get( 1 ).getDisplayCode() + ); + assertEquals( + "100", + displayItemsSortedByInteger.get( 2 ).getDisplayCode() + ); + } ); } @Override public Class[] getAnnotatedClasses() { - return new Class[] {DisplayItem.class}; + return new Class[] { DisplayItem.class }; } /** @@ -200,8 +200,8 @@ public class FormulaWithColumnTypesTest extends BaseCoreFunctionalTestCase { public ExtendedDialect() { super(); + registerKeyword( "FLOAT" ); registerKeyword( "INTEGER" ); } - } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaWithPartitionByTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaWithPartitionByTest.java new file mode 100644 index 0000000000..0c7a28b6c1 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/formula/FormulaWithPartitionByTest.java @@ -0,0 +1,130 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.orm.test.formula; + +import java.io.Serializable; +import java.util.List; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; + +import org.hibernate.annotations.Formula; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DialectFeatureChecks; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.RequiresDialectFeature; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Vlad Mihalcea + * @author Nathan Xu + */ +@DomainModel( annotatedClasses = FormulaWithPartitionByTest.DisplayItem.class ) +@SessionFactory +@RequiresDialectFeature( jiraKey = "HHH-10754", feature = DialectFeatureChecks.SupportPartitionBy.class ) +public class FormulaWithPartitionByTest { + + @BeforeEach + void setUp(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final DisplayItem displayItem20_1 = new DisplayItem(); + displayItem20_1.setId( 1 ); + displayItem20_1.setDiscountCode( "20" ); + displayItem20_1.setDiscountValue( 12.34d ); + + final DisplayItem displayItem20_2 = new DisplayItem(); + displayItem20_2.setId( 2 ); + displayItem20_2.setDiscountCode( "20" ); + displayItem20_2.setDiscountValue( 15.89 ); + + final DisplayItem displayItem100 = new DisplayItem(); + displayItem100.setId( 3 ); + displayItem100.setDiscountCode( "100" ); + displayItem100.setDiscountValue( 12.5 ); + + session.persist( displayItem20_1 ); + session.persist( displayItem20_2 ); + session.persist( displayItem100 ); + } ); + } + + @Test + @TestForIssue( jiraKey = "HHH-10754" ) + void testFormulaAnnotationWithPartitionBy(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final List displayItems = session.createQuery( "select di from DisplayItem di order by di.id", DisplayItem.class).getResultList(); + + assertNotNull( displayItems ); + assertEquals( 3, displayItems.size() ); + + assertEquals( 1, displayItems.get( 0 ).getItemsByCode().intValue() ); + assertEquals( 2, displayItems.get( 1 ).getItemsByCode().intValue() ); + assertEquals( 1, displayItems.get( 2 ).getItemsByCode().intValue() ); + } ); + } + + @AfterEach + void tearDown(SessionFactoryScope scope) { + scope.inTransaction( session -> session.createQuery( "delete from DisplayItem" ).executeUpdate() ); + } + + @Entity(name = "DisplayItem") + public static class DisplayItem implements Serializable { + + @Id + private Integer id; + + @Column(name = "DISCOUNT_CODE") + private String discountCode; + + @Column(name = "DISCOUNT_VALUE") + private Double discountValue; + + @Formula("ROW_NUMBER() OVER( PARTITION BY DISCOUNT_CODE ORDER BY SIGN(DISCOUNT_VALUE) DESC )") + private Integer itemsByCode; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getDiscountCode() { + return discountCode; + } + + public void setDiscountCode(String discountCode) { + this.discountCode = discountCode; + } + + public Integer getItemsByCode() { + return itemsByCode; + } + + public void setItemsByCode(Integer itemsByCode) { + this.itemsByCode = itemsByCode; + } + + public Double getDiscountValue() { + return discountValue; + } + + public void setDiscountValue(Double discountValue) { + this.discountValue = discountValue; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/formula/FormulaTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/formula/FormulaTests.java new file mode 100644 index 0000000000..b9c4d697f1 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/formula/FormulaTests.java @@ -0,0 +1,133 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.orm.test.metamodel.mapping.formula; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + +import org.hibernate.annotations.Formula; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +/** + * @author Nathan Xu + */ +@DomainModel( + annotatedClasses = { + FormulaTests.Account.class + } +) +@SessionFactory +public class FormulaTests { + + @BeforeEach + void setUp(SessionFactoryScope scope) { + scope.inTransaction( session -> { + Account account = new Account( ); + account.setId( 1L ); + account.setCredit( 5000d ); + account.setRate( 1.25 / 100 ); + session.persist( account ); + } ); + } + + @Test + void testLoader(SessionFactoryScope scope) { + scope.inTransaction( session -> { + Account account = session.find( Account.class, 1L ); + assertThat( account.getInterest(), is( 62.5d )); + } ); + } + + @Test + void testHQL(SessionFactoryScope scope) { + scope.inTransaction( session -> { + Account account = session.createQuery( "select a from Account a where a.id = :id", Account.class ) + .setParameter( "id", 1L ).uniqueResult(); + assertThat( account.getInterest(), is( 62.5d )); + } ); + } + + @Test + void testCriteria(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final CriteriaBuilder criteriaBuilder = scope.getSessionFactory().getCriteriaBuilder(); + final CriteriaQuery criteria = criteriaBuilder.createQuery( Account.class ); + Root root = criteria.from( Account.class ); + criteria.select( root ); + criteria.where( criteriaBuilder.equal( root.get( "id" ), criteriaBuilder.literal( 1L ) ) ); + Account account = session.createQuery( criteria ).uniqueResult(); + assertThat( account.getInterest(), is( 62.5d )); + } ); + } + + @AfterEach + void tearDown(SessionFactoryScope scope) { + scope.inTransaction( session -> { + session.createQuery( "delete from Account" ).executeUpdate(); + } ); + } + + @Entity(name = "Account") + public static class Account { + + @Id + private Long id; + + private Double credit; + + private Double rate; + + @Formula(value = "credit * rate") + private Double interest; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Double getCredit() { + return credit; + } + + public void setCredit(Double credit) { + this.credit = credit; + } + + public Double getRate() { + return rate; + } + + public void setRate(Double rate) { + this.rate = rate; + } + + public Double getInterest() { + return interest; + } + + public void setInterest(Double interest) { + this.interest = interest; + } + + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/manytoone/ManyToOneJoinTableTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/manytoone/ManyToOneJoinTableTest.java index 9dfeee6ed2..2a4bf95e93 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/manytoone/ManyToOneJoinTableTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/manytoone/ManyToOneJoinTableTest.java @@ -56,12 +56,12 @@ public class ManyToOneJoinTableTest { final ToOneAttributeMapping simpleAttributeMapping = (ToOneAttributeMapping) simpleEntityAssociation; ForeignKeyDescriptor foreignKeyDescriptor = simpleAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "other_simple" ) ); assertThat( keyColumn, is( "RHS_ID" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "simple_entity" ) ); assertThat( targetColumn, is( "id" ) ); } ); @@ -73,12 +73,12 @@ public class ManyToOneJoinTableTest { final ToOneAttributeMapping anotherAttributeMapping = (ToOneAttributeMapping) anotherEntityAssociation; foreignKeyDescriptor = anotherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "other_another" ) ); assertThat( keyColumn, is( "RHS_ID" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "another_entity" ) ); assertThat( targetColumn, is( "id" ) ); } ); @@ -95,12 +95,12 @@ public class ManyToOneJoinTableTest { ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) otherEntityEntityAssociation; foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "other_simple" ) ); assertThat( keyColumn, is( "LHS_ID" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "other_entity" ) ); assertThat( targetColumn, is( "id" ) ); } ); @@ -117,12 +117,12 @@ public class ManyToOneJoinTableTest { otherAttributeMapping = (ToOneAttributeMapping) otherEntityEntityAssociation; foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "another_entity" ) ); assertThat( keyColumn, is( "other_id" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "other_entity" ) ); assertThat( targetColumn, is( "id" ) ); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/manytoone/ManyToOneTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/manytoone/ManyToOneTest.java index 69685e96d9..9ba982fa03 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/manytoone/ManyToOneTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/manytoone/ManyToOneTest.java @@ -53,12 +53,12 @@ public class ManyToOneTest { final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) simpleEntityAssociation; ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormua, jdbcMapping) -> { assertThat( keyTable, is( "other_entity" ) ); assertThat( keyColumn, is( "simple_entity_id" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "simple_entity" ) ); assertThat( targetColumn, is( "id" ) ); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithBidirectionalAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithBidirectionalAssociationTest.java index ec387c47c9..682a63336a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithBidirectionalAssociationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithBidirectionalAssociationTest.java @@ -51,12 +51,12 @@ public class EntityWithBidirectionalAssociationTest { final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation; ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "PARENT" ) ); assertThat( keyColumn, is( "child_id" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "CHILD" ) ); assertThat( targetColumn, is( "id" ) ); } ); @@ -72,12 +72,12 @@ public class EntityWithBidirectionalAssociationTest { final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation; foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "PARENT" ) ); assertThat( keyColumn, is( "child_id" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "CHILD" ) ); assertThat( targetColumn, is( "id" ) ); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneBidirectionalJoinTableAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneBidirectionalJoinTableAssociationTest.java index 334bf6a40c..066e9232be 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneBidirectionalJoinTableAssociationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneBidirectionalJoinTableAssociationTest.java @@ -53,12 +53,12 @@ public class EntityWithOneBidirectionalJoinTableAssociationTest { final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation; ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "PARENT_CHILD" ) ); assertThat( keyColumn, is( "child_id" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "CHILD" ) ); assertThat( targetColumn, is( "id" ) ); } ); @@ -74,12 +74,12 @@ public class EntityWithOneBidirectionalJoinTableAssociationTest { final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation; foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "PARENT_CHILD" ) ); assertThat( keyColumn, is( "parent_id" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "PARENT" ) ); assertThat( targetColumn, is( "id" ) ); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneToOneJoinTableTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneToOneJoinTableTest.java index 68acfbc0bb..c905e5aea1 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneToOneJoinTableTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneToOneJoinTableTest.java @@ -47,12 +47,12 @@ public class EntityWithOneToOneJoinTableTest { final ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) other; final ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "Entity_SimpleEntity" ) ); assertThat( keyColumn, is( "other_id" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "SIMPLE_ENTITY" ) ); assertThat( targetColumn, is( "id" ) ); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneToOneSharingPrimaryKeyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneToOneSharingPrimaryKeyTest.java index bdb83975b5..102c2681a8 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneToOneSharingPrimaryKeyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/metamodel/mapping/onetoone/EntityWithOneToOneSharingPrimaryKeyTest.java @@ -48,12 +48,12 @@ public class EntityWithOneToOneSharingPrimaryKeyTest { final ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) otherAssociation; ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); - foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> { assertThat( keyTable, is( "EntityWithOneToOneSharingPrimaryKey" ) ); assertThat( keyColumn, is( "id" ) ); } ); - foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { + foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> { assertThat( targetTable, is( "SIMPLE_ENTITY" ) ); assertThat( targetColumn, is( "id" ) ); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaNativeQueryTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaNativeQueryTest.java deleted file mode 100644 index 6827671f51..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaNativeQueryTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.test.annotations.formula; - -import org.hibernate.annotations.Formula; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.cfg.Configuration; - -import org.hibernate.testing.FailureExpected; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import javax.persistence.*; -import java.util.List; - -import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; -import static org.junit.Assert.assertEquals; - -/** - * @author Алексей Макаров - * @author Gail Badner - */ -@TestForIssue(jiraKey = "HHH-7525") -public class FormulaNativeQueryTest extends BaseCoreFunctionalTestCase { - - // Add your entities here. - @Override - protected Class[] getAnnotatedClasses() { - return new Class[]{ - Foo.class - }; - } - - // Add in any settings that are specific to your test. See resources/hibernate.properties for the defaults. - @Override - protected void configure(Configuration configuration) { - super.configure(configuration); - - configuration.setProperty(AvailableSettings.SHOW_SQL, Boolean.TRUE.toString()); - configuration.setProperty(AvailableSettings.FORMAT_SQL, Boolean.TRUE.toString()); - } - - @Before - public void prepare() { - doInHibernate( - this::sessionFactory, session -> { - session.persist( new Foo( 1, 1 ) ); - session.persist( new Foo( 1, 2 ) ); - session.persist( new Foo( 2, 1 ) ); - } - ); - } - - @After - public void cleanup() { - doInHibernate( - this::sessionFactory, session -> { - session.createQuery( "delete from Foo" ).executeUpdate(); - } - ); - } - - @Test - @FailureExpected( jiraKey = "HHH-7525" ) - public void testNativeQuery() throws Exception { - doInHibernate( - this::sessionFactory, session -> { - Query query = session.createNativeQuery( "SELECT ft.* FROM foo_table ft", Foo.class ); - List list = query.getResultList(); - assertEquals( 3, list.size() ); - } - ); - } - - @Test - public void testHql() throws Exception { - // Show that HQL does work - doInHibernate( - this::sessionFactory, session -> { - Query query = session.createQuery( "SELECT ft FROM Foo ft", Foo.class ); - List list = query.getResultList(); - assertEquals(3, list.size()); - } - ); - } - - @Entity(name = "Foo") - @Table(name = "foo_table") - public static class Foo { - - private int id; - private int locationStart; - private int locationEnd; - private int distance; - - public Foo() { - } - - public Foo(int locationStart, int locationEnd) { - this.locationStart = locationStart; - this.locationEnd = locationEnd; - } - - @Id - @GeneratedValue - public int getId() { - return id; - } - private void setId(int id) { - this.id = id; - } - - public int getLocationStart() { - return locationStart; - } - public void setLocationStart(int locationStart) { - this.locationStart = locationStart; - } - - public int getLocationEnd() { - return locationEnd; - } - public void setLocationEnd(int locationEnd) { - this.locationEnd = locationEnd; - } - - @Formula("abs(locationEnd - locationStart)") - public int getDistance() { - return distance; - } - - public void setDistance(int distance) { - this.distance = distance; - } - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaWithPartitionByTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaWithPartitionByTest.java deleted file mode 100644 index 736d0c909a..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/formula/FormulaWithPartitionByTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.test.annotations.formula; - -import java.io.Serializable; -import java.util.List; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; - -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.hibernate.annotations.Formula; -import org.hibernate.dialect.Oracle8iDialect; -import org.hibernate.dialect.PostgreSQL91Dialect; -import org.hibernate.dialect.SQLServer2005Dialect; - -import org.hibernate.testing.DialectCheck; -import org.hibernate.testing.DialectChecks; -import org.hibernate.testing.RequiresDialect; -import org.hibernate.testing.RequiresDialectFeature; -import org.hibernate.testing.RequiresDialects; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * @author Vlad Mihalcea - */ -@RequiresDialectFeature( jiraKey = "HHH-10754", value = DialectChecks.SupportPartitionBy.class) -public class FormulaWithPartitionByTest extends BaseCoreFunctionalTestCase { - - @Test - @TestForIssue(jiraKey = "HHH-10754") - public void testFormulaAnnotationWithPartitionBy() { - - Session session = openSession(); - Transaction transaction = session.beginTransaction(); - - DisplayItem displayItem20_1 = new DisplayItem(); - displayItem20_1.setId( 1 ); - displayItem20_1.setDiscountCode( "20" ); - displayItem20_1.setDiscountValue( 12.34d ); - - DisplayItem displayItem20_2 = new DisplayItem(); - displayItem20_2.setId( 2 ); - displayItem20_2.setDiscountCode( "20" ); - displayItem20_2.setDiscountValue( 15.89 ); - - DisplayItem displayItem100 = new DisplayItem(); - displayItem100.setId( 3 ); - displayItem100.setDiscountCode( "100" ); - displayItem100.setDiscountValue( 12.5 ); - - session.persist( displayItem20_1 ); - session.persist( displayItem20_2 ); - session.persist( displayItem100 ); - - transaction.commit(); - session.close(); - - session = openSession(); - transaction = session.beginTransaction(); - - List displayItems = session.createQuery( "select di from DisplayItem di order by di.id", DisplayItem.class).getResultList(); - - assertNotNull( displayItems ); - assertEquals( displayItems.size(), 3 ); - - assertEquals( 1, displayItems.get( 0 ).getItemsByCode().intValue() ); - assertEquals( 2, displayItems.get( 1 ).getItemsByCode().intValue() ); - assertEquals( 1, displayItems.get( 2 ).getItemsByCode().intValue() ); - - transaction.commit(); - session.close(); - } - - @Override - public Class[] getAnnotatedClasses() { - return new Class[] {DisplayItem.class}; - } - - @Entity(name = "DisplayItem") - public static class DisplayItem implements Serializable { - - @Id - private Integer id; - - @Column(name = "DISCOUNT_CODE") - private String discountCode; - - @Column(name = "DISCOUNT_VALUE") - private Double discountValue; - - @Formula("ROW_NUMBER() OVER( PARTITION BY DISCOUNT_CODE ORDER BY SIGN(DISCOUNT_VALUE) DESC )") - private Integer itemsByCode; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getDiscountCode() { - return discountCode; - } - - public void setDiscountCode(String discountCode) { - this.discountCode = discountCode; - } - - public Integer getItemsByCode() { - return itemsByCode; - } - - public void setItemsByCode(Integer itemsByCode) { - this.itemsByCode = itemsByCode; - } - - public Double getDiscountValue() { - return discountValue; - } - - public void setDiscountValue(Double discountValue) { - this.discountValue = discountValue; - } - } -}