diff --git a/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/fetcher/RecursiveTest.java b/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/fetcher/RecursiveTest.java index 7f9d0b186..fb9b1670f 100644 --- a/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/fetcher/RecursiveTest.java +++ b/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/fetcher/RecursiveTest.java @@ -9,6 +9,10 @@ import org.babyfish.jimmer.sql.model.TreeNodeFetcher; import org.babyfish.jimmer.sql.model.TreeNodeProps; import org.babyfish.jimmer.sql.model.TreeNodeTable; +import org.babyfish.jimmer.sql.model.issue888.ItemFetcher; +import org.babyfish.jimmer.sql.model.issue888.StructureFetcher; +import org.babyfish.jimmer.sql.model.issue888.StructureTable; +import org.h2.table.TableFilter; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -815,4 +819,81 @@ public void filter(FilterArgs args) { } ); } + + @Test + public void testIssue888() { + StructureTable table = StructureTable.$; + executeAndExpect( + getSqlClient() + .createQuery(table) + .where(table.id().eq(1L)) + .select( + table.fetch( + StructureFetcher.$ + .allScalarFields() + .items( + ItemFetcher.$ + .allScalarFields() + .recursiveChildItems() + ) + ) + ), + ctx -> { + ctx.sql( + "select tb_1_.ID, tb_1_.NAME " + + "from issue888_structure " + + "tb_1_ where tb_1_.ID = ?" + ).variables(1L); + ctx.statement(1).sql( + "select tb_1_.ID, tb_1_.NAME " + + "from issue888_item tb_1_ " + + "where tb_1_.STRUCTURE_ID = ?" + ).variables(1L); + ctx.statement(2).sql( + "select tb_1_.ID, tb_1_.NAME " + + "from issue888_item tb_1_ " + + "where tb_1_.PARENT_ID = ? " + + "order by tb_1_.ID asc" + ).variables(1L); + ctx.statement(3).sql( + "select tb_1_.PARENT_ID, tb_1_.ID, tb_1_.NAME " + + "from issue888_item tb_1_ " + + "where tb_1_.PARENT_ID in (?, ?) " + + "order by tb_1_.ID asc" + ).variables(2L, 5L); + ctx.statement(4).sql( + "select tb_1_.PARENT_ID, tb_1_.ID, tb_1_.NAME " + + "from issue888_item tb_1_ " + + "where tb_1_.PARENT_ID in (?, ?, ?, ?) " + + "order by tb_1_.ID asc" + ).variables(3L, 4L, 6L, 7L); + ctx.row( + 0, + "{" + + "--->\"id\":1,\"name\":\"structure-1\"," + + "--->\"items\":[" + + "--->--->{" + + "--->--->--->\"id\":1,\"name\":\"item-1\"," + + "--->--->--->\"childItems\":[" + + "--->--->--->--->{" + + "--->--->--->--->--->\"id\":2,\"name\":\"item-1.1\"," + + "--->--->--->--->--->\"childItems\":[" + + "--->--->--->--->--->--->{\"id\":3,\"name\":\"item-1.1.1\",\"childItems\":[]}," + + "--->--->--->--->--->--->{\"id\":4,\"name\":\"item-1.1.2\",\"childItems\":[]}" + + "--->--->--->--->--->]" + + "--->--->--->--->},{" + + "--->--->--->--->--->\"id\":5,\"name\":\"item-1.2\"," + + "--->--->--->--->--->\"childItems\":[" + + "--->--->--->--->--->--->{\"id\":6,\"name\":\"item-1.2.1\",\"childItems\":[]}," + + "--->--->--->--->--->--->{\"id\":7,\"name\":\"item-1.2.2\",\"childItems\":[]}" + + "--->--->--->--->--->]" + + "--->--->--->--->}" + + "--->--->--->]" + + "--->--->}" + + "--->]" + + "}" + ); + } + ); + } } diff --git a/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/model/issue888/Item.java b/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/model/issue888/Item.java new file mode 100644 index 000000000..273f10cfa --- /dev/null +++ b/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/model/issue888/Item.java @@ -0,0 +1,30 @@ +package org.babyfish.jimmer.sql.model.issue888; + +import org.babyfish.jimmer.sql.*; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +@Entity +@Table(name = "issue888_item") +public interface Item { + + @Id + long id(); + + @Column + String name(); + + @Nullable + @ManyToOne + Structure structure(); + + @ManyToOne + Item parent(); + + @OneToMany( + mappedBy = "parent", + orderedProps = @OrderedProp("id") + ) + List childItems(); +} diff --git a/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/model/issue888/Structure.java b/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/model/issue888/Structure.java new file mode 100644 index 000000000..fee3739cb --- /dev/null +++ b/project/jimmer-sql/src/test/java/org/babyfish/jimmer/sql/model/issue888/Structure.java @@ -0,0 +1,21 @@ +package org.babyfish.jimmer.sql.model.issue888; + +import org.babyfish.jimmer.sql.Entity; +import org.babyfish.jimmer.sql.Id; +import org.babyfish.jimmer.sql.OneToMany; +import org.babyfish.jimmer.sql.Table; + +import java.util.List; + +@Entity +@Table(name = "issue888_structure") +public interface Structure { + + @Id + long id(); + + String name(); + + @OneToMany(mappedBy = "structure") + List items(); +} diff --git a/project/jimmer-sql/src/test/resources/database.sql b/project/jimmer-sql/src/test/resources/database.sql index 304a7f2b0..5bf7bb497 100644 --- a/project/jimmer-sql/src/test/resources/database.sql +++ b/project/jimmer-sql/src/test/resources/database.sql @@ -3,6 +3,8 @@ create schema if not exists B; create schema if not exists C; create schema if not exists D; +drop table issue888_item if exists; +drop table issue888_structure if exists; drop table post_2_category_2_mapping if exists; drop table post_2 if exists; drop table category_2 if exists; @@ -1415,3 +1417,45 @@ insert into person(id, name, friend_id) values update person set friend_id = 4 where id = 1; + + + +create table issue888_structure( + id bigint not null, + name varchar(20) not null +); +alter table issue888_structure + add constraint pk_issue888_structure + primary key(id); + +create table issue888_item( + id bigint not null, + name varchar(20) not null, + structure_id bigint, + parent_id bigint +); +alter table issue888_item + add constraint pk_issue888_item + primary key(id); +alter table issue888_item + add constraint fk_issue888_item__structure + foreign key(structure_id) + references issue888_structure(id); +alter table issue888_item + add constraint fk_issue888_item__item + foreign key(parent_id) + references issue888_item(id); + +insert into issue888_structure(id, name) values(1, 'structure-1'); + +insert into issue888_item(id, name, structure_id) values + (1, 'item-1', 1); + +insert into issue888_item(id, name, parent_id) values + (2, 'item-1.1', 1), + (3, 'item-1.1.1', 2), + (4, 'item-1.1.2', 2), + (5, 'item-1.2', 1), + (6, 'item-1.2.1', 5), + (7, 'item-1.2.2', 5) +; \ No newline at end of file