diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaTypeValidationTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaTypeValidationTests.java new file mode 100644 index 0000000000..5fce4336cf --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaTypeValidationTests.java @@ -0,0 +1,85 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.orm.test.query.criteria; + +import java.util.HashSet; +import java.util.Set; + +import org.hibernate.query.criteria.HibernateCriteriaBuilder; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; +import jakarta.persistence.criteria.SetJoin; + +@DomainModel( annotatedClasses = { + CriteriaTypeValidationTests.Parent.class, + CriteriaTypeValidationTests.Child.class +} ) +@SessionFactory +public class CriteriaTypeValidationTests { + + @Test + @JiraKey( "HHH-17001" ) + public void testHhh17001(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + final Child someChildToCompareTo = new Child( 1L ); + session.persist(someChildToCompareTo); + + final HibernateCriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cq = cb.createQuery(Parent.class); + final Root root = cq.from(Parent.class); + final SetJoin childrenJoin = root.joinSet( "children" ); + // This will cause a StackOverflowError: + childrenJoin.on(cb.equal(childrenJoin, someChildToCompareTo)); + // This works: + // cq.where(cb.equal(childrenJoin, someChildToCompareTo)); + session.createQuery(cq).getResultList(); + } + ); + } + + + @Entity + public static class Parent { + @Id + private Long id; + + private String name; + + @OneToMany(mappedBy = "parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) + private Set children = new HashSet<>(); + } + + @Entity + public static class Child { + @Id + private Long id; + + @ManyToOne + private Parent parent; + + public Child() { + } + + public Child(Long id) { + this.id = id; + } + } +}