2017-03-06 4 views
0

Link.javaGespannt Kind holen, wenn Daten Mutterfeder JPA Laden

@Entity 
@Table(name = "LINK") 
@AttributeOverride(name="id", [email protected](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; 
    } 


} 

LinkRepository .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

erzeugten Abfragen:

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] 

Ich erhalte eine Abfrage für jedes Kind, das mit dem abgerufenen Elternteil verwandt ist. Unabhängig davon, ob es die Zugriffsrolle hat oder nicht.

Ich möchte die Eltern und ihre Childs abrufen, die eine Zugriffsrolle haben, nicht alle Childs, die zu diesem Elternteil gehören.

+0

Sie haben fetch = FetchType.EAGER. Für was denkst du ist es? Es teilt JPA mit, dass jedes Mal, wenn ein Link geladen wird, seine Kinder geladen werden müssen. –

+0

Das stimmt. Wie kann ich sie basierend auf ihrer Zugriffsrolle abrufen, während ich dies versuchte? –

Antwort

0

Die einzige Methode, mit der Sie eine übergeordnete Entität abrufen und eine ihrer Sammlungen mit einer Teilmenge von Einträgen basierend auf einigen Kriterien füllen können, ist die Verwendung der proprietären Hibernate-Filter.

Ich bin nicht sicher, ob die anderen JPA-Anbieter auch eine proprietäre Lösung bieten, aber JPA selbst bietet dies nicht direkt an.

Zuerst müssen Sie eine Filterdefinition unter Verwendung von @FilterDef registrieren und dann müssen Sie die Definition des Filters mit der @Filter auf Ihrer Sammlung Eigenschaft verweisen.

Der schwierige Teil hier ist, dass Sie nicht auf @Query Spring-Daten oder ihre Repository-Implementierung Generierungsprozess helfen können. Sie müssen eine echte Implementierung verwenden, damit Sie diesen Hibernate-Filter manuell aktivieren können, bevor Sie die übergeordnete Entität abfragen.

Filter filter = session.enableFilter("link-with-restrictions-by-roles"); 
filter.setParameter("roles", yourRolesList); 
return session.createQuery(...).getResultList(); 

Die Dokumentation beschreibt die Verwendung von @Filter und @FilterDef im Detail. Sie können auch einen anderen Beitrag von mir finden, wo ich etwas mehr Implementierungsdetails here gebe.

Verwandte Themen