web-dev-qa-db-fra.com

Critères JPA 2 Recherche dans le chemin de recherche

Avec la méthode de jonction JPA 2 Criteria, je peux effectuer les opérations suivantes:

    //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();

Comment puis-je faire la même chose avec la méthode fetch, je m'attendais à ce que l'interface Fetch ait la méthode get pour la navigation par chemin, mais ce n'est pas le cas:

    //Fetch Join Example

    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(p.get(Player_.age), age)); //This leads to compilation error there is no such method get in interface Fetch
    TypedQuery<Team> q = entityManager.createQuery(cq);
    List<Team> result = q.getResultList();

Selon la documentation Hiberante, fetch renvoie un objet Join incorrect. http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/querycriteria.html#querycriteria-from-fetch

25
Alfredo Osorio

D'accord avec vous sur cette méthode et sur le fait que vous vous attendez à ce qu'elle permette ce que vous dites. Une autre option serait

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

c’est-à-dire faire une join(), ajouter une fetch() pour cela, puis utiliser la jointure. Cela est illogique et ne fait qu’ajouter à la nature peu élégante des critères de l’APP, mais devrait de toute façon être une solution de contournement

19
DataNucleus

Cela fonctionne pour moi en utilisant 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();

Certes, cela pourrait briser la portabilité, mais dans notre cas, nous avons utilisé les fonctionnalités exclusives d’hibernate d’autres.

* C'est très étrange parce que la documentation d'hibernation ne montre pas cet exemple.

Pour le comprendre, regardez cette 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);
}
10
Eduardo Fabricio

Tout ce que vous avez à faire est le suivant: 

1- Do Fetch ..__ 2- Ensuite, suivez le chemin qui vous mène à l'endroit souhaité.

Dans ton cas: 

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)); 
4
Haytham Salhi

Depuis JPA 2.1, les graphiques d'entités dynamiques peuvent être utilisés pour extraire des requêtes de critères, en utilisant join () au lieu de fetch (). De l'exemple dans la 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();

Si ce:

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

est remplacé par ceci:

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

alors tous les joueurs seront désirés.

3
Darren Reimer

J'utilise JPA 2.1 avec Hibernate 4.3.7 et les instructions ci-dessous me conviennent parfaitement. Il ne semble même pas si moche.

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

moche mais:

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

va produire singel rejoindre avec chercher dans sql mais est un bidule laid qui fonctionne JBoss6.1 hibernate

0
Jernej