Skip to content

Commit 68d3cc1

Browse files
committed
HHH-18563 Add test using foreign key property
1 parent a73f76e commit 68d3cc1

File tree

5 files changed

+114
-25
lines changed

5 files changed

+114
-25
lines changed

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
@@ -56,6 +56,7 @@
5656
import org.hibernate.sql.ast.tree.select.QueryPart;
5757
import org.hibernate.sql.ast.tree.select.QuerySpec;
5858
import org.hibernate.sql.ast.tree.select.SelectClause;
59+
import org.hibernate.sql.ast.tree.select.SelectStatement;
5960
import org.hibernate.sql.ast.tree.select.SortSpecification;
6061
import org.hibernate.sql.ast.tree.update.Assignable;
6162
import org.hibernate.sql.ast.tree.update.Assignment;
@@ -680,10 +681,10 @@ protected void visitSetAssignment(Assignment assignment) {
680681
}
681682
}
682683
final List<ColumnReference> columnReferences = assignment.getAssignable().getColumnReferences();
684+
final Expression assignedValue = assignment.getAssignedValue();
683685
if ( columnReferences.size() == 1 ) {
684686
columnReferences.get( 0 ).appendColumnForWrite( this );
685687
appendSql( '=' );
686-
final Expression assignedValue = assignment.getAssignedValue();
687688
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( assignedValue );
688689
if ( sqlTuple != null ) {
689690
assert sqlTuple.getExpressions().size() == 1;
@@ -693,7 +694,7 @@ protected void visitSetAssignment(Assignment assignment) {
693694
assignedValue.accept( this );
694695
}
695696
}
696-
else {
697+
else if ( assignedValue instanceof SelectStatement ) {
697698
char separator = OPEN_PARENTHESIS;
698699
for ( ColumnReference columnReference : columnReferences ) {
699700
appendSql( separator );
@@ -703,5 +704,18 @@ protected void visitSetAssignment(Assignment assignment) {
703704
appendSql( ")=" );
704705
assignment.getAssignedValue().accept( this );
705706
}
707+
else {
708+
assert assignedValue instanceof SqlTupleContainer;
709+
final List<? extends Expression> expressions = ( (SqlTupleContainer) assignedValue ).getSqlTuple().getExpressions();
710+
columnReferences.get( 0 ).appendColumnForWrite( this, null );
711+
appendSql( '=' );
712+
expressions.get( 0 ).accept( this );
713+
for ( int i = 1; i < columnReferences.size(); i++ ) {
714+
appendSql( ',' );
715+
columnReferences.get( i ).appendColumnForWrite( this, null );
716+
appendSql( '=' );
717+
expressions.get( i ).accept( this );
718+
}
719+
}
706720
}
707721
}

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.hibernate.sql.ast.tree.select.QueryPart;
5555
import org.hibernate.sql.ast.tree.select.QuerySpec;
5656
import org.hibernate.sql.ast.tree.select.SelectClause;
57+
import org.hibernate.sql.ast.tree.select.SelectStatement;
5758
import org.hibernate.sql.ast.tree.select.SortSpecification;
5859
import org.hibernate.sql.ast.tree.update.Assignable;
5960
import org.hibernate.sql.ast.tree.update.Assignment;
@@ -637,10 +638,10 @@ protected void visitSetAssignment(Assignment assignment) {
637638
}
638639
}
639640
final List<ColumnReference> columnReferences = assignment.getAssignable().getColumnReferences();
641+
final Expression assignedValue = assignment.getAssignedValue();
640642
if ( columnReferences.size() == 1 ) {
641643
columnReferences.get( 0 ).appendColumnForWrite( this );
642644
appendSql( '=' );
643-
final Expression assignedValue = assignment.getAssignedValue();
644645
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( assignedValue );
645646
if ( sqlTuple != null ) {
646647
assert sqlTuple.getExpressions().size() == 1;
@@ -650,15 +651,28 @@ protected void visitSetAssignment(Assignment assignment) {
650651
assignedValue.accept( this );
651652
}
652653
}
653-
else {
654+
else if ( assignedValue instanceof SelectStatement ) {
654655
char separator = OPEN_PARENTHESIS;
655656
for ( ColumnReference columnReference : columnReferences ) {
656657
appendSql( separator );
657658
columnReference.appendColumnForWrite( this );
658659
separator = COMMA_SEPARATOR_CHAR;
659660
}
660661
appendSql( ")=" );
661-
assignment.getAssignedValue().accept( this );
662+
assignedValue.accept( this );
663+
}
664+
else {
665+
assert assignedValue instanceof SqlTupleContainer;
666+
final List<? extends Expression> expressions = ( (SqlTupleContainer) assignedValue ).getSqlTuple().getExpressions();
667+
columnReferences.get( 0 ).appendColumnForWrite( this, null );
668+
appendSql( '=' );
669+
expressions.get( 0 ).accept( this );
670+
for ( int i = 1; i < columnReferences.size(); i++ ) {
671+
appendSql( ',' );
672+
columnReferences.get( i ).appendColumnForWrite( this, null );
673+
appendSql( '=' );
674+
expressions.get( i ).accept( this );
675+
}
662676
}
663677
}
664678

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/sql/ast/spi/AbstractSqlAstTranslator.java

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,10 +1158,10 @@ protected void visitSetAssignment(Assignment assignment) {
11581158
}
11591159
}
11601160
final List<ColumnReference> columnReferences = assignable.getColumnReferences();
1161+
final Expression assignedValue = assignment.getAssignedValue();
11611162
if ( columnReferences.size() == 1 ) {
11621163
columnReferences.get( 0 ).appendColumnForWrite( this, null );
11631164
appendSql( '=' );
1164-
final Expression assignedValue = assignment.getAssignedValue();
11651165
final SqlTuple sqlTuple = getSqlTuple( assignedValue );
11661166
if ( sqlTuple != null ) {
11671167
assert sqlTuple.getExpressions().size() == 1;
@@ -1171,15 +1171,28 @@ protected void visitSetAssignment(Assignment assignment) {
11711171
assignedValue.accept( this );
11721172
}
11731173
}
1174-
else {
1174+
else if ( assignedValue instanceof SelectStatement ) {
11751175
char separator = OPEN_PARENTHESIS;
11761176
for ( ColumnReference columnReference : columnReferences ) {
11771177
appendSql( separator );
11781178
columnReference.appendColumnForWrite( this, null );
11791179
separator = COMMA_SEPARATOR_CHAR;
11801180
}
11811181
appendSql( ")=" );
1182-
assignment.getAssignedValue().accept( this );
1182+
assignedValue.accept( this );
1183+
}
1184+
else {
1185+
assert assignedValue instanceof SqlTupleContainer;
1186+
final List<? extends Expression> expressions = ( (SqlTupleContainer) assignedValue ).getSqlTuple().getExpressions();
1187+
columnReferences.get( 0 ).appendColumnForWrite( this, null );
1188+
appendSql( '=' );
1189+
expressions.get( 0 ).accept( this );
1190+
for ( int i = 1; i < columnReferences.size(); i++ ) {
1191+
appendSql( ',' );
1192+
columnReferences.get( i ).appendColumnForWrite( this, null );
1193+
appendSql( '=' );
1194+
expressions.get( i ).accept( this );
1195+
}
11831196
}
11841197
}
11851198

@@ -2048,17 +2061,39 @@ private void renderPredicatedSetAssignments(List<Assignment> assignments, Predic
20482061
visitSetAssignment( assignment );
20492062
}
20502063
else {
2051-
assert assignment.getAssignable().getColumnReferences().size() == 1;
2052-
final Expression expression = new CaseSearchedExpression(
2053-
(MappingModelExpressible<?>) assignment.getAssignedValue().getExpressionType(),
2054-
List.of(
2055-
new CaseSearchedExpression.WhenFragment(
2056-
predicate, assignment.getAssignedValue()
2064+
final Assignable assignable = assignment.getAssignable();
2065+
final Expression assignedValue = assignment.getAssignedValue();
2066+
final Expression expression;
2067+
if ( assignable.getColumnReferences().size() == 1 ) {
2068+
expression = new CaseSearchedExpression(
2069+
(MappingModelExpressible) assignedValue.getExpressionType(),
2070+
List.of( new CaseSearchedExpression.WhenFragment( predicate, assignedValue ) ),
2071+
assignable.getColumnReferences().get( 0 )
2072+
);
2073+
}
2074+
else {
2075+
assert assignedValue instanceof SqlTupleContainer;
2076+
final List<? extends Expression> expressions =
2077+
( (SqlTupleContainer) assignedValue ).getSqlTuple().getExpressions();
2078+
final List<Expression> tupleExpressions = new ArrayList<>( expressions.size() );
2079+
for ( int i = 0; i < expressions.size(); i++ ) {
2080+
tupleExpressions.add(
2081+
new CaseSearchedExpression(
2082+
(MappingModelExpressible<?>) expressions.get( i ).getExpressionType(),
2083+
List.of( new CaseSearchedExpression.WhenFragment(
2084+
predicate,
2085+
expressions.get( i )
2086+
) ),
2087+
assignable.getColumnReferences().get( i )
20572088
)
2058-
),
2059-
assignment.getAssignable().getColumnReferences().get( 0 )
2060-
);
2061-
visitSetAssignment( new Assignment( assignment.getAssignable(), expression ) );
2089+
);
2090+
}
2091+
expression = new SqlTuple(
2092+
tupleExpressions,
2093+
(MappingModelExpressible) assignedValue.getExpressionType()
2094+
);
2095+
}
2096+
visitSetAssignment( new Assignment( assignable, expression ) );
20622097
}
20632098
}
20642099
}

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

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
package org.hibernate.orm.test.flush;
66

7-
import org.hibernate.testing.jdbc.SQLStatementInspector;
87
import org.hibernate.testing.orm.junit.DomainModel;
98
import org.hibernate.testing.orm.junit.SessionFactory;
109
import org.hibernate.testing.orm.junit.SessionFactoryScope;
@@ -26,9 +25,7 @@
2625
AutoFlushOnUpdateQueryTest.Fruit.class,
2726
}
2827
)
29-
@SessionFactory(
30-
statementInspectorClass = SQLStatementInspector.class
31-
)
28+
@SessionFactory
3229
public class AutoFlushOnUpdateQueryTest {
3330

3431
public static final String FRUIT_NAME = "Apple";
@@ -54,8 +51,6 @@ public void tearDown(SessionFactoryScope scope) {
5451

5552
@Test
5653
public void testFlushIsExecuted(SessionFactoryScope scope) {
57-
SQLStatementInspector statementInspector = scope.getStatementInspector( SQLStatementInspector.class );
58-
statementInspector.clear();
5954
scope.inTransaction(
6055
session -> {
6156
Fruit fruit = session
@@ -85,6 +80,37 @@ public void testFlushIsExecuted(SessionFactoryScope scope) {
8580
);
8681
}
8782

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+
88114
@Entity(name = "Fruit")
89115
public static class Fruit {
90116

0 commit comments

Comments
 (0)