HHH-17143 - More not-found fix ups
https://hibernate.atlassian.net/browse/HHH-17143
This commit is contained in:
parent
f7709e7610
commit
3e96ddce40
|
@ -63,6 +63,7 @@ import org.hibernate.property.access.spi.PropertyAccess;
|
|||
import org.hibernate.spi.EntityIdentifierNavigablePath;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.spi.TreatedNavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||
import org.hibernate.sql.ast.spi.FromClauseAccess;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||
|
@ -1991,6 +1992,19 @@ public class ToOneAttributeMapping
|
|||
return join;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAstJoinType determineSqlJoinType(TableGroup lhs, SqlAstJoinType requestedJoinType, boolean fetched) {
|
||||
if ( requestedJoinType != null ) {
|
||||
return requestedJoinType;
|
||||
}
|
||||
|
||||
if ( fetched ) {
|
||||
return getDefaultSqlAstJoinType( lhs );
|
||||
}
|
||||
|
||||
return SqlAstJoinType.INNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyTableGroup createRootTableGroupJoin(
|
||||
NavigablePath navigablePath,
|
||||
|
|
|
@ -206,10 +206,11 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
|
|||
resultTableGroup = tableGroup;
|
||||
}
|
||||
}
|
||||
else if ( inferredMapping == null && hasNotFound( mapping ) ) {
|
||||
// This is necessary to allow expression like `where root.notFoundAssociation is null`
|
||||
// to render to `alias.not_found_fk is null`, but IMO this shouldn't be done
|
||||
// todo: discuss removing this part and create a left joined table group instead?
|
||||
else if ( inferredMapping == null
|
||||
&& hasNotFound( mapping )
|
||||
&& sqlAstCreationState.getCurrentClauseStack().getCurrent() == Clause.SET ) {
|
||||
// for not-found mappings encountered in the SET clause of an UPDATE statement
|
||||
// we will want to (1) not join and (2) render the fk
|
||||
resultModelPart = keyTargetMatchPart;
|
||||
resultTableGroup = sqlAstCreationState.getFromClauseAccess()
|
||||
.findTableGroup( tableGroup.getNavigablePath().getParent() );
|
||||
|
@ -218,6 +219,10 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
|
|||
// If the mapping is an inverse association, use the PK and disallow FK optimizations
|
||||
resultModelPart = ( (EntityAssociationMapping) mapping ).getAssociatedEntityMappingType().getIdentifierMapping();
|
||||
resultTableGroup = tableGroup;
|
||||
|
||||
// todo (not-found) : in the case of not-found=ignore, we want to do the join, however -
|
||||
// * use a left join when the association is the path terminus (`root.association`)
|
||||
// * use an inner join when it is further de-referenced (`root.association.stuff`)
|
||||
}
|
||||
}
|
||||
else if ( mapping instanceof AnonymousTupleEntityValuedModelPart ) {
|
||||
|
|
|
@ -78,18 +78,14 @@ public interface TableGroupJoinProducer extends TableGroupProducer {
|
|||
SqlAstCreationState creationState);
|
||||
|
||||
default SqlAstJoinType determineSqlJoinType(TableGroup lhs, SqlAstJoinType requestedJoinType, boolean fetched) {
|
||||
final SqlAstJoinType joinType;
|
||||
if ( requestedJoinType == null ) {
|
||||
if ( fetched ) {
|
||||
joinType = getDefaultSqlAstJoinType( lhs );
|
||||
}
|
||||
else {
|
||||
joinType = SqlAstJoinType.INNER;
|
||||
}
|
||||
if ( requestedJoinType != null ) {
|
||||
return requestedJoinType;
|
||||
}
|
||||
else {
|
||||
joinType = requestedJoinType;
|
||||
|
||||
if ( fetched ) {
|
||||
return getDefaultSqlAstJoinType( lhs );
|
||||
}
|
||||
return joinType;
|
||||
|
||||
return SqlAstJoinType.INNER;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.hibernate.orm.test.notfound;
|
|||
import org.hibernate.annotations.NotFound;
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
|
||||
import org.hibernate.testing.jdbc.SQLStatementInspector;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
|
@ -17,7 +18,7 @@ import jakarta.persistence.JoinColumn;
|
|||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
|
@ -25,7 +26,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
|||
MutationQueriesAndNotFoundActionTest.Comment.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
@SessionFactory( useCollectingStatementInspector = true )
|
||||
@JiraKey("HHH-16878")
|
||||
public class MutationQueriesAndNotFoundActionTest {
|
||||
|
||||
|
@ -56,8 +57,12 @@ public class MutationQueriesAndNotFoundActionTest {
|
|||
|
||||
@Test
|
||||
public void testUpdate(SessionFactoryScope scope) {
|
||||
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
statementInspector.clear();
|
||||
|
||||
int affectedComments = session.createMutationQuery(
|
||||
"update Comment c set c.text = :text where c.user = :user" )
|
||||
.setParameter( "text", "updated" )
|
||||
|
@ -65,6 +70,10 @@ public class MutationQueriesAndNotFoundActionTest {
|
|||
.executeUpdate();
|
||||
|
||||
assertThat( affectedComments ).isEqualTo( 2 );
|
||||
assertThat( statementInspector.getSqlQueries() ).hasSize( 1 );
|
||||
assertThat( statementInspector.getSqlQueries().get( 0 ) ).matches( (sql) -> {
|
||||
return sql.contains( " join " ) || sql.contains( "exists" );
|
||||
} );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue