Я пытался использовать граф сущностей, чтобы избежать запроса N + 1, и он работал, как и ожидалось.
Он отличается от объекта самоссылки, хотя этот код может получить правильный список, возник запрос N + 1.
Мой вопрос состоит в том, как исключить N + 1 запрос с самоссылочным объектом?
Заранее спасибо.
лог и код следующим образом
Hibernate:
select
sysperm0_.pval as pval1_0_0_,
children1_.pval as pval1_0_1_,
sysperm2_.pval as pval1_0_2_,
sysperm0_.parent as parent4_0_0_,
sysperm0_.created as created2_0_0_,
sysperm0_.leaf as leaf3_0_0_,
sysperm0_.pname as pname5_0_0_,
sysperm0_.ptype as ptype6_0_0_,
sysperm0_.updated as updated7_0_0_,
children1_.parent as parent4_0_1_,
children1_.created as created2_0_1_,
children1_.leaf as leaf3_0_1_,
children1_.pname as pname5_0_1_,
children1_.ptype as ptype6_0_1_,
children1_.updated as updated7_0_1_,
children1_.parent as parent4_0_0__,
children1_.pval as pval1_0_0__,
sysperm2_.parent as parent4_0_2_,
sysperm2_.created as created2_0_2_,
sysperm2_.leaf as leaf3_0_2_,
sysperm2_.pname as pname5_0_2_,
sysperm2_.ptype as ptype6_0_2_,
sysperm2_.updated as updated7_0_2_
from
sys_perm sysperm0_
left outer join
sys_perm children1_
on sysperm0_.pval=children1_.parent
left outer join
sys_perm sysperm2_
on children1_.parent=sysperm2_.pval
where
sysperm0_.pval=?
Hibernate:
select
children0_.parent as parent4_0_0_,
children0_.pval as pval1_0_0_,
children0_.pval as pval1_0_1_,
children0_.parent as parent4_0_1_,
children0_.created as created2_0_1_,
children0_.leaf as leaf3_0_1_,
children0_.pname as pname5_0_1_,
children0_.ptype as ptype6_0_1_,
children0_.updated as updated7_0_1_
from
sys_perm children0_
where
children0_.parent=?
.......XN
492373 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
5197227 nanoseconds spent preparing 8 JDBC statements;
18997333 nanoseconds spent executing 8 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
сущность
@Table(name="sys_perm")
@Entity
@NamedEntityGraph(
name = "test",
attributeNodes = {
@NamedAttributeNode(value="children",subgraph="sub_perm"),
},
subgraphs = {
@NamedSubgraph(
name = "sub_perm",
attributeNodes = {
@NamedAttributeNode("_parent")
}
)
}
)
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class SysPerm implements Serializable {
@Id
private String pval;
private String parent;
private String pname;
private Integer ptype;
private Boolean leaf;
@CreationTimestamp
private Date created;
@UpdateTimestamp
private Date updated;
@ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.ALL})
@JoinColumn(name = "parent", referencedColumnName = "pval", insertable=false, updatable=false)
@JsonIgnore
private SysPerm _parent;
@OneToMany(mappedBy="_parent", fetch=FetchType.EAGER, cascade={CascadeType.ALL})
private List<SysPerm> children = new ArrayList<>();
}
хранилище
public interface SysPermRepository extends JpaRepository<SysPerm, Long>{
@EntityGraph(value = "test", type = EntityGraphType.FETCH)
List<SysPerm> findByPval(String pval);
}
схема
CREATE TABLE `sys_perm` (
`pval` varchar(50) NOT NULL ,
`parent` varchar(25) DEFAULT NULL ,
`pname` varchar(50) DEFAULT NULL ,
`ptype` int(3) DEFAULT NULL ,
`leaf` tinyint(1) DEFAULT NULL ,
`created` timestamp NULL DEFAULT NULL ,
`updated` timestamp NULL DEFAULT NULL ,
PRIMARY KEY (`pval`),
UNIQUE KEY `pval` (`pval`),
KEY `FKaiy87e3krvn4suwleaooces17` (`parent`),
CONSTRAINT `FKaiy87e3krvn4suwleaooces17` FOREIGN KEY (`parent`) REFERENCES `sys_perm` (`pval`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;