Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.List;
import java.util.Map;

import jakarta.persistence.metamodel.Bindable;
import org.hibernate.Incubating;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.UnsupportedMappingException;
Expand All @@ -31,6 +32,7 @@
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
import org.hibernate.sql.ast.spi.FromClauseAccess;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.ObjectArrayJavaType;

Expand Down Expand Up @@ -177,20 +179,21 @@ public SqmPathSource<?> findSubPathSource(String name) {
final SqmSelectableNode<?> component = components[index];
if ( component instanceof SqmPath<?> ) {
final SqmPath<?> sqmPath = (SqmPath<?>) component;
if ( sqmPath.getNodeType() instanceof SingularPersistentAttribute<?, ?> ) {
final Bindable<?> model = sqmPath.getModel();
if ( model instanceof SingularPersistentAttribute<?, ?> ) {
//noinspection unchecked,rawtypes
return new AnonymousTupleSqmAssociationPathSource(
name,
sqmPath,
( (SingularPersistentAttribute<?, ?>) sqmPath.getNodeType() ).getType()
( (SingularPersistentAttribute<?, ?>) model ).getType()
);
}
else if ( sqmPath.getNodeType() instanceof PluralPersistentAttribute<?, ?, ?> ) {
else if ( model instanceof PluralPersistentAttribute<?, ?, ?> ) {
//noinspection unchecked,rawtypes
return new AnonymousTupleSqmAssociationPathSource(
name,
sqmPath,
( (PluralPersistentAttribute<?, ?, ?>) sqmPath.getNodeType() ).getElementType()
( (PluralPersistentAttribute<?, ?, ?>) model ).getElementType()
);
}
else if ( sqmPath.getNodeType() instanceof EntityDomainType<?> ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ private AttributeJoinDelegate resolveAlias(String identifier, boolean isTerminal
if ( allowReuse ) {
if ( !isTerminal ) {
for ( SqmJoin<?, ?> sqmJoin : lhs.getSqmJoins() ) {
if ( sqmJoin.getAlias() == null && sqmJoin.getReferencedPathSource() == subPathSource ) {
if ( sqmJoin.getAlias() == null && sqmJoin.getModel() == subPathSource ) {
return sqmJoin;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ public static <T, A> SqmAttributeJoin<T, A> findCompatibleFetchJoin(
SqmPathSource<A> pathSource,
SqmJoinType requestedJoinType) {
for ( final SqmJoin<T, ?> join : sqmFrom.getSqmJoins() ) {
if ( join.getReferencedPathSource() == pathSource ) {
if ( join.getModel() == pathSource ) {
final SqmAttributeJoin<T, ?> attributeJoin = (SqmAttributeJoin<T, ?>) join;
if ( attributeJoin.isFetched() ) {
final SqmJoinType joinType = join.getSqmJoinType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public <X> X accept(SemanticQueryWalker<X> walker) {
@Override
public PersistentAttribute<? super O, ?> getAttribute() {
//noinspection unchecked
return (PersistentAttribute<? super O, ?>) getReferencedPathSource();
return (PersistentAttribute<? super O, ?>) getModel();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.TreatableDomainType;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.sqm.NodeBuilder;
Expand Down Expand Up @@ -86,6 +87,16 @@ public SqmSingularJoin<O, T> copy(SqmCopyContext context) {
return path;
}

@Override
public SqmPathSource<T> getNodeType() {
return getReferencedPathSource();
}

@Override
public SqmPathSource<T> getReferencedPathSource() {
return getModel().getPathSource();
}

@Override
public SingularPersistentAttribute<O, T> getModel() {
return (SingularPersistentAttribute<O, T>) super.getNodeType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.List;

import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterAll;
Expand All @@ -29,7 +30,11 @@
@DomainModel( annotatedClasses = {
LeftJoinNullnessPredicateQueryTest.Author.class,
LeftJoinNullnessPredicateQueryTest.Book.class
} )
})
@Jira( "https://hibernate.atlassian.net/browse/HHH-16505" )
@Jira( "https://hibernate.atlassian.net/browse/HHH-17379" )
@Jira( "https://hibernate.atlassian.net/browse/HHH-17397" )
@Jira( "https://hibernate.atlassian.net/browse/HHH-19116" )
public class LeftJoinNullnessPredicateQueryTest {
@BeforeAll
public void setUp(SessionFactoryScope scope) {
Expand Down Expand Up @@ -80,6 +85,19 @@ public void testIsNotNull(SessionFactoryScope scope) {
} );
}

@Test
public void testIsNullImplicit(SessionFactoryScope scope) {
scope.inTransaction( session -> {
final List<Book> resultList = session.createQuery(
"select book from Book book " +
"where book.author is null",
Book.class
).getResultList();
assertThat( resultList ).hasSize( 1 );
assertThat( resultList.get( 0 ).getTitle() ).isEqualTo( "Unknown Author" );
} );
}

@Test
public void testDereferenceIsNull(SessionFactoryScope scope) {
scope.inTransaction( session -> {
Expand Down Expand Up @@ -108,6 +126,19 @@ public void testDereferenceIsNotNull(SessionFactoryScope scope) {
} );
}

@Test
public void testFkImplicitIsNull(SessionFactoryScope scope) {
scope.inTransaction( session -> {
final List<Book> resultList = session.createQuery(
"select book from Book book " +
"where fk(book.author) is null",
Book.class
).getResultList();
assertThat( resultList ).hasSize( 1 );
assertThat( resultList.get( 0 ).getTitle() ).isEqualTo( "Unknown Author" );
} );
}

@Test
public void testIsNotNullWithCondition(SessionFactoryScope scope) {
scope.inTransaction( session -> {
Expand Down
Loading