加载 parent spring 数据时急切获取 child jpa
Eagerly fetch child when loading parent spring data jpa
Link.java
@Entity
@Table(name = "LINK")
@AttributeOverride(name="id", column=@Column(name="LINK_ID"))
public class Link extends AbstractAuditableEntity<Integer> {
/**
*
*/
private static final long serialVersionUID = 3825555385014396995L;
@Column(name="NAME")
private String name;
@Column(name="UI_SREF")
private String uiSref;
@ManyToOne
@JoinColumn(name="PARENT_LINK_ID")
private Link parentLink;
@OneToMany(mappedBy="parentLink", fetch = FetchType.EAGER)
private List<Link> childLinks;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the uiSref
*/
public String getUiSref() {
return uiSref;
}
/**
* @param uiSref the uiSref to set
*/
public void setUiSref(String uiSref) {
this.uiSref = uiSref;
}
/**
* @return the parentLink
*/
public Link getParentLink() {
return parentLink;
}
/**
* @param parentLink the parentLink to set
*/
public void setParentLink(Link parentLink) {
this.parentLink = parentLink;
}
/**
* @return the childLinks
*/
public List<Link> getChildLinks() {
return childLinks;
}
/**
* @param childLinks the childLinks to set
*/
public void setChildLinks(List<Link> childLinks) {
this.childLinks = childLinks;
}
}
链接库。java
public interface LinkRepository extends BaseRepository<Integer, Link> {
@Query("select distinct p from Link l JOIN fetch l.parentLink p where l.id in (select lar.link.id from LinkAccessRole lar where lar.accessRoleLu in ?1) and p.id in (select lar.link.id from LinkAccessRole lar where lar.accessRoleLu in ?1)")
public List<Link> getNavigationByaccessRoleLuList(List<AccessRoleLu> accessRoleLu);
}
Link_Table
Link_Access_Role Table
生成的查询:
SELECT DISTINCT t0.LINK_ID, t0.CREATED_BY_ID, t0.CREATED_DATE, t0.LAST_MODIFIED_BY_ID, t0.LAST_MODIFIED_DATE, t0.NAME, t0.UI_SREF, t0.PARENT_LINK_ID FROM LINK t0, LINK t1 WHERE ((t1.LINK_ID IN (SELECT t2.LINK_ID FROM LINK_ACCESS_ROLE t3, LINK t2 WHERE ((t3.ACCESS_ROLE_ID IN (?,?)) AND (t2.LINK_ID = t3.LINK_ID))) AND t0.LINK_ID IN (SELECT t4.LINK_ID FROM LINK_ACCESS_ROLE t5, LINK t4 WHERE ((t5.ACCESS_ROLE_ID IN (?,?)) AND (t4.LINK_ID = t5.LINK_ID)))) AND (t0.LINK_ID = t1.PARENT_LINK_ID))
bind => [4 parameters bound]
SELECT LINK_ID, CREATED_BY_ID, CREATED_DATE, LAST_MODIFIED_BY_ID, LAST_MODIFIED_DATE, NAME, UI_SREF, PARENT_LINK_ID FROM LINK WHERE (PARENT_LINK_ID = ?)
bind => [1 parameter bound]
SELECT LINK_ID, CREATED_BY_ID, CREATED_DATE, LAST_MODIFIED_BY_ID, LAST_MODIFIED_DATE, NAME, UI_SREF, PARENT_LINK_ID FROM LINK WHERE (PARENT_LINK_ID = ?)
bind => [1 parameter bound]
我为每个 child 获取一个与获取的 parent 相关的查询,无论它是否具有访问角色。
我想获取 parents 及其具有访问权限的 childs 而不是所有与 parent 相关的 childs。
获取父实体并使用基于某些条件 的条目子集填充其中一个集合的唯一方法是使用 Hibernate 的专有过滤器。
我不确定其他 JPA 提供商是否也提供了一些专有解决方案,但 JPA 本身并不直接提供这个。
您首先需要使用 @FilterDef
注册过滤器定义,然后您需要使用 属性.
集合中的 @Filter
引用过滤器定义
这里困难的部分是您不能依赖 Spring 数据的 @Query
或它们的存储库实现生成过程来提供帮助。您将需要使用真正的实现,以便您可以在查询父实体之前手动启用此休眠过滤器。
Filter filter = session.enableFilter( "link-with-restrictions-by-roles" );
filter.setParameter( "roles", yourRolesList );
return session.createQuery( ... ).getResultList();
文档详细描述了 @Filter
和 @FilterDef
的用法。您还可以找到我的另一个 post,我在其中提供了更多实现细节 .
Link.java
@Entity
@Table(name = "LINK")
@AttributeOverride(name="id", column=@Column(name="LINK_ID"))
public class Link extends AbstractAuditableEntity<Integer> {
/**
*
*/
private static final long serialVersionUID = 3825555385014396995L;
@Column(name="NAME")
private String name;
@Column(name="UI_SREF")
private String uiSref;
@ManyToOne
@JoinColumn(name="PARENT_LINK_ID")
private Link parentLink;
@OneToMany(mappedBy="parentLink", fetch = FetchType.EAGER)
private List<Link> childLinks;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the uiSref
*/
public String getUiSref() {
return uiSref;
}
/**
* @param uiSref the uiSref to set
*/
public void setUiSref(String uiSref) {
this.uiSref = uiSref;
}
/**
* @return the parentLink
*/
public Link getParentLink() {
return parentLink;
}
/**
* @param parentLink the parentLink to set
*/
public void setParentLink(Link parentLink) {
this.parentLink = parentLink;
}
/**
* @return the childLinks
*/
public List<Link> getChildLinks() {
return childLinks;
}
/**
* @param childLinks the childLinks to set
*/
public void setChildLinks(List<Link> childLinks) {
this.childLinks = childLinks;
}
}
链接库。java
public interface LinkRepository extends BaseRepository<Integer, Link> {
@Query("select distinct p from Link l JOIN fetch l.parentLink p where l.id in (select lar.link.id from LinkAccessRole lar where lar.accessRoleLu in ?1) and p.id in (select lar.link.id from LinkAccessRole lar where lar.accessRoleLu in ?1)")
public List<Link> getNavigationByaccessRoleLuList(List<AccessRoleLu> accessRoleLu);
}
Link_Table Link_Access_Role Table
生成的查询:
SELECT DISTINCT t0.LINK_ID, t0.CREATED_BY_ID, t0.CREATED_DATE, t0.LAST_MODIFIED_BY_ID, t0.LAST_MODIFIED_DATE, t0.NAME, t0.UI_SREF, t0.PARENT_LINK_ID FROM LINK t0, LINK t1 WHERE ((t1.LINK_ID IN (SELECT t2.LINK_ID FROM LINK_ACCESS_ROLE t3, LINK t2 WHERE ((t3.ACCESS_ROLE_ID IN (?,?)) AND (t2.LINK_ID = t3.LINK_ID))) AND t0.LINK_ID IN (SELECT t4.LINK_ID FROM LINK_ACCESS_ROLE t5, LINK t4 WHERE ((t5.ACCESS_ROLE_ID IN (?,?)) AND (t4.LINK_ID = t5.LINK_ID)))) AND (t0.LINK_ID = t1.PARENT_LINK_ID))
bind => [4 parameters bound]
SELECT LINK_ID, CREATED_BY_ID, CREATED_DATE, LAST_MODIFIED_BY_ID, LAST_MODIFIED_DATE, NAME, UI_SREF, PARENT_LINK_ID FROM LINK WHERE (PARENT_LINK_ID = ?)
bind => [1 parameter bound]
SELECT LINK_ID, CREATED_BY_ID, CREATED_DATE, LAST_MODIFIED_BY_ID, LAST_MODIFIED_DATE, NAME, UI_SREF, PARENT_LINK_ID FROM LINK WHERE (PARENT_LINK_ID = ?)
bind => [1 parameter bound]
我为每个 child 获取一个与获取的 parent 相关的查询,无论它是否具有访问角色。
我想获取 parents 及其具有访问权限的 childs 而不是所有与 parent 相关的 childs。
获取父实体并使用基于某些条件 的条目子集填充其中一个集合的唯一方法是使用 Hibernate 的专有过滤器。
我不确定其他 JPA 提供商是否也提供了一些专有解决方案,但 JPA 本身并不直接提供这个。
您首先需要使用 @FilterDef
注册过滤器定义,然后您需要使用 属性.
@Filter
引用过滤器定义
这里困难的部分是您不能依赖 Spring 数据的 @Query
或它们的存储库实现生成过程来提供帮助。您将需要使用真正的实现,以便您可以在查询父实体之前手动启用此休眠过滤器。
Filter filter = session.enableFilter( "link-with-restrictions-by-roles" );
filter.setParameter( "roles", yourRolesList );
return session.createQuery( ... ).getResultList();
文档详细描述了 @Filter
和 @FilterDef
的用法。您还可以找到我的另一个 post,我在其中提供了更多实现细节