JPA 2 Criteria Fetch Path Navigation

前端 未结 6 662
我寻月下人不归
我寻月下人不归 2020-12-08 14:38

With JPA 2 Criteria Join method I can do the following:

    //Join Example (default inner join)
    int age = 25;
    CriteriaBuilder cb = entityManager.getC         


        
相关标签:
6条回答
  • 2020-12-08 15:03

    Agree with you about that method, and the fact that you would expect it to allow what you say. Another option would be

    Join<Team, Player> p = t.join(Team_.players);
    t.fetch(Team_.players);
    c.select(t).where(cb.equal(p.get(Player_.age), age));
    

    i.e do a join(), add a fetch() for it, and then make use of the join. This is illogical and only adds to the inelegant nature of JPA Criteria, but anyway, ought to be a workaround

    0 讨论(0)
  • 2020-12-08 15:03

    All you have to do is the following:

    1- Do Fetch. 2- Then, go over the path to where you want.

    In your case:

    int age = 25;
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Team> cq = cb.createQuery(Team.class);
    Root<Team> t = cq.from(Team.class);
    Fetch<Team,Player> p = t.fetch(Team_.players);
    cq.where(cb.equal(t.get("player").get("age"), age)); 
    
    0 讨论(0)
  • 2020-12-08 15:05

    Beginning with JPA 2.1, dynamic entity graphs can be used for fetching in criteria queries, while using join() instead of fetch(). From the example in the question:

    //Join Example (default inner join)
    int age = 25;
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Team> c = cb.createQuery(Team.class);
    Root<Team> t = c.from(Team.class);
    Join<Team, Player> p = t.join(Team_.players);
    c.select(t).where(cb.equal(p.get(Player_.age), age));
    TypedQuery<Team> q = entityManager.createQuery(c);
    List<Team> result = q.getResultList();
    

    If this:

    TypedQuery<Team> q = entityManager.createQuery(c);
    

    is replaced with this:

    EntityGraph<Team> fetchGraph = getEntityManager().createEntityGraph(Team.class);
    fetchGraph.addSubgraph(Team_.players);
    TypedQuery<Team> q = entityManager.createQuery(c).setHint("javax.persistence.loadgraph", fetchGraph);
    

    then all players will be eager fetched.

    0 讨论(0)
  • 2020-12-08 15:08

    I am using JPA 2.1 with Hibernate 4.3.7 and the below works for me well. It does not even look that ugly.

    Join<Team,Player> p = (Join) t.fetch(Team_.players);
    
    0 讨论(0)
  • 2020-12-08 15:12

    ugly but:

    Join<Team, Player> p=t.fetch(Team_.players);
    

    will produce singel join with fetch in sql but is a ugly hack that works JBoss6.1 hibernate

    0 讨论(0)
  • 2020-12-08 15:22

    It Works for me using Hibernate Provider.

    //Join Example (default inner join)
    
        int age = 25;
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Team> c = cb.createQuery(Team.class);
        Root<Team> t = c.from(Team.class);
    
        // Join<Team, Player> p = t.join(Team_.players); 
        Join<Team, Player> p = (Join<Team, Player>)t.fetch(Team_.players); 
    
        c.select(t).where(cb.equal(p.get(Player_.age), age));
        TypedQuery<Team> q = entityManager.createQuery(c);
        List<Team> result = q.getResultList();
    

    Certainly, it could broken the portability, but in our case we have been using others hibernate's exclusive features.

    *It is very strange because the hibernate documentation doesn't show this example.

    To grasp it look at this interface.

    /*
     * Hibernate, Relational Persistence for Idiomatic Java
     *
     * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
     * indicated by the @author tags or express copyright attribution
     * statements applied by the authors.  All third-party contributions are
     * distributed under license by Red Hat Inc.
     *
     * This copyrighted material is made available to anyone wishing to use, modify,
     * copy, or redistribute it subject to the terms and conditions of the GNU
     * Lesser General Public License, as published by the Free Software Foundation.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
     * for more details.
     *
     * You should have received a copy of the GNU Lesser General Public License
     * along with this distribution; if not, write to:
     * Free Software Foundation, Inc.
     * 51 Franklin Street, Fifth Floor
     * Boston, MA  02110-1301  USA
     */
    package org.hibernate.ejb.criteria;
    
    import javax.persistence.criteria.Fetch;
    import javax.persistence.criteria.Join;
    
    /**
     * Consolidates the {@link Join} and {@link Fetch} hierarchies since that is how we implement them.
     * This allows us to treat them polymorphically.
    *
    * @author Steve Ebersole
    */
    public interface JoinImplementor<Z,X> extends Join<Z,X>, Fetch<Z,X>, FromImplementor<Z,X> {
        /**
         * {@inheritDoc}
         * <p/>
         * Refined return type
         */
        public JoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
    }
    
    0 讨论(0)
提交回复
热议问题