diff --git a/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/Author.java b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/Author.java new file mode 100644 index 0000000000..a37b0910a2 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/Author.java @@ -0,0 +1,25 @@ +package org.hibernate.query.criteria.internal.hhh14916; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +@Entity +public class Author { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + public Long authorId; + + @Column + public String name; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "author", orphanRemoval = true, cascade = CascadeType.ALL) + public List books = new ArrayList<>(); +} diff --git a/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/Book.java b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/Book.java new file mode 100644 index 0000000000..23ec689a03 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/Book.java @@ -0,0 +1,32 @@ +package org.hibernate.query.criteria.internal.hhh14916; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +@Entity +public class Book { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + public Long bookId; + + @Column + public String name; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "author_id", nullable = false) + public Author author; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "book", orphanRemoval = true, cascade = CascadeType.ALL) + public List chapters = new ArrayList<>(); +} diff --git a/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/Chapter.java b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/Chapter.java new file mode 100644 index 0000000000..a97d6da843 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/Chapter.java @@ -0,0 +1,22 @@ +package org.hibernate.query.criteria.internal.hhh14916; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +@Entity +public class Chapter { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + public Long chapterId; + + public String name; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "book_id", nullable = false) + public Book book; +} diff --git a/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/HHH14916Test.java b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/HHH14916Test.java new file mode 100644 index 0000000000..3583194b83 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/query/criteria/internal/hhh14916/HHH14916Test.java @@ -0,0 +1,74 @@ +package org.hibernate.query.criteria.internal.hhh14916; + +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; +import org.hibernate.testing.TestForIssue; +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.JoinType; +import javax.persistence.criteria.ListJoin; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +@TestForIssue( jiraKey = "HHH-14916" ) +public class HHH14916Test extends BaseEntityManagerFunctionalTestCase { + + @Before + public void before() { + populateData(); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Author.class, Book.class, Chapter.class }; + } + + @Test + public void testJoinOnFetchNoExceptionThrow() { + doInJPA( this::entityManagerFactory, entityManager -> { + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + final CriteriaQuery query = builder.createQuery(Author.class); + + final Root root = query.from(Author.class); + final ListJoin authorBookJoin = (ListJoin)root.fetch("books", JoinType.LEFT); + + final ListJoin bookChapterJoin = authorBookJoin.joinList("chapters", JoinType.LEFT); + + final Predicate finalPredicate = builder.equal(bookChapterJoin.get("name"), "Overview of HTTP"); + query.where(finalPredicate); + + Author author = entityManager.createQuery(query).getSingleResult(); + + assertEquals(author.name, "David Gourley"); + assertEquals(author.books.get(0).name, "HTTP Definitive guide"); + assertEquals(author.books.get(0).chapters.get(0).name, "Overview of HTTP"); + } ); + } + + public void populateData() { + doInJPA(this::entityManagerFactory, entityManager -> { + // Insert data + Chapter chapter = new Chapter(); + chapter.name = "Overview of HTTP"; + + Book book = new Book(); + book.name = "HTTP Definitive guide"; + + Author author = new Author(); + author.name = "David Gourley"; + + book.chapters.add(chapter); + author.books.add(book); + + chapter.book = book; + book.author = author; + + entityManager.persist(author); + }); + } +}