implement @Formula

This commit is contained in:
Nathan Xu 2020-04-25 16:32:15 -04:00 committed by Steve Ebersole
parent e10992e4fc
commit 40575125f1
55 changed files with 812 additions and 462 deletions

View File

@ -99,7 +99,7 @@ class DatabaseSnapshotExecutor {
final List<DomainResult> domainResults = new ArrayList<>(); final List<DomainResult> domainResults = new ArrayList<>();
entityDescriptor.getIdentifierMapping().visitColumns( entityDescriptor.getIdentifierMapping().visitColumns(
(tab, col, jdbcMapping) -> { (tab, col, isColFormula, jdbcMapping) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference( tab ); final TableReference tableReference = rootTableGroup.resolveTableReference( tab );
final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping ); final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping );
@ -111,6 +111,7 @@ class DatabaseSnapshotExecutor {
s -> new ColumnReference( s -> new ColumnReference(
tableReference, tableReference,
col, col,
isColFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )
@ -145,7 +146,7 @@ class DatabaseSnapshotExecutor {
contributorMapping -> { contributorMapping -> {
rootPath.append( contributorMapping.getAttributeName() ); rootPath.append( contributorMapping.getAttributeName() );
contributorMapping.visitColumns( contributorMapping.visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference( final TableReference tableReference = rootTableGroup.resolveTableReference(
containingTableExpression ); containingTableExpression );
@ -158,6 +159,7 @@ class DatabaseSnapshotExecutor {
s -> new ColumnReference( s -> new ColumnReference(
tableReference, tableReference,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )

View File

@ -327,6 +327,7 @@ public class LoaderSelectBuilder {
p -> new ColumnReference( p -> new ColumnReference(
tableReference, tableReference,
columnExpression, columnExpression,
false,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
) )
@ -356,7 +357,7 @@ public class LoaderSelectBuilder {
final List<ColumnReference> columnReferences = new ArrayList<>( numberOfKeyColumns ); final List<ColumnReference> columnReferences = new ArrayList<>( numberOfKeyColumns );
keyPart.visitColumns( keyPart.visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference( containingTableExpression ); final TableReference tableReference = rootTableGroup.resolveTableReference( containingTableExpression );
columnReferences.add( columnReferences.add(
(ColumnReference) sqlExpressionResolver.resolveSqlExpression( (ColumnReference) sqlExpressionResolver.resolveSqlExpression(
@ -364,6 +365,7 @@ public class LoaderSelectBuilder {
p -> new ColumnReference( p -> new ColumnReference(
tableReference, tableReference,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
) )
@ -683,6 +685,7 @@ public class LoaderSelectBuilder {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
rootTableGroup.resolveTableReference( simpleFkDescriptor.getContainingTableExpression() ), rootTableGroup.resolveTableReference( simpleFkDescriptor.getContainingTableExpression() ),
simpleFkDescriptor.getMappedColumnExpression(), simpleFkDescriptor.getMappedColumnExpression(),
false,
simpleFkDescriptor.getJdbcMapping(), simpleFkDescriptor.getJdbcMapping(),
this.creationContext.getSessionFactory() this.creationContext.getSessionFactory()
) )
@ -691,13 +694,14 @@ public class LoaderSelectBuilder {
else { else {
final List<ColumnReference> columnReferences = new ArrayList<>( jdbcTypeCount ); final List<ColumnReference> columnReferences = new ArrayList<>( jdbcTypeCount );
fkDescriptor.visitColumns( fkDescriptor.visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) ->
columnReferences.add( columnReferences.add(
(ColumnReference) sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression( (ColumnReference) sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
createColumnReferenceKey( containingTableExpression, columnExpression ), createColumnReferenceKey( containingTableExpression, columnExpression ),
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
rootTableGroup.resolveTableReference( containingTableExpression ), rootTableGroup.resolveTableReference( containingTableExpression ),
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
this.creationContext.getSessionFactory() this.creationContext.getSessionFactory()
) )
@ -747,7 +751,7 @@ public class LoaderSelectBuilder {
final MutableInteger count = new MutableInteger(); final MutableInteger count = new MutableInteger();
fkDescriptor.visitTargetColumns( fkDescriptor.visitTargetColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
// for each column, resolve a SqlSelection and add it to the sub-query select-clause // for each column, resolve a SqlSelection and add it to the sub-query select-clause
final TableReference tableReference = ownerTableGroup.resolveTableReference( containingTableExpression ); final TableReference tableReference = ownerTableGroup.resolveTableReference( containingTableExpression );
final Expression expression = sqlExpressionResolver.resolveSqlExpression( final Expression expression = sqlExpressionResolver.resolveSqlExpression(
@ -755,6 +759,7 @@ public class LoaderSelectBuilder {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference, tableReference,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )

View File

@ -24,6 +24,10 @@ public interface BasicValuedModelPart extends BasicValuedMapping, ModelPart, Fet
*/ */
String getMappedColumnExpression(); String getMappedColumnExpression();
default boolean isMappedColumnExpressionFormula() {
return false;
}
@Override @Override
default MappingType getPartMappingType() { default MappingType getPartMappingType() {
return this::getJavaTypeDescriptor; return this::getJavaTypeDescriptor;

View File

@ -15,5 +15,6 @@ public interface ColumnConsumer {
void accept( void accept(
String containingTableExpression, String containingTableExpression,
String columnExpression, String columnExpression,
boolean isColumnExpressionFormula,
JdbcMapping jdbcMapping); JdbcMapping jdbcMapping);
} }

View File

@ -177,6 +177,7 @@ public class EmbeddableMappingType implements ManagedMappingType {
(BasicType) subtype, (BasicType) subtype,
containingTableExpression, containingTableExpression,
mappedColumnExpressions.get( columnPosition++ ), mappedColumnExpressions.get( columnPosition++ ),
false,
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ), representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
compositeType.getCascadeStyle( attributeIndex ), compositeType.getCascadeStyle( attributeIndex ),
creationProcess creationProcess

View File

@ -34,6 +34,7 @@ public class MappingModelHelper {
return new ColumnReference( return new ColumnReference(
basicPart.getContainingTableExpression(), basicPart.getContainingTableExpression(),
basicPart.getMappedColumnExpression(), basicPart.getMappedColumnExpression(),
basicPart.isMappedColumnExpressionFormula(),
basicPart.getJdbcMapping(), basicPart.getJdbcMapping(),
sessionFactory sessionFactory
); );
@ -44,6 +45,7 @@ public class MappingModelHelper {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
basicPart.getContainingTableExpression(), basicPart.getContainingTableExpression(),
basicPart.getMappedColumnExpression(), basicPart.getMappedColumnExpression(),
basicPart.isMappedColumnExpressionFormula(),
basicPart.getJdbcMapping(), basicPart.getJdbcMapping(),
sessionFactory sessionFactory
) )
@ -53,12 +55,13 @@ public class MappingModelHelper {
else { else {
final List<ColumnReference> columnReferences = new ArrayList<>( jdbcTypeCount ); final List<ColumnReference> columnReferences = new ArrayList<>( jdbcTypeCount );
modelPart.visitColumns( modelPart.visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
final ColumnReference colRef; final ColumnReference colRef;
if ( sqlExpressionResolver == null ) { if ( sqlExpressionResolver == null ) {
colRef = new ColumnReference( colRef = new ColumnReference(
containingTableExpression, containingTableExpression,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
); );
@ -69,6 +72,7 @@ public class MappingModelHelper {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
containingTableExpression, containingTableExpression,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )

View File

@ -125,7 +125,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
@Override @Override
public void visitColumns(ColumnConsumer consumer) { public void visitColumns(ColumnConsumer consumer) {
consumer.accept( getContainingTableExpression(), getMappedColumnExpression(), getJdbcMapping() ); consumer.accept( getContainingTableExpression(), getMappedColumnExpression(), false, getJdbcMapping() );
} }
@Override @Override
@ -190,6 +190,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
rootTableReference.getIdentificationVariable(), rootTableReference.getIdentificationVariable(),
pkColumnName, pkColumnName,
false,
( (BasicValuedMapping) entityPersister.getIdentifierType() ).getJdbcMapping(), ( (BasicValuedMapping) entityPersister.getIdentifierType() ).getJdbcMapping(),
sessionFactory sessionFactory
) )
@ -224,6 +225,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
rootTable, rootTable,
pkColumnName, pkColumnName,
false,
( (BasicValuedModelPart) entityPersister.getIdentifierType() ).getJdbcMapping(), ( (BasicValuedModelPart) entityPersister.getIdentifierType() ).getJdbcMapping(),
sessionFactory sessionFactory
) )

View File

@ -131,6 +131,7 @@ public class BasicValuedCollectionPart
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableGroup.getPrimaryTableReference().getIdentificationVariable(), tableGroup.getPrimaryTableReference().getIdentificationVariable(),
columnExpression, columnExpression,
false,
mapper, mapper,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
) )

View File

@ -9,9 +9,11 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchTiming; import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ColumnConsumer; import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.ConvertibleModelPart; 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.metamodel.model.domain.NavigableRole;
import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.sql.Template;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlAstCreationState; import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.spi.SqlExpressionResolver;
@ -50,6 +53,7 @@ public class BasicValuedSingularAttributeMapping
private final NavigableRole navigableRole; private final NavigableRole navigableRole;
private final String tableExpression; private final String tableExpression;
private final String mappedColumnExpression; private final String mappedColumnExpression;
private final boolean isMappedColumnExpressionFormula;
private final JdbcMapping jdbcMapping; private final JdbcMapping jdbcMapping;
private final BasicValueConverter valueConverter; private final BasicValueConverter valueConverter;
@ -65,6 +69,7 @@ public class BasicValuedSingularAttributeMapping
FetchStrategy mappedFetchStrategy, FetchStrategy mappedFetchStrategy,
String tableExpression, String tableExpression,
String mappedColumnExpression, String mappedColumnExpression,
boolean isMappedColumnExpressionFormula,
BasicValueConverter valueConverter, BasicValueConverter valueConverter,
JdbcMapping jdbcMapping, JdbcMapping jdbcMapping,
ManagedMappingType declaringType, ManagedMappingType declaringType,
@ -73,6 +78,7 @@ public class BasicValuedSingularAttributeMapping
this.navigableRole = navigableRole; this.navigableRole = navigableRole;
this.tableExpression = tableExpression; this.tableExpression = tableExpression;
this.mappedColumnExpression = mappedColumnExpression; this.mappedColumnExpression = mappedColumnExpression;
this.isMappedColumnExpressionFormula = isMappedColumnExpressionFormula;
this.valueConverter = valueConverter; this.valueConverter = valueConverter;
this.jdbcMapping = jdbcMapping; this.jdbcMapping = jdbcMapping;
@ -104,6 +110,11 @@ public class BasicValuedSingularAttributeMapping
return mappedColumnExpression; return mappedColumnExpression;
} }
@Override
public boolean isMappedColumnExpressionFormula() {
return isMappedColumnExpressionFormula;
}
@Override @Override
public String getContainingTableExpression() { public String getContainingTableExpression() {
return tableExpression; return tableExpression;
@ -142,15 +153,18 @@ public class BasicValuedSingularAttributeMapping
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() ); final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
final String tableAlias = tableReference.getIdentificationVariable();
final String columnExpression = getMappedColumnExpression();
return expressionResolver.resolveSqlSelection( return expressionResolver.resolveSqlSelection(
expressionResolver.resolveSqlExpression( expressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( SqlExpressionResolver.createColumnReferenceKey(
tableReference, tableReference,
getMappedColumnExpression() columnExpression
), ),
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(), tableAlias,
getMappedColumnExpression(), columnExpression,
isMappedColumnExpressionFormula(),
jdbcMapping, jdbcMapping,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
) )
@ -179,6 +193,7 @@ public class BasicValuedSingularAttributeMapping
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(), tableReference.getIdentificationVariable(),
getMappedColumnExpression(), getMappedColumnExpression(),
isMappedColumnExpressionFormula(),
jdbcMapping, jdbcMapping,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
) )
@ -246,6 +261,6 @@ public class BasicValuedSingularAttributeMapping
@Override @Override
public void visitColumns(ColumnConsumer consumer) { public void visitColumns(ColumnConsumer consumer) {
consumer.accept( tableExpression, mappedColumnExpression, jdbcMapping ); consumer.accept( tableExpression, mappedColumnExpression, isMappedColumnExpressionFormula, jdbcMapping );
} }
} }

View File

@ -138,6 +138,7 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD
p -> new ColumnReference( p -> new ColumnReference(
tableGroup.getPrimaryTableReference().getIdentificationVariable(), tableGroup.getPrimaryTableReference().getIdentificationVariable(),
columnName, columnName,
false,
type, type,
sessionFactory sessionFactory
) )
@ -176,6 +177,7 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD
p -> new ColumnReference( p -> new ColumnReference(
tableGroup.getPrimaryTableReference().getIdentificationVariable(), tableGroup.getPrimaryTableReference().getIdentificationVariable(),
columnName, columnName,
false,
type, type,
sessionFactory sessionFactory
) )

View File

@ -217,6 +217,7 @@ public class EmbeddedAttributeMapping
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(), tableReference.getIdentificationVariable(),
attrColumnExpr, attrColumnExpr,
false,
jdbcMapping, jdbcMapping,
sqlAstCreationState.getCreationContext().getSessionFactory() sqlAstCreationState.getCreationContext().getSessionFactory()
) )

View File

@ -177,7 +177,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
final List<Expression> expressions = new ArrayList<>(); final List<Expression> expressions = new ArrayList<>();
getEmbeddableTypeDescriptor().visitColumns( getEmbeddableTypeDescriptor().visitColumns(
(tableExpression, columnExpression, jdbcMapping) ->{ (tableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) ->{
assert containingTableExpression.equals( tableExpression ); assert containingTableExpression.equals( tableExpression );
assert columnExpressions.contains( columnExpression ); assert columnExpressions.contains( columnExpression );
expressions.add( expressions.add(
@ -186,6 +186,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableGroup.resolveTableReference( tableExpression ), tableGroup.resolveTableReference( tableExpression ),
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sqlAstCreationState.getCreationContext().getSessionFactory() sqlAstCreationState.getCreationContext().getSessionFactory()
) )

View File

@ -118,6 +118,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
new ColumnReference( new ColumnReference(
identificationVariable, identificationVariable,
columnExpression, columnExpression,
false,
jdbcMapping, jdbcMapping,
creationState.getSqlAstCreationState() creationState.getSqlAstCreationState()
.getCreationContext() .getCreationContext()
@ -169,6 +170,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
new ColumnReference( new ColumnReference(
identificationVariable, identificationVariable,
columnExpression, columnExpression,
false,
jdbcMapping, jdbcMapping,
creationState.getSqlAstCreationState() creationState.getSqlAstCreationState()
.getCreationContext() .getCreationContext()
@ -260,6 +262,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
new ColumnReference( new ColumnReference(
lhs, lhs,
lhsExpressions.get( i ), lhsExpressions.get( i ),
false,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
), ),
@ -267,6 +270,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
new ColumnReference( new ColumnReference(
rhs, rhs,
rhsColumnExpressions.get( i ), rhsColumnExpressions.get( i ),
false,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
) )
@ -312,14 +316,14 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
@Override @Override
public void visitReferringColumns(ColumnConsumer consumer) { public void visitReferringColumns(ColumnConsumer consumer) {
for ( int i = 0; i < keyColumnExpressions.size(); i++ ) { 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 @Override
public void visitTargetColumns(ColumnConsumer consumer) { public void visitTargetColumns(ColumnConsumer consumer) {
for ( int i = 0; i < keyColumnExpressions.size(); i++ ) { 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 ) );
} }
} }

View File

@ -227,6 +227,7 @@ public class EmbeddedIdentifierMappingImpl
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(), tableReference.getIdentificationVariable(),
attrColumnExpr, attrColumnExpr,
false,
jdbcMapping, jdbcMapping,
sqlAstCreationState.getCreationContext().getSessionFactory() sqlAstCreationState.getCreationContext().getSessionFactory()
) )

View File

@ -49,6 +49,7 @@ public class EntityDiscriminatorMappingImpl extends AbstractEntityDiscriminatorM
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(), tableReference.getIdentificationVariable(),
getMappedColumnExpression(), getMappedColumnExpression(),
false,
getJdbcMapping(), getJdbcMapping(),
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
) )

View File

@ -87,6 +87,7 @@ public class EntityRowIdMappingImpl implements EntityRowIdMapping {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
columnTableReference, columnTableReference,
rowIdName, rowIdName,
false,
JavaObjectType.INSTANCE, JavaObjectType.INSTANCE,
sqlAstCreationState.getCreationContext().getSessionFactory() sqlAstCreationState.getCreationContext().getSessionFactory()
) )

View File

@ -142,6 +142,7 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
columnTableReference, columnTableReference,
columnExpression, columnExpression,
false,
versionBasicType, versionBasicType,
sqlAstCreationState.getCreationContext().getSessionFactory() sqlAstCreationState.getCreationContext().getSessionFactory()
) )
@ -179,6 +180,7 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
columnTableReference, columnTableReference,
columnExpression, columnExpression,
false,
versionBasicType, versionBasicType,
sqlAstCreationState.getCreationContext().getSessionFactory() sqlAstCreationState.getCreationContext().getSessionFactory()
) )

View File

@ -204,6 +204,7 @@ public class MappingModelCreationHelper {
(BasicType) idSubPropertyType, (BasicType) idSubPropertyType,
rootTableName, rootTableName,
rootTableKeyColumnNames[columnsConsumedSoFar], rootTableKeyColumnNames[columnsConsumedSoFar],
false,
entityPersister.getRepresentationStrategy().resolvePropertyAccess( bootIdSubProperty ), entityPersister.getRepresentationStrategy().resolvePropertyAccess( bootIdSubProperty ),
CascadeStyles.ALL, CascadeStyles.ALL,
creationProcess creationProcess
@ -272,6 +273,7 @@ public class MappingModelCreationHelper {
BasicType attrType, BasicType attrType,
String tableExpression, String tableExpression,
String attrColumnName, String attrColumnName,
boolean isAttrFormula,
PropertyAccess propertyAccess, PropertyAccess propertyAccess,
CascadeStyle cascadeStyle, CascadeStyle cascadeStyle,
MappingModelCreationProcess creationProcess) { MappingModelCreationProcess creationProcess) {
@ -333,6 +335,15 @@ public class MappingModelCreationHelper {
: FetchStrategy.IMMEDIATE_JOIN; : FetchStrategy.IMMEDIATE_JOIN;
if ( valueConverter != null ) { 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 // we want to "decompose" the "type" into its various pieces as expected by the mapping
assert valueConverter.getRelationalJavaDescriptor() == resolution.getRelationalJavaDescriptor(); assert valueConverter.getRelationalJavaDescriptor() == resolution.getRelationalJavaDescriptor();
@ -354,6 +365,7 @@ public class MappingModelCreationHelper {
fetchStrategy, fetchStrategy,
tableExpression, tableExpression,
attrColumnName, attrColumnName,
false,
valueConverter, valueConverter,
mappingBasicType.getJdbcMapping(), mappingBasicType.getJdbcMapping(),
declaringType, declaringType,
@ -369,6 +381,7 @@ public class MappingModelCreationHelper {
fetchStrategy, fetchStrategy,
tableExpression, tableExpression,
attrColumnName, attrColumnName,
isAttrFormula,
null, null,
attrType, attrType,
declaringType, declaringType,

View File

@ -89,6 +89,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
new ColumnReference( new ColumnReference(
identificationVariable, identificationVariable,
targetColumnExpression, targetColumnExpression,
false,
jdbcMapping, jdbcMapping,
creationState.getSqlAstCreationState() creationState.getSqlAstCreationState()
.getCreationContext() .getCreationContext()
@ -139,6 +140,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
new ColumnReference( new ColumnReference(
identificationVariable, identificationVariable,
keyColumnExpression, keyColumnExpression,
false,
jdbcMapping, jdbcMapping,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory() creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
) )
@ -167,6 +169,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
new ColumnReference( new ColumnReference(
lhs, lhs,
keyColumnExpression, keyColumnExpression,
false,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
), ),
@ -174,6 +177,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
new ColumnReference( new ColumnReference(
rhs, rhs,
targetColumnExpression, targetColumnExpression,
false,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
) )
@ -184,6 +188,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
new ColumnReference( new ColumnReference(
lhs, lhs,
targetColumnExpression, targetColumnExpression,
false,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
), ),
@ -191,6 +196,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
new ColumnReference( new ColumnReference(
rhs, rhs,
keyColumnExpression, keyColumnExpression,
false,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
) )
@ -285,12 +291,12 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
@Override @Override
public void visitReferringColumns(ColumnConsumer consumer) { public void visitReferringColumns(ColumnConsumer consumer) {
consumer.accept( keyColumnContainingTable, keyColumnExpression, jdbcMapping ); consumer.accept( keyColumnContainingTable, keyColumnExpression, false, jdbcMapping );
} }
@Override @Override
public void visitTargetColumns(ColumnConsumer consumer) { public void visitTargetColumns(ColumnConsumer consumer) {
consumer.accept( targetColumnContainingTable, targetColumnExpression, jdbcMapping ); consumer.accept( targetColumnContainingTable, targetColumnExpression, false, jdbcMapping );
} }
@Override @Override

View File

@ -26,10 +26,12 @@ import org.hibernate.sql.ast.tree.select.SortSpecification;
*/ */
public class ColumnReference implements OrderingExpression, SequencePart { public class ColumnReference implements OrderingExpression, SequencePart {
private final String columnExpression; private final String columnExpression;
private final boolean isColumnExpressionFormula;
private final NavigablePath rootPath; private final NavigablePath rootPath;
public ColumnReference(String columnExpression, NavigablePath rootPath) { public ColumnReference(String columnExpression, boolean isColumnExpressionFormula, NavigablePath rootPath) {
this.columnExpression = columnExpression; this.columnExpression = columnExpression;
this.isColumnExpressionFormula = isColumnExpressionFormula;
this.rootPath = rootPath; this.rootPath = rootPath;
} }
@ -37,6 +39,10 @@ public class ColumnReference implements OrderingExpression, SequencePart {
return columnExpression; return columnExpression;
} }
public boolean isColumnExpressionFormula() {
return isColumnExpressionFormula;
}
@Override @Override
public SequencePart resolvePathPart( public SequencePart resolvePathPart(
String name, String name,
@ -63,6 +69,7 @@ public class ColumnReference implements OrderingExpression, SequencePart {
sqlAstProcessingState -> new org.hibernate.sql.ast.tree.expression.ColumnReference( sqlAstProcessingState -> new org.hibernate.sql.ast.tree.expression.ColumnReference(
tableGroup.getPrimaryTableReference(), tableGroup.getPrimaryTableReference(),
columnExpression, columnExpression,
isColumnExpressionFormula,
// because these ordering fragments are only ever part of the order-by clause, there // because these ordering fragments are only ever part of the order-by clause, there
// is no need for the JdbcMapping // is no need for the JdbcMapping
null, null,

View File

@ -58,6 +58,7 @@ public interface DomainPath extends OrderingExpression, SequencePart {
new ColumnReference( new ColumnReference(
tableReference, tableReference,
basicValuedPart.getMappedColumnExpression(), basicValuedPart.getMappedColumnExpression(),
basicValuedPart.isMappedColumnExpressionFormula(),
basicValuedPart.getJdbcMapping(), basicValuedPart.getJdbcMapping(),
creationState.getCreationContext().getSessionFactory() creationState.getCreationContext().getSessionFactory()
), ),
@ -68,7 +69,7 @@ public interface DomainPath extends OrderingExpression, SequencePart {
} }
else { else {
getReferenceModelPart().visitColumns( getReferenceModelPart().visitColumns(
(tableExpression, columnExpression, jdbcMapping) -> { (tableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
final TableReference tableReference = tableGroup.resolveTableReference( tableExpression ); final TableReference tableReference = tableGroup.resolveTableReference( tableExpression );
ast.addSortSpecification( ast.addSortSpecification(
new SortSpecification( new SortSpecification(
@ -80,6 +81,7 @@ public interface DomainPath extends OrderingExpression, SequencePart {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference, tableReference,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )

View File

@ -37,7 +37,7 @@ public class RootSequencePart implements SequencePart {
if ( isTerminal ) { if ( isTerminal ) {
// assume a column-reference // assume a column-reference
return new ColumnReference( name, pluralAttributePath.getNavigablePath() ); return new ColumnReference( name, false, pluralAttributePath.getNavigablePath() );
} }
throw new PathResolutionException( throw new PathResolutionException(

View File

@ -122,7 +122,6 @@ import org.hibernate.loader.entity.CacheEntityLoaderHelper;
import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.Formula;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass; import org.hibernate.mapping.RootClass;
@ -824,7 +823,8 @@ public abstract class AbstractEntityPersister
colAliases[k] = thing.getAlias( dialect, prop.getValue().getTable() ); colAliases[k] = thing.getAlias( dialect, prop.getValue().getTable() );
if ( thing.isFormula() ) { if ( thing.isFormula() ) {
foundFormula = true; 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() ); formulaTemplates[k] = thing.getTemplate( dialect, factory.getQueryEngine().getSqmFunctionRegistry() );
} }
else { else {
@ -1406,6 +1406,7 @@ public abstract class AbstractEntityPersister
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
rootTableReference.getIdentificationVariable(), rootTableReference.getIdentificationVariable(),
rootPkColumnName, rootPkColumnName,
false,
jdbcMapping, jdbcMapping,
getFactory() getFactory()
) )
@ -1420,6 +1421,7 @@ public abstract class AbstractEntityPersister
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
joinedTableReference.getIdentificationVariable(), joinedTableReference.getIdentificationVariable(),
fkColumnName, fkColumnName,
false,
jdbcMapping, jdbcMapping,
getFactory() getFactory()
) )
@ -6143,6 +6145,7 @@ public abstract class AbstractEntityPersister
(BasicType) attrType, (BasicType) attrType,
tableExpression, tableExpression,
attrColumnNames[0], attrColumnNames[0],
false,
propertyAccess, propertyAccess,
tupleAttrDefinition.getCascadeStyle(), tupleAttrDefinition.getCascadeStyle(),
creationProcess creationProcess
@ -6150,6 +6153,17 @@ public abstract class AbstractEntityPersister
} }
if ( attrType instanceof BasicType ) { 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( return MappingModelCreationHelper.buildBasicAttributeMapping(
attrName, attrName,
getNavigableRole().append( bootProperty.getName() ), getNavigableRole().append( bootProperty.getName() ),
@ -6158,7 +6172,8 @@ public abstract class AbstractEntityPersister
this, this,
(BasicType) attrType, (BasicType) attrType,
tableExpression, tableExpression,
attrColumnNames[0], attrColumnExpression,
isAttrColumnExpressionFormula,
propertyAccess, propertyAccess,
tupleAttrDefinition.getCascadeStyle(), tupleAttrDefinition.getCascadeStyle(),
creationProcess creationProcess

View File

@ -33,6 +33,7 @@ import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.DynamicFilterAliasGenerator; import org.hibernate.internal.DynamicFilterAliasGenerator;
import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.TableGroupFilterAliasGenerator;
import org.hibernate.internal.util.MarkerObject; import org.hibernate.internal.util.MarkerObject;
import org.hibernate.internal.util.MutableInteger; import org.hibernate.internal.util.MutableInteger;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
@ -1272,7 +1273,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
() -> columnConsumer -> { () -> columnConsumer -> {
final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition]; final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition];
for ( String column : keyColumnNames ) { 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( return new ColumnReference(
tableReference.getIdentificationVariable(), tableReference.getIdentificationVariable(),
discriminatorColumnNameByTableName.get( tableReference.getTableExpression() ), discriminatorColumnNameByTableName.get( tableReference.getTableExpression() ),
false,
jdbcMappings.get( 0 ), jdbcMappings.get( 0 ),
getFactory() getFactory()
); );

View File

@ -928,6 +928,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableGroup.getPrimaryTableReference().getIdentificationVariable(), tableGroup.getPrimaryTableReference().getIdentificationVariable(),
getDiscriminatorColumnName(), getDiscriminatorColumnName(),
false,
( (BasicType) getDiscriminatorType() ).getJdbcMapping(), ( (BasicType) getDiscriminatorType() ).getJdbcMapping(),
getFactory() getFactory()
) )
@ -952,7 +953,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
() -> columnConsumer -> { () -> columnConsumer -> {
final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition]; final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition];
for ( String column : keyColumnNames ) { for ( String column : keyColumnNames ) {
columnConsumer.accept( tableName, column, null ); columnConsumer.accept( tableName, column, false,null );
} }
} }
); );

View File

@ -389,7 +389,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
() -> columnConsumer -> { () -> columnConsumer -> {
final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition]; final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition];
for ( String column : keyColumnNames ) { for ( String column : keyColumnNames ) {
columnConsumer.accept( tableName, column, null ); columnConsumer.accept( tableName, column, false, null );
} }
} }
); );

View File

@ -80,7 +80,7 @@ public class MatchingIdSelectionHelper {
final List<DomainResult> domainResults = new ArrayList<>(); final List<DomainResult> domainResults = new ArrayList<>();
final MutableInteger i = new MutableInteger(); final MutableInteger i = new MutableInteger();
targetEntityDescriptor.getIdentifierMapping().visitColumns( targetEntityDescriptor.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
final int position = i.getAndIncrement(); final int position = i.getAndIncrement();
final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression ); final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression );
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression( final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
@ -88,6 +88,7 @@ public class MatchingIdSelectionHelper {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference, tableReference,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )
@ -141,7 +142,7 @@ public class MatchingIdSelectionHelper {
final MutableInteger i = new MutableInteger(); final MutableInteger i = new MutableInteger();
targetEntityDescriptor.getIdentifierMapping().visitColumns( targetEntityDescriptor.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
final int position = i.getAndIncrement(); final int position = i.getAndIncrement();
final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression ); final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression );
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression( final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
@ -149,6 +150,7 @@ public class MatchingIdSelectionHelper {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference, tableReference,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )

View File

@ -221,10 +221,11 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele
final List<ColumnReference> columnsToMatchReferences = new ArrayList<>(); final List<ColumnReference> columnsToMatchReferences = new ArrayList<>();
columnsToMatchVisitationSupplier.get().accept( columnsToMatchVisitationSupplier.get().accept(
(containingTableExpression, columnExpression, jdbcMapping) -> columnsToMatchReferences.add( (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> columnsToMatchReferences.add(
new ColumnReference( new ColumnReference(
targetTableReference, targetTableReference,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )

View File

@ -76,7 +76,7 @@ public final class ExecuteWithIdTableHelper {
for ( int i = 0; i < idTable.getIdTableColumns().size(); i++ ) { for ( int i = 0; i < idTable.getIdTableColumns().size(); i++ ) {
final IdTableColumn column = idTable.getIdTableColumns().get( i ); final IdTableColumn column = idTable.getIdTableColumns().get( i );
idTableInsert.addTargetColumnReferences( 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(); final MutableInteger positionWrapper = new MutableInteger();
mutatingEntityDescriptor.getIdentifierMapping().visitColumns( mutatingEntityDescriptor.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
final int jdbcPosition = positionWrapper.getAndIncrement(); final int jdbcPosition = positionWrapper.getAndIncrement();
final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression ); final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression );
matchingIdSelection.getSelectClause().addSqlSelection( matchingIdSelection.getSelectClause().addSqlSelection(
@ -100,6 +100,7 @@ public final class ExecuteWithIdTableHelper {
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
tableReference, tableReference,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
factory factory
) )
@ -190,6 +191,7 @@ public final class ExecuteWithIdTableHelper {
new ColumnReference( new ColumnReference(
tableReference, tableReference,
idTableColumn.getColumnName(), idTableColumn.getColumnName(),
false,
idTableColumn.getJdbcMapping(), idTableColumn.getJdbcMapping(),
executionContext.getSession().getFactory() executionContext.getSession().getFactory()
) )
@ -211,6 +213,7 @@ public final class ExecuteWithIdTableHelper {
new ColumnReference( new ColumnReference(
idTableReference, idTableReference,
idTable.getSessionUidColumn().getColumnName(), idTable.getSessionUidColumn().getColumnName(),
false,
idTable.getSessionUidColumn().getJdbcMapping(), idTable.getSessionUidColumn().getJdbcMapping(),
executionContext.getSession().getFactory() executionContext.getSession().getFactory()
), ),

View File

@ -53,12 +53,13 @@ public final class ExecuteWithoutIdTableHelper {
matchingIdSelect.getFromClause().addRoot( matchingIdSelectTableGroup ); matchingIdSelect.getFromClause().addRoot( matchingIdSelectTableGroup );
rootEntityPersister.getIdentifierMapping().visitColumns( rootEntityPersister.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
final ColumnReference columnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression( final ColumnReference columnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, columnExpression ), SqlExpressionResolver.createColumnReferenceKey( rootTableReference, columnExpression ),
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
rootTableReference, rootTableReference,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )

View File

@ -34,7 +34,7 @@ public class IdTable implements Exportable {
); );
entityDescriptor.getIdentifierMapping().visitColumns( entityDescriptor.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> columns.add( (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> columns.add(
new IdTableColumn( new IdTableColumn(
this, this,
columnExpression, columnExpression,

View File

@ -285,7 +285,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
*/ */
final List<ColumnReference> deletingTableColumnRefs = new ArrayList<>(); final List<ColumnReference> deletingTableColumnRefs = new ArrayList<>();
tableKeyColumnVisitationSupplier.get().accept( tableKeyColumnVisitationSupplier.get().accept(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
assert targetTableReference.getTableExpression().equals( containingTableExpression ); assert targetTableReference.getTableExpression().equals( containingTableExpression );
final Expression expression = sqlExpressionResolver.resolveSqlExpression( final Expression expression = sqlExpressionResolver.resolveSqlExpression(
@ -293,6 +293,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
sqlAstProcessingState -> new ColumnReference( sqlAstProcessingState -> new ColumnReference(
rootTableGroup.getPrimaryTableReference(), rootTableGroup.getPrimaryTableReference(),
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )
@ -456,12 +457,13 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector( entityDescriptor ); final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector( entityDescriptor );
tableKeyColumnVisitationSupplier.get().accept( tableKeyColumnVisitationSupplier.get().accept(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
assert containingTableExpression.equals( tableExpression ); assert containingTableExpression.equals( tableExpression );
keyColumnCollector.apply( keyColumnCollector.apply(
new ColumnReference( new ColumnReference(
(String) null, (String) null,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
factory factory
) )

View File

@ -236,12 +236,13 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector( entityDescriptor ); final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector( entityDescriptor );
tableKeyColumnVisitationSupplier.get().accept( tableKeyColumnVisitationSupplier.get().accept(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
assert containingTableExpression.equals( tableExpression ); assert containingTableExpression.equals( tableExpression );
keyColumnCollector.apply( keyColumnCollector.apply(
new ColumnReference( new ColumnReference(
(String) null, (String) null,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
sessionFactory sessionFactory
) )

View File

@ -67,6 +67,7 @@ public class DisjunctionRestrictionProducer implements MatchingIdRestrictionProd
final ColumnReference idColumnReference = new ColumnReference( final ColumnReference idColumnReference = new ColumnReference(
mutatingTableReference, mutatingTableReference,
idColumn, idColumn,
false,
basicIdMapping.getJdbcMapping(), basicIdMapping.getJdbcMapping(),
sessionFactory sessionFactory
); );
@ -88,8 +89,8 @@ public class DisjunctionRestrictionProducer implements MatchingIdRestrictionProd
final List<ColumnReference> columnReferences = new ArrayList<>( idColumnCount ); final List<ColumnReference> columnReferences = new ArrayList<>( idColumnCount );
final List<JdbcMapping> jdbcMappings = new ArrayList<>( idColumnCount ); final List<JdbcMapping> jdbcMappings = new ArrayList<>( idColumnCount );
identifierMapping.visitColumns( identifierMapping.visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
columnReferences.add( new ColumnReference( mutatingTableReference, columnExpression, jdbcMapping, sessionFactory ) ); columnReferences.add( new ColumnReference( mutatingTableReference, columnExpression, isColumnExpressionFormula, jdbcMapping, sessionFactory ) );
jdbcMappings.add( jdbcMapping ); jdbcMappings.add( jdbcMapping );
} }
); );

View File

@ -69,6 +69,7 @@ public class InPredicateRestrictionProducer implements MatchingIdRestrictionProd
final Expression inFixture = new ColumnReference( final Expression inFixture = new ColumnReference(
mutatingTableReference, mutatingTableReference,
idColumn, idColumn,
false,
basicIdMapping.getJdbcMapping(), basicIdMapping.getJdbcMapping(),
sessionFactory sessionFactory
); );
@ -83,8 +84,8 @@ public class InPredicateRestrictionProducer implements MatchingIdRestrictionProd
final List<ColumnReference> columnReferences = new ArrayList<>( idColumnCount ); final List<ColumnReference> columnReferences = new ArrayList<>( idColumnCount );
final List<JdbcMapping> jdbcMappings = new ArrayList<>( idColumnCount ); final List<JdbcMapping> jdbcMappings = new ArrayList<>( idColumnCount );
identifierMapping.visitColumns( identifierMapping.visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
columnReferences.add( new ColumnReference( mutatingTableReference, columnExpression, jdbcMapping, sessionFactory ) ); columnReferences.add( new ColumnReference( mutatingTableReference, columnExpression, isColumnExpressionFormula, jdbcMapping, sessionFactory ) );
jdbcMappings.add( jdbcMapping ); jdbcMappings.add( jdbcMapping );
} }
); );

View File

@ -62,6 +62,7 @@ public class BasicValuedPathInterpretation<T> implements AssignableSqmPathInterp
sacs -> new ColumnReference( sacs -> new ColumnReference(
tableReference.getIdentificationVariable(), tableReference.getIdentificationVariable(),
mapping.getMappedColumnExpression(), mapping.getMappedColumnExpression(),
mapping.isMappedColumnExpressionFormula(),
mapping.getJdbcMapping(), mapping.getJdbcMapping(),
sqlAstCreationState.getCreationContext().getSessionFactory() sqlAstCreationState.getCreationContext().getSessionFactory()
) )

View File

@ -237,7 +237,7 @@ public class StandardSqmUpdateTranslator
// create one JdbcParameter for each column in the assigned path // create one JdbcParameter for each column in the assigned path
assignedPathInterpretation.getExpressionType().visitColumns( assignedPathInterpretation.getExpressionType().visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> { (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> {
final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping ); final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping );
jdbcParametersForSqm.add( jdbcParameter ); jdbcParametersForSqm.add( jdbcParameter );
assignments.add( assignments.add(
@ -246,6 +246,7 @@ public class StandardSqmUpdateTranslator
// we do not want a qualifier (table alias) here // we do not want a qualifier (table alias) here
(String) null, (String) null,
columnExpression, columnExpression,
isColumnExpressionFormula,
jdbcMapping, jdbcMapping,
getCreationContext().getSessionFactory() getCreationContext().getSessionFactory()
), ),

View File

@ -277,6 +277,9 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
@Override @Override
public SqmSelectStatement<T> orderBy(Order... orders) { public SqmSelectStatement<T> orderBy(Order... orders) {
if ( getQuerySpec().getOrderByClause() == null ) {
getQuerySpec().setOrderByClause( new SqmOrderByClause() );
}
for ( Order order : orders ) { for ( Order order : orders ) {
getQuerySpec().getOrderByClause().addSortSpecification( (SqmSortSpecification) order ); getQuerySpec().getOrderByClause().addSortSpecification( (SqmSortSpecification) order );
} }
@ -285,6 +288,9 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
@Override @Override
public SqmSelectStatement<T> orderBy(List<Order> orders) { public SqmSelectStatement<T> orderBy(List<Order> orders) {
if ( getQuerySpec().getOrderByClause() == null ) {
getQuerySpec().setOrderByClause( new SqmOrderByClause() );
}
for ( Order order : orders ) { for ( Order order : orders ) {
getQuerySpec().getOrderByClause().addSortSpecification( (SqmSortSpecification) order ); getQuerySpec().getOrderByClause().addSortSpecification( (SqmSortSpecification) order );
} }

View File

@ -492,11 +492,7 @@ public abstract class AbstractSqlAstWalker
@Override @Override
public void visitColumnReference(ColumnReference columnReference) { public void visitColumnReference(ColumnReference columnReference) {
if ( columnReference.getQualifier() != null ) { appendSql( columnReference.getExpressionText() );
appendSql( columnReference.getQualifier() );
appendSql( "." );
}
appendSql( columnReference.getColumnExpression() );
} }
@Override @Override

View File

@ -46,7 +46,7 @@ public class CteTable {
final int numberOfColumns = entityDescriptor.getIdentifierMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() ); final int numberOfColumns = entityDescriptor.getIdentifierMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
cteColumns = new ArrayList<>( numberOfColumns ); cteColumns = new ArrayList<>( numberOfColumns );
entityDescriptor.getIdentifierMapping().visitColumns( entityDescriptor.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, jdbcMapping) -> cteColumns.add( (containingTableExpression, columnExpression, isColumnExpressionFormula, jdbcMapping) -> cteColumns.add(
new CteColumn( new CteColumn(
"cte_" + columnExpression, "cte_" + columnExpression,
jdbcMapping jdbcMapping
@ -183,6 +183,7 @@ public class CteTable {
new ColumnReference( new ColumnReference(
tableReference, tableReference,
cteColumn.getColumnExpression(), cteColumn.getColumnExpression(),
false,
cteColumn.getJdbcMapping(), cteColumn.getJdbcMapping(),
sessionFactory sessionFactory
) )

View File

@ -4,19 +4,18 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later * 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 * 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; package org.hibernate.sql.ast.tree.expression;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.sql.Template;
import org.hibernate.sql.ast.SqlAstWalker; import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.update.Assignable; 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 * Models a reference to a Column in a SQL AST
* *
* @author Steve Ebersole * @author Steve Ebersole
* @author Nathan Xu
*/ */
public class ColumnReference implements Expression, Assignable { public class ColumnReference implements Expression, Assignable {
private final String qualifier; private final String qualifier;
private final String columnExpression; private final String columnExpression;
private final boolean isColumnExpressionFormula;
private final String referenceExpression; private final String referenceExpression;
private final JdbcMapping jdbcMapping; private final JdbcMapping jdbcMapping;
public ColumnReference( public ColumnReference(
String qualifier, String qualifier,
String columnExpression, String columnExpression,
boolean isColumnExpressionFormula,
JdbcMapping jdbcMapping, JdbcMapping jdbcMapping,
SessionFactoryImplementor sessionFactory) { SessionFactoryImplementor sessionFactory) {
this.qualifier = StringHelper.nullIfEmpty( qualifier ); this.qualifier = StringHelper.nullIfEmpty( qualifier );
this.columnExpression = columnExpression; if ( isColumnExpressionFormula ) {
this.referenceExpression = this.qualifier == null assert qualifier != null;
? columnExpression this.columnExpression = StringHelper.replace( columnExpression, Template.TEMPLATE, qualifier );
: this.qualifier + "." + columnExpression; }
else {
this.columnExpression = columnExpression;
}
this.isColumnExpressionFormula = isColumnExpressionFormula;
this.referenceExpression = this.qualifier == null || isColumnExpressionFormula
? this.columnExpression
: this.qualifier + "." + this.columnExpression;
this.jdbcMapping = jdbcMapping; this.jdbcMapping = jdbcMapping;
} }
public ColumnReference( public ColumnReference(
TableReference tableReference, TableReference tableReference,
String columnExpression, String columnExpression,
boolean isColumnExpressionFormula,
JdbcMapping jdbcMapping, JdbcMapping jdbcMapping,
SessionFactoryImplementor sessionFactory) { SessionFactoryImplementor sessionFactory) {
this( tableReference.getIdentificationVariable(), columnExpression, jdbcMapping, sessionFactory ); this( tableReference.getIdentificationVariable(), columnExpression, isColumnExpressionFormula, jdbcMapping, sessionFactory );
} }
public String getQualifier() { public String getQualifier() {
@ -61,6 +71,10 @@ public class ColumnReference implements Expression, Assignable {
return columnExpression; return columnExpression;
} }
public boolean isColumnExpressionFormula() {
return isColumnExpressionFormula;
}
public String getExpressionText() { public String getExpressionText() {
return referenceExpression; return referenceExpression;
} }
@ -103,7 +117,7 @@ public class ColumnReference implements Expression, Assignable {
} }
final ColumnReference that = (ColumnReference) o; final ColumnReference that = (ColumnReference) o;
return Objects.equals( referenceExpression, that.referenceExpression ); return referenceExpression.equals( that.referenceExpression );
} }
@Override @Override

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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<Account> criteria = criteriaBuilder.createQuery( Account.class );
final Root<Account> 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;
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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<Foo> query = session.createNativeQuery( "SELECT ft.* FROM foo_table ft", Foo.class );
final List<Foo> list = query.getResultList();
assertThat( list, hasSize( 3 ) );
} );
}
@Test
void testHql(SessionFactoryScope scope) {
scope.inTransaction( session -> {
final Query<Foo> query = session.createQuery( "SELECT ft FROM Foo ft", Foo.class );
final List<Foo> 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;
}
}
}

View File

@ -4,74 +4,59 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/ */
package org.hibernate.test.annotations.formula; package org.hibernate.orm.test.formula;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.annotations.Formula; 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.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.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.orm.junit.DomainModel;
import org.junit.Test; 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) @RequiresDialect(H2Dialect.class)
public class FormulaWithAliasTest extends BaseCoreFunctionalTestCase { public class FormulaWithAliasTest {
@Override @BeforeEach
protected Class<?>[] getAnnotatedClasses() { void setUp(SessionFactoryScope scope) {
return new Class[] { Customer.class }; scope.inTransaction( session -> {
} final Customer company1 = new Customer();
@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();
company1.setBalance(new BigDecimal(100)); company1.setBalance(new BigDecimal(100));
company1.setVip(true); company1.setVip(true);
session.persist(company1); session.persist(company1);
Customer company2 = new Customer(); final Customer company2 = new Customer();
company2.setBalance(new BigDecimal(1000)); company2.setBalance(new BigDecimal(1000));
company2.setVip(false); company2.setVip(false);
session.persist(company2); session.persist(company2);
} ); } );
}
doInHibernate( this::sessionFactory, session -> { @Test
List<Customer> customers = session.createQuery( @TestForIssue(jiraKey = "HHH-12280")
"select c " + void testFormulaWithAlias(SessionFactoryScope scope) {
"from Customer c ", Customer.class) scope.inTransaction( session -> {
.getResultList(); final List<Customer> customers = session.createQuery( "select c from Customer c ", Customer.class ).getResultList();
assertEquals(2, customers.size()); assertEquals(2, customers.size());
assertEquals(1d, customers.get(0).getPercentage().doubleValue(), 0); assertEquals(1d, customers.get(0).getPercentage().doubleValue(), 0);
@ -79,6 +64,11 @@ public class FormulaWithAliasTest extends BaseCoreFunctionalTestCase {
} ); } );
} }
@AfterEach
void tearDown(SessionFactoryScope scope) {
scope.inTransaction( session -> session.createQuery( "delete from Customer" ).executeUpdate() );
}
@Entity(name = "Customer") @Entity(name = "Customer")
public static class Customer implements Serializable{ public static class Customer implements Serializable{

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/ */
package org.hibernate.test.annotations.formula; package org.hibernate.orm.test.formula;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
@ -49,89 +49,89 @@ public class FormulaWithColumnTypesTest extends BaseCoreFunctionalTestCase {
@TestForIssue(jiraKey = "HHH-9951") @TestForIssue(jiraKey = "HHH-9951")
public void testFormulaAnnotationWithTypeNames() { public void testFormulaAnnotationWithTypeNames() {
inTransaction( inTransaction( session -> {
session -> { session.getSessionFactory().getQueryEngine().getInterpretationCache().close();
DisplayItem displayItem20 = new DisplayItem();
displayItem20.setDisplayCode( "20" );
DisplayItem displayItem03 = new DisplayItem(); final DisplayItem displayItem20 = new DisplayItem();
displayItem03.setDisplayCode( "03" ); displayItem20.setDisplayCode( "20" );
DisplayItem displayItem100 = new DisplayItem(); final DisplayItem displayItem03 = new DisplayItem();
displayItem100.setDisplayCode( "100" ); displayItem03.setDisplayCode( "03" );
session.persist( displayItem20 ); final DisplayItem displayItem100 = new DisplayItem();
session.persist( displayItem03 ); displayItem100.setDisplayCode( "100" );
session.persist( displayItem100 );
} session.persist( displayItem20 );
); session.persist( displayItem03 );
session.persist( displayItem100 );
} );
// 1. Default sorting by display code natural ordering (resulting in 3-100-20). // 1. Default sorting by display code natural ordering (resulting in 3-100-20).
inTransaction( inTransaction( session -> {
session -> { session.getSessionFactory().getQueryEngine().getInterpretationCache().close();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<DisplayItem> criteria = criteriaBuilder.createQuery( DisplayItem.class );
Root<DisplayItem> root = criteria.from( DisplayItem.class );
criteria.orderBy( criteriaBuilder.asc( root.get( "displayCode" ) ) );
List displayItems = session.createQuery( criteria ).list(); final CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
final CriteriaQuery<DisplayItem> criteria = criteriaBuilder.createQuery( DisplayItem.class );
final Root<DisplayItem> root = criteria.from( DisplayItem.class );
criteria.orderBy( criteriaBuilder.asc( root.get( "displayCode" ) ) );
final List<DisplayItem> displayItems = session.createQuery( criteria ).getResultList();
// List displayItems = session.createCriteria( DisplayItem.class ) // List displayItems = session.createCriteria( DisplayItem.class )
// .addOrder( Order.asc( "displayCode" ) ) // .addOrder( Order.asc( "displayCode" ) )
// .list(); // .list();
assertNotNull( displayItems ); assertNotNull( displayItems );
assertEquals( displayItems.size(), 3 ); assertEquals( 3, displayItems.size() );
assertEquals( assertEquals(
"03", "03",
( (DisplayItem) displayItems.get( 0 ) ).getDisplayCode() displayItems.get( 0 ).getDisplayCode()
); );
assertEquals( assertEquals(
"100", "100",
( (DisplayItem) displayItems.get( 1 ) ).getDisplayCode() displayItems.get( 1 ).getDisplayCode()
); );
assertEquals( assertEquals(
"20", "20",
( (DisplayItem) displayItems.get( 2 ) ).getDisplayCode() displayItems.get( 2 ).getDisplayCode()
); );
} } );
);
// 2. Sorting by the casted type (resulting in 3-20-100). // 2. Sorting by the casted type (resulting in 3-20-100).
inTransaction( inTransaction( session -> {
session -> { session.getSessionFactory().getQueryEngine().getInterpretationCache().close();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<DisplayItem> criteria = criteriaBuilder.createQuery( DisplayItem.class );
Root<DisplayItem> root = criteria.from( DisplayItem.class );
criteria.orderBy( criteriaBuilder.asc( root.get( "displayCodeAsInteger" ) ) );
List displayItemsSortedByInteger = session.createQuery( criteria ).list(); final CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
final CriteriaQuery<DisplayItem> criteria = criteriaBuilder.createQuery( DisplayItem.class );
final Root<DisplayItem> root = criteria.from( DisplayItem.class );
criteria.orderBy( criteriaBuilder.asc( root.get( "displayCodeAsInteger" ) ) );
final List<DisplayItem> displayItemsSortedByInteger = session.createQuery( criteria ).getResultList();
// List displayItemsSortedByInteger = session.createCriteria( DisplayItem.class ) // List displayItemsSortedByInteger = session.createCriteria( DisplayItem.class )
// .addOrder( Order.asc( "displayCodeAsInteger" ) ) // .addOrder( Order.asc( "displayCodeAsInteger" ) )
// .list(); // .list();
assertNotNull( displayItemsSortedByInteger ); assertNotNull( displayItemsSortedByInteger );
assertEquals( displayItemsSortedByInteger.size(), 3 ); assertEquals( 3, displayItemsSortedByInteger.size() );
assertEquals( assertEquals(
"03", "03",
( (DisplayItem) displayItemsSortedByInteger.get( 0 ) ).getDisplayCode() displayItemsSortedByInteger.get( 0 ).getDisplayCode()
); );
assertEquals( assertEquals(
"20", "20",
( (DisplayItem) displayItemsSortedByInteger.get( 1 ) ).getDisplayCode() displayItemsSortedByInteger.get( 1 ).getDisplayCode()
); );
assertEquals( assertEquals(
"100", "100",
( (DisplayItem) displayItemsSortedByInteger.get( 2 ) ).getDisplayCode() displayItemsSortedByInteger.get( 2 ).getDisplayCode()
); );
} } );
);
} }
@Override @Override
public Class<?>[] getAnnotatedClasses() { public Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {DisplayItem.class}; return new Class<?>[] { DisplayItem.class };
} }
/** /**
@ -200,8 +200,8 @@ public class FormulaWithColumnTypesTest extends BaseCoreFunctionalTestCase {
public ExtendedDialect() { public ExtendedDialect() {
super(); super();
registerKeyword( "FLOAT" );
registerKeyword( "INTEGER" ); registerKeyword( "INTEGER" );
} }
} }
} }

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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<DisplayItem> 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;
}
}
}

View File

@ -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<Account> criteria = criteriaBuilder.createQuery( Account.class );
Root<Account> 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;
}
}
}

View File

@ -56,12 +56,12 @@ public class ManyToOneJoinTableTest {
final ToOneAttributeMapping simpleAttributeMapping = (ToOneAttributeMapping) simpleEntityAssociation; final ToOneAttributeMapping simpleAttributeMapping = (ToOneAttributeMapping) simpleEntityAssociation;
ForeignKeyDescriptor foreignKeyDescriptor = simpleAttributeMapping.getForeignKeyDescriptor(); ForeignKeyDescriptor foreignKeyDescriptor = simpleAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "other_simple" ) ); assertThat( keyTable, is( "other_simple" ) );
assertThat( keyColumn, is( "RHS_ID" ) ); assertThat( keyColumn, is( "RHS_ID" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "simple_entity" ) ); assertThat( targetTable, is( "simple_entity" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );
@ -73,12 +73,12 @@ public class ManyToOneJoinTableTest {
final ToOneAttributeMapping anotherAttributeMapping = (ToOneAttributeMapping) anotherEntityAssociation; final ToOneAttributeMapping anotherAttributeMapping = (ToOneAttributeMapping) anotherEntityAssociation;
foreignKeyDescriptor = anotherAttributeMapping.getForeignKeyDescriptor(); foreignKeyDescriptor = anotherAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "other_another" ) ); assertThat( keyTable, is( "other_another" ) );
assertThat( keyColumn, is( "RHS_ID" ) ); assertThat( keyColumn, is( "RHS_ID" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "another_entity" ) ); assertThat( targetTable, is( "another_entity" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );
@ -95,12 +95,12 @@ public class ManyToOneJoinTableTest {
ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) otherEntityEntityAssociation; ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) otherEntityEntityAssociation;
foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "other_simple" ) ); assertThat( keyTable, is( "other_simple" ) );
assertThat( keyColumn, is( "LHS_ID" ) ); assertThat( keyColumn, is( "LHS_ID" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "other_entity" ) ); assertThat( targetTable, is( "other_entity" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );
@ -117,12 +117,12 @@ public class ManyToOneJoinTableTest {
otherAttributeMapping = (ToOneAttributeMapping) otherEntityEntityAssociation; otherAttributeMapping = (ToOneAttributeMapping) otherEntityEntityAssociation;
foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "another_entity" ) ); assertThat( keyTable, is( "another_entity" ) );
assertThat( keyColumn, is( "other_id" ) ); assertThat( keyColumn, is( "other_id" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "other_entity" ) ); assertThat( targetTable, is( "other_entity" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );

View File

@ -53,12 +53,12 @@ public class ManyToOneTest {
final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) simpleEntityAssociation; final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) simpleEntityAssociation;
ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor(); ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormua, jdbcMapping) -> {
assertThat( keyTable, is( "other_entity" ) ); assertThat( keyTable, is( "other_entity" ) );
assertThat( keyColumn, is( "simple_entity_id" ) ); assertThat( keyColumn, is( "simple_entity_id" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "simple_entity" ) ); assertThat( targetTable, is( "simple_entity" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );

View File

@ -51,12 +51,12 @@ public class EntityWithBidirectionalAssociationTest {
final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation; final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation;
ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor(); ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "PARENT" ) ); assertThat( keyTable, is( "PARENT" ) );
assertThat( keyColumn, is( "child_id" ) ); assertThat( keyColumn, is( "child_id" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "CHILD" ) ); assertThat( targetTable, is( "CHILD" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );
@ -72,12 +72,12 @@ public class EntityWithBidirectionalAssociationTest {
final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation; final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation;
foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor(); foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "PARENT" ) ); assertThat( keyTable, is( "PARENT" ) );
assertThat( keyColumn, is( "child_id" ) ); assertThat( keyColumn, is( "child_id" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "CHILD" ) ); assertThat( targetTable, is( "CHILD" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );

View File

@ -53,12 +53,12 @@ public class EntityWithOneBidirectionalJoinTableAssociationTest {
final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation; final ToOneAttributeMapping childAttributeMapping = (ToOneAttributeMapping) childAssociation;
ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor(); ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "PARENT_CHILD" ) ); assertThat( keyTable, is( "PARENT_CHILD" ) );
assertThat( keyColumn, is( "child_id" ) ); assertThat( keyColumn, is( "child_id" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "CHILD" ) ); assertThat( targetTable, is( "CHILD" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );
@ -74,12 +74,12 @@ public class EntityWithOneBidirectionalJoinTableAssociationTest {
final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation; final ToOneAttributeMapping parentAttributeMapping = (ToOneAttributeMapping) parentAssociation;
foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor(); foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "PARENT_CHILD" ) ); assertThat( keyTable, is( "PARENT_CHILD" ) );
assertThat( keyColumn, is( "parent_id" ) ); assertThat( keyColumn, is( "parent_id" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "PARENT" ) ); assertThat( targetTable, is( "PARENT" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );

View File

@ -47,12 +47,12 @@ public class EntityWithOneToOneJoinTableTest {
final ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) other; final ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) other;
final ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); final ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "Entity_SimpleEntity" ) ); assertThat( keyTable, is( "Entity_SimpleEntity" ) );
assertThat( keyColumn, is( "other_id" ) ); assertThat( keyColumn, is( "other_id" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "SIMPLE_ENTITY" ) ); assertThat( targetTable, is( "SIMPLE_ENTITY" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );

View File

@ -48,12 +48,12 @@ public class EntityWithOneToOneSharingPrimaryKeyTest {
final ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) otherAssociation; final ToOneAttributeMapping otherAttributeMapping = (ToOneAttributeMapping) otherAssociation;
ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor(); ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor();
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> { foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, isKeyColumnFormula, jdbcMapping) -> {
assertThat( keyTable, is( "EntityWithOneToOneSharingPrimaryKey" ) ); assertThat( keyTable, is( "EntityWithOneToOneSharingPrimaryKey" ) );
assertThat( keyColumn, is( "id" ) ); assertThat( keyColumn, is( "id" ) );
} ); } );
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> { foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, isTargetColumnFormula, jdbcMapping) -> {
assertThat( targetTable, is( "SIMPLE_ENTITY" ) ); assertThat( targetTable, is( "SIMPLE_ENTITY" ) );
assertThat( targetColumn, is( "id" ) ); assertThat( targetColumn, is( "id" ) );
} ); } );

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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<Foo> 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<Foo> 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;
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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<DisplayItem> 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;
}
}
}