Skip to content

Commit 3e96ddc

Browse files
sebersolebeikov
authored andcommitted
HHH-17143 - More not-found fix ups
https://hibernate.atlassian.net/browse/HHH-17143
1 parent f7709e7 commit 3e96ddc

File tree

4 files changed

+41
-17
lines changed

4 files changed

+41
-17
lines changed

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import org.hibernate.spi.EntityIdentifierNavigablePath;
6464
import org.hibernate.spi.NavigablePath;
6565
import org.hibernate.spi.TreatedNavigablePath;
66+
import org.hibernate.sql.ast.Clause;
6667
import org.hibernate.sql.ast.SqlAstJoinType;
6768
import org.hibernate.sql.ast.spi.FromClauseAccess;
6869
import org.hibernate.sql.ast.spi.SqlAliasBase;
@@ -1991,6 +1992,19 @@ public TableGroupJoin createTableGroupJoin(
19911992
return join;
19921993
}
19931994

1995+
@Override
1996+
public SqlAstJoinType determineSqlJoinType(TableGroup lhs, SqlAstJoinType requestedJoinType, boolean fetched) {
1997+
if ( requestedJoinType != null ) {
1998+
return requestedJoinType;
1999+
}
2000+
2001+
if ( fetched ) {
2002+
return getDefaultSqlAstJoinType( lhs );
2003+
}
2004+
2005+
return SqlAstJoinType.INNER;
2006+
}
2007+
19942008
@Override
19952009
public LazyTableGroup createRootTableGroupJoin(
19962010
NavigablePath navigablePath,

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,11 @@ private static <T> EntityValuedPathInterpretation<T> from(
206206
resultTableGroup = tableGroup;
207207
}
208208
}
209-
else if ( inferredMapping == null && hasNotFound( mapping ) ) {
210-
// This is necessary to allow expression like `where root.notFoundAssociation is null`
211-
// to render to `alias.not_found_fk is null`, but IMO this shouldn't be done
212-
// todo: discuss removing this part and create a left joined table group instead?
209+
else if ( inferredMapping == null
210+
&& hasNotFound( mapping )
211+
&& sqlAstCreationState.getCurrentClauseStack().getCurrent() == Clause.SET ) {
212+
// for not-found mappings encountered in the SET clause of an UPDATE statement
213+
// we will want to (1) not join and (2) render the fk
213214
resultModelPart = keyTargetMatchPart;
214215
resultTableGroup = sqlAstCreationState.getFromClauseAccess()
215216
.findTableGroup( tableGroup.getNavigablePath().getParent() );
@@ -218,6 +219,10 @@ else if ( inferredMapping == null && hasNotFound( mapping ) ) {
218219
// If the mapping is an inverse association, use the PK and disallow FK optimizations
219220
resultModelPart = ( (EntityAssociationMapping) mapping ).getAssociatedEntityMappingType().getIdentifierMapping();
220221
resultTableGroup = tableGroup;
222+
223+
// todo (not-found) : in the case of not-found=ignore, we want to do the join, however -
224+
// * use a left join when the association is the path terminus (`root.association`)
225+
// * use an inner join when it is further de-referenced (`root.association.stuff`)
221226
}
222227
}
223228
else if ( mapping instanceof AnonymousTupleEntityValuedModelPart ) {

hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoinProducer.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,14 @@ TableGroup createRootTableGroupJoin(
7878
SqlAstCreationState creationState);
7979

8080
default SqlAstJoinType determineSqlJoinType(TableGroup lhs, SqlAstJoinType requestedJoinType, boolean fetched) {
81-
final SqlAstJoinType joinType;
82-
if ( requestedJoinType == null ) {
83-
if ( fetched ) {
84-
joinType = getDefaultSqlAstJoinType( lhs );
85-
}
86-
else {
87-
joinType = SqlAstJoinType.INNER;
88-
}
81+
if ( requestedJoinType != null ) {
82+
return requestedJoinType;
8983
}
90-
else {
91-
joinType = requestedJoinType;
84+
85+
if ( fetched ) {
86+
return getDefaultSqlAstJoinType( lhs );
9287
}
93-
return joinType;
88+
89+
return SqlAstJoinType.INNER;
9490
}
9591
}

hibernate-core/src/test/java/org/hibernate/orm/test/notfound/MutationQueriesAndNotFoundActionTest.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.hibernate.annotations.NotFound;
44
import org.hibernate.annotations.NotFoundAction;
55

6+
import org.hibernate.testing.jdbc.SQLStatementInspector;
67
import org.hibernate.testing.orm.junit.DomainModel;
78
import org.hibernate.testing.orm.junit.JiraKey;
89
import org.hibernate.testing.orm.junit.SessionFactory;
@@ -17,15 +18,15 @@
1718
import jakarta.persistence.ManyToOne;
1819
import jakarta.persistence.Table;
1920

20-
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
21+
import static org.assertj.core.api.Assertions.assertThat;
2122

2223
@DomainModel(
2324
annotatedClasses = {
2425
MutationQueriesAndNotFoundActionTest.User.class,
2526
MutationQueriesAndNotFoundActionTest.Comment.class
2627
}
2728
)
28-
@SessionFactory
29+
@SessionFactory( useCollectingStatementInspector = true )
2930
@JiraKey("HHH-16878")
3031
public class MutationQueriesAndNotFoundActionTest {
3132

@@ -56,15 +57,23 @@ public void tearDown(SessionFactoryScope scope) {
5657

5758
@Test
5859
public void testUpdate(SessionFactoryScope scope) {
60+
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
61+
5962
scope.inTransaction(
6063
session -> {
64+
statementInspector.clear();
65+
6166
int affectedComments = session.createMutationQuery(
6267
"update Comment c set c.text = :text where c.user = :user" )
6368
.setParameter( "text", "updated" )
6469
.setParameter( "user", session.getReference( User.class, 1L ) )
6570
.executeUpdate();
6671

6772
assertThat( affectedComments ).isEqualTo( 2 );
73+
assertThat( statementInspector.getSqlQueries() ).hasSize( 1 );
74+
assertThat( statementInspector.getSqlQueries().get( 0 ) ).matches( (sql) -> {
75+
return sql.contains( " join " ) || sql.contains( "exists" );
76+
} );
6877
}
6978
);
7079
}

0 commit comments

Comments
 (0)