Skip to content

Commit f8f5adf

Browse files
committed
HHH-18563 Add test using foreign key property
1 parent 9699a1b commit f8f5adf

File tree

7 files changed

+120
-28
lines changed

7 files changed

+120
-28
lines changed

gradle/databases.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ ext {
3636
'connection.init_sql' : ''
3737
],
3838
derby : [
39-
'db.dialect' : 'org.hibernate.dialect.DerbyDialect',
39+
'db.dialect' : 'org.hibernate.community.dialect.DerbyDialect',
4040
'jdbc.driver': 'org.apache.derby.iapi.jdbc.AutoloadedDriver',
4141
'jdbc.user' : 'hibernate_orm_test',
4242
'jdbc.pass' : 'hibernate_orm_test',
@@ -46,7 +46,7 @@ ext {
4646
'connection.init_sql' : ''
4747
],
4848
derby_old : [
49-
'db.dialect' : 'org.hibernate.dialect.DerbyDialect',
49+
'db.dialect' : 'org.hibernate.community.dialect.DerbyDialect',
5050
'jdbc.driver': 'org.apache.derby.jdbc.EmbeddedDriver',
5151
'jdbc.user' : 'hibernate_orm_test',
5252
'jdbc.pass' : 'hibernate_orm_test',

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacySqlAstTranslator.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.hibernate.sql.ast.tree.select.QueryPart;
5151
import org.hibernate.sql.ast.tree.select.QuerySpec;
5252
import org.hibernate.sql.ast.tree.select.SelectClause;
53+
import org.hibernate.sql.ast.tree.select.SelectStatement;
5354
import org.hibernate.sql.ast.tree.select.SortSpecification;
5455
import org.hibernate.sql.ast.tree.update.Assignable;
5556
import org.hibernate.sql.ast.tree.update.Assignment;
@@ -688,10 +689,10 @@ protected void visitSetAssignment(Assignment assignment) {
688689
}
689690
}
690691
final List<ColumnReference> columnReferences = assignment.getAssignable().getColumnReferences();
692+
final Expression assignedValue = assignment.getAssignedValue();
691693
if ( columnReferences.size() == 1 ) {
692694
columnReferences.get( 0 ).appendColumnForWrite( this );
693695
appendSql( '=' );
694-
final Expression assignedValue = assignment.getAssignedValue();
695696
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( assignedValue );
696697
if ( sqlTuple != null ) {
697698
assert sqlTuple.getExpressions().size() == 1;
@@ -701,7 +702,7 @@ protected void visitSetAssignment(Assignment assignment) {
701702
assignedValue.accept( this );
702703
}
703704
}
704-
else {
705+
else if ( assignedValue instanceof SelectStatement ) {
705706
char separator = OPEN_PARENTHESIS;
706707
for ( ColumnReference columnReference : columnReferences ) {
707708
appendSql( separator );
@@ -711,5 +712,18 @@ protected void visitSetAssignment(Assignment assignment) {
711712
appendSql( ")=" );
712713
assignment.getAssignedValue().accept( this );
713714
}
715+
else {
716+
assert assignedValue instanceof SqlTupleContainer;
717+
final List<? extends Expression> expressions = ( (SqlTupleContainer) assignedValue ).getSqlTuple().getExpressions();
718+
columnReferences.get( 0 ).appendColumnForWrite( this, null );
719+
appendSql( '=' );
720+
expressions.get( 0 ).accept( this );
721+
for ( int i = 1; i < columnReferences.size(); i++ ) {
722+
appendSql( ',' );
723+
columnReferences.get( i ).appendColumnForWrite( this, null );
724+
appendSql( '=' );
725+
expressions.get( i ).accept( this );
726+
}
727+
}
714728
}
715729
}

hibernate-core/src/main/java/org/hibernate/dialect/OracleSqlAstTranslator.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.hibernate.sql.ast.tree.select.QueryPart;
4848
import org.hibernate.sql.ast.tree.select.QuerySpec;
4949
import org.hibernate.sql.ast.tree.select.SelectClause;
50+
import org.hibernate.sql.ast.tree.select.SelectStatement;
5051
import org.hibernate.sql.ast.tree.select.SortSpecification;
5152
import org.hibernate.sql.ast.tree.update.Assignable;
5253
import org.hibernate.sql.ast.tree.update.Assignment;
@@ -631,10 +632,10 @@ protected void visitSetAssignment(Assignment assignment) {
631632
}
632633
}
633634
final List<ColumnReference> columnReferences = assignment.getAssignable().getColumnReferences();
635+
final Expression assignedValue = assignment.getAssignedValue();
634636
if ( columnReferences.size() == 1 ) {
635637
columnReferences.get( 0 ).appendColumnForWrite( this );
636638
appendSql( '=' );
637-
final Expression assignedValue = assignment.getAssignedValue();
638639
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( assignedValue );
639640
if ( sqlTuple != null ) {
640641
assert sqlTuple.getExpressions().size() == 1;
@@ -644,15 +645,28 @@ protected void visitSetAssignment(Assignment assignment) {
644645
assignedValue.accept( this );
645646
}
646647
}
647-
else {
648+
else if ( assignedValue instanceof SelectStatement ) {
648649
char separator = OPEN_PARENTHESIS;
649650
for ( ColumnReference columnReference : columnReferences ) {
650651
appendSql( separator );
651652
columnReference.appendColumnForWrite( this );
652653
separator = COMMA_SEPARATOR_CHAR;
653654
}
654655
appendSql( ")=" );
655-
assignment.getAssignedValue().accept( this );
656+
assignedValue.accept( this );
657+
}
658+
else {
659+
assert assignedValue instanceof SqlTupleContainer;
660+
final List<? extends Expression> expressions = ( (SqlTupleContainer) assignedValue ).getSqlTuple().getExpressions();
661+
columnReferences.get( 0 ).appendColumnForWrite( this, null );
662+
appendSql( '=' );
663+
expressions.get( 0 ).accept( this );
664+
for ( int i = 1; i < columnReferences.size(); i++ ) {
665+
appendSql( ',' );
666+
columnReferences.get( i ).appendColumnForWrite( this, null );
667+
appendSql( '=' );
668+
expressions.get( i ).accept( this );
669+
}
656670
}
657671
}
658672

hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ private List<Assignment> getCompatibleAssignments(InsertSelectStatement dmlState
12991299
final List<Assignment> assignments = conflictClause.getAssignments();
13001300
for ( Assignment assignment : assignments ) {
13011301
for ( ColumnReference targetColumn : dmlStatement.getTargetColumns() ) {
1302-
if ( targetColumn.equals( assignment.getAssignable() ) ) {
1302+
if ( assignment.getAssignable().getColumnReferences().contains( targetColumn ) ) {
13031303
if ( compatibleAssignments == null ) {
13041304
compatibleAssignments = new ArrayList<>( assignments.size() );
13051305
}

hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/EntityValuedPathInterpretation.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import org.hibernate.dialect.Dialect;
1313
import org.hibernate.dialect.FunctionalDependencyAnalysisSupport;
1414
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
15-
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
1615
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
1716
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
1817
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;

hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,10 +1241,10 @@ protected void visitSetAssignment(Assignment assignment) {
12411241
}
12421242
}
12431243
final List<ColumnReference> columnReferences = assignable.getColumnReferences();
1244+
final Expression assignedValue = assignment.getAssignedValue();
12441245
if ( columnReferences.size() == 1 ) {
12451246
columnReferences.get( 0 ).appendColumnForWrite( this, null );
12461247
appendSql( '=' );
1247-
final Expression assignedValue = assignment.getAssignedValue();
12481248
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( assignedValue );
12491249
if ( sqlTuple != null ) {
12501250
assert sqlTuple.getExpressions().size() == 1;
@@ -1254,15 +1254,28 @@ protected void visitSetAssignment(Assignment assignment) {
12541254
assignedValue.accept( this );
12551255
}
12561256
}
1257-
else {
1257+
else if ( assignedValue instanceof SelectStatement ) {
12581258
char separator = OPEN_PARENTHESIS;
12591259
for ( ColumnReference columnReference : columnReferences ) {
12601260
appendSql( separator );
12611261
columnReference.appendColumnForWrite( this, null );
12621262
separator = COMMA_SEPARATOR_CHAR;
12631263
}
12641264
appendSql( ")=" );
1265-
assignment.getAssignedValue().accept( this );
1265+
assignedValue.accept( this );
1266+
}
1267+
else {
1268+
assert assignedValue instanceof SqlTupleContainer;
1269+
final List<? extends Expression> expressions = ( (SqlTupleContainer) assignedValue ).getSqlTuple().getExpressions();
1270+
columnReferences.get( 0 ).appendColumnForWrite( this, null );
1271+
appendSql( '=' );
1272+
expressions.get( 0 ).accept( this );
1273+
for ( int i = 1; i < columnReferences.size(); i++ ) {
1274+
appendSql( ',' );
1275+
columnReferences.get( i ).appendColumnForWrite( this, null );
1276+
appendSql( '=' );
1277+
expressions.get( i ).accept( this );
1278+
}
12661279
}
12671280
}
12681281

@@ -2155,17 +2168,39 @@ private void renderPredicatedSetAssignments(List<Assignment> assignments, Predic
21552168
visitSetAssignment( assignment );
21562169
}
21572170
else {
2158-
assert assignment.getAssignable().getColumnReferences().size() == 1;
2159-
final Expression expression = new CaseSearchedExpression(
2160-
(MappingModelExpressible) assignment.getAssignedValue().getExpressionType(),
2161-
List.of(
2162-
new CaseSearchedExpression.WhenFragment(
2163-
predicate, assignment.getAssignedValue()
2171+
final Assignable assignable = assignment.getAssignable();
2172+
final Expression assignedValue = assignment.getAssignedValue();
2173+
final Expression expression;
2174+
if ( assignable.getColumnReferences().size() == 1 ) {
2175+
expression = new CaseSearchedExpression(
2176+
(MappingModelExpressible) assignedValue.getExpressionType(),
2177+
List.of( new CaseSearchedExpression.WhenFragment( predicate, assignedValue ) ),
2178+
assignable.getColumnReferences().get( 0 )
2179+
);
2180+
}
2181+
else {
2182+
assert assignedValue instanceof SqlTupleContainer;
2183+
final List<? extends Expression> expressions =
2184+
( (SqlTupleContainer) assignedValue ).getSqlTuple().getExpressions();
2185+
final List<Expression> tupleExpressions = new ArrayList<>( expressions.size() );
2186+
for ( int i = 0; i < expressions.size(); i++ ) {
2187+
tupleExpressions.add(
2188+
new CaseSearchedExpression(
2189+
(MappingModelExpressible) expressions.get( i ).getExpressionType(),
2190+
List.of( new CaseSearchedExpression.WhenFragment(
2191+
predicate,
2192+
expressions.get( i )
2193+
) ),
2194+
assignable.getColumnReferences().get( i )
21642195
)
2165-
),
2166-
assignment.getAssignable().getColumnReferences().get( 0 )
2167-
);
2168-
visitSetAssignment( new Assignment( assignment.getAssignable(), expression ) );
2196+
);
2197+
}
2198+
expression = new SqlTuple(
2199+
tupleExpressions,
2200+
(MappingModelExpressible) assignedValue.getExpressionType()
2201+
);
2202+
}
2203+
visitSetAssignment( new Assignment( assignable, expression ) );
21692204
}
21702205
}
21712206
}

hibernate-core/src/test/java/org/hibernate/orm/test/flush/AutoFlushOnUpdateQueryTest.java

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
15
package org.hibernate.orm.test.flush;
26

3-
import org.hibernate.testing.jdbc.SQLStatementInspector;
47
import org.hibernate.testing.orm.junit.DomainModel;
58
import org.hibernate.testing.orm.junit.SessionFactory;
69
import org.hibernate.testing.orm.junit.SessionFactoryScope;
@@ -22,9 +25,7 @@
2225
AutoFlushOnUpdateQueryTest.Fruit.class,
2326
}
2427
)
25-
@SessionFactory(
26-
statementInspectorClass = SQLStatementInspector.class
27-
)
28+
@SessionFactory
2829
public class AutoFlushOnUpdateQueryTest {
2930

3031
public static final String FRUIT_NAME = "Apple";
@@ -50,8 +51,6 @@ public void tearDown(SessionFactoryScope scope) {
5051

5152
@Test
5253
public void testFlushIsExecuted(SessionFactoryScope scope) {
53-
SQLStatementInspector statementInspector = scope.getStatementInspector( SQLStatementInspector.class );
54-
statementInspector.clear();
5554
scope.inTransaction(
5655
session -> {
5756
Fruit fruit = session
@@ -81,6 +80,37 @@ public void testFlushIsExecuted(SessionFactoryScope scope) {
8180
);
8281
}
8382

83+
@Test
84+
public void testFlushIsExecuted2(SessionFactoryScope scope) {
85+
scope.inTransaction(
86+
session -> {
87+
Fruit fruit = session
88+
.createQuery(
89+
"select f from Fruit f where f.name = :name",
90+
Fruit.class
91+
).setParameter( "name", FRUIT_NAME ).getSingleResult();
92+
93+
FruitLogEntry logEntry = new FruitLogEntry( fruit, "foo" );
94+
session.persist( logEntry );
95+
96+
session.createMutationQuery( "update Fruit f set f.logEntry.id = :logEntryId where f.id = :fruitId" )
97+
.setParameter( "logEntryId", logEntry.getId() )
98+
.setParameter( "fruitId", fruit.getId() ).executeUpdate();
99+
}
100+
);
101+
102+
scope.inTransaction(
103+
session -> {
104+
Fruit fruit = session
105+
.createQuery(
106+
"select f from Fruit f where f.name = :name",
107+
Fruit.class
108+
).setParameter( "name", FRUIT_NAME ).getSingleResult();
109+
assertThat( fruit.getLogEntry() ).isNotNull();
110+
}
111+
);
112+
}
113+
84114
@Entity(name = "Fruit")
85115
public static class Fruit {
86116

0 commit comments

Comments
 (0)