diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/Level1.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/Level1.java new file mode 100644 index 00000000..872cb49f --- /dev/null +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/Level1.java @@ -0,0 +1,68 @@ +package org.hibernate.bugs; + +import java.util.LinkedHashSet; +import java.util.Set; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.NamedAttributeNode; +import jakarta.persistence.NamedEntityGraph; +import jakarta.persistence.NamedEntityGraphs; +import jakarta.persistence.NamedSubgraph; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OrderBy; + +@Entity +@NamedEntityGraphs({ + @NamedEntityGraph( + name = "level1_loadAll", + attributeNodes = { + @NamedAttributeNode(value = "childs", subgraph = "subgraph.childs") + }, + subgraphs = { + @NamedSubgraph( + name = "subgraph.childs", + attributeNodes = { + @NamedAttributeNode(value = "childs") + } + ) + } + ) +}) +public class Level1 { + + @Id + private Long id; + + @OneToMany(fetch = FetchType.LAZY, + mappedBy = "parent", + cascade = CascadeType.ALL, + orphanRemoval = true) + @OrderBy("id") + private Set childs = new LinkedHashSet<>(); + + public Level1() { + } + + public Level1(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Set getChilds() { + return childs; + } + + public void setChilds(Set childs) { + this.childs = childs; + } + +} diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/Level2.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/Level2.java new file mode 100644 index 00000000..de102d01 --- /dev/null +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/Level2.java @@ -0,0 +1,64 @@ +package org.hibernate.bugs; + +import java.util.LinkedHashSet; +import java.util.Set; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OrderBy; + +@Entity +public class Level2 { + + @Id + Long id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "parent_id", nullable = false) + private Level1 parent; + + @OneToMany(fetch = FetchType.LAZY, + mappedBy = "parent", + cascade = CascadeType.ALL, + orphanRemoval = true) + @OrderBy("id") + private Set childs = new LinkedHashSet<>(); + + + public Level2() { + } + + public Level2(Level1 parent, Long id) { + this.parent = parent; + this.id = id; + parent.getChilds().add(this); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Level1 getParent() { + return parent; + } + + public void setParent(Level1 parent) { + this.parent = parent; + } + + public Set getChilds() { + return childs; + } + + public void setChilds(Set childs) { + this.childs = childs; + } +} diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/Level3.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/Level3.java new file mode 100644 index 00000000..a2d097d6 --- /dev/null +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/Level3.java @@ -0,0 +1,43 @@ +package org.hibernate.bugs; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; + +@Entity +public class Level3 { + + @Id + Long id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "parent_id", nullable = false) + private Level2 parent; + + public Level3() { + } + + public Level3(Level2 parent, Long id) { + this.parent = parent; + this.id = id; + parent.getChilds().add(this); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Level2 getParent() { + return parent; + } + + public void setParent(Level2 parent) { + this.parent = parent; + } +} diff --git a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/ORMUnitTestCase.java b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/ORMUnitTestCase.java index 66757be0..5737bf63 100644 --- a/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/ORMUnitTestCase.java +++ b/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/ORMUnitTestCase.java @@ -15,11 +15,14 @@ */ package org.hibernate.bugs; +import java.util.HashMap; +import java.util.Map; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Assert; import org.junit.Test; /** @@ -37,8 +40,9 @@ public class ORMUnitTestCase extends BaseCoreFunctionalTestCase { @Override protected Class[] getAnnotatedClasses() { return new Class[] { -// Foo.class, -// Bar.class + Level1.class, + Level2.class, + Level3.class, }; } @@ -68,10 +72,64 @@ protected void configure(Configuration configuration) { // Add your tests, using standard JUnit. @Test - public void hhh123Test() throws Exception { + public void hhh18436Test() throws Exception { // BaseCoreFunctionalTestCase automatically creates the SessionFactory and provides the Session. Session s = openSession(); Transaction tx = s.beginTransaction(); + Level1 root = new Level1(1L); + + Level2 child1 = new Level2(root, 1L); + Level2 child2 = new Level2(root,2L); + Level2 child3 = new Level2(root,3L); + + new Level3(child2,1L); + + s.persist(root); + s.flush(); + s.clear(); + + Level1 loadedWithoutEntityGraph = s.find(Level1.class, 1L); + + long i = 1; + for (Level2 child : loadedWithoutEntityGraph.getChilds()) { + Assert.assertEquals("Childs not in expected order", Long.valueOf(i), child.getId()); + i++; + } + + tx.commit(); + s.close(); + } + + // Add your tests, using standard JUnit. + @Test + public void hhh18436TestEntitygraph() throws Exception { + // BaseCoreFunctionalTestCase automatically creates the SessionFactory and provides the Session. + Session s = openSession(); + Transaction tx = s.beginTransaction(); + Level1 root = new Level1(1L); + + Level2 child1 = new Level2(root, 1L); + Level2 child2 = new Level2(root,2L); + Level2 child3 = new Level2(root,3L); + + new Level3(child2,1L); + + s.persist(root); + s.flush(); + s.clear(); + + // Hints + Map hints = new HashMap<>(); + hints.put("jakarta.persistence.loadgraph", s.getEntityGraph("level1_loadAll")); + + Level1 loadedWithEntityGraph = s.find(Level1.class, 1L, hints); + + long i = 1; + for (Level2 child : loadedWithEntityGraph.getChilds()) { + Assert.assertEquals("Childs not in expected order", Long.valueOf(i), child.getId()); + i++; + } + // Do stuff... tx.commit(); s.close();