11
votes

Résumé des requêtes nommées dans un Abstrait JPA Dao

J'ai une classe abstraite DAO qui utilise des types paramétrés E code> (entité) et k code> (clé primaire). Dans chaque entité, j'ai un @NamedQuery code>. Je tiens à appeler de manière dynamique cette requête nommée sans connaître son nom exact et son nom de paramètre.

À titre d'exemple, imaginez l'entité suivante Ville code> p>

public abstract class AbstractDao<E, K> implements Dao<E, K> {

    @PersistenceContext
    protected EntityManager entityManager;
    protected Class<E> entityClass;

    protected AbstractDao(Class<E> entityClass) {
        this.entityClass = entityClass; 
    }

    @Override
    public E findByName(String name) {
        try {
            return (E) entityManager
                .createNamedQuery("findCityByName")
                .setParameter("CityName", name)
                .getSingleResult();
        } catch(Exception e) {
            return null;
        }
    }

    // ...
}


0 commentaires

4 Réponses :


1
votes

La méthode la plus simple consiste à transmettre le nom de la requête sur le constructeur de l'abstrait DAO: xxx pré>

puis définissez une chaîne finale publique statique en ville pour contenir le nom: P >

public enum NamedEntityType {
    CITY(City.class, "findCityByname"), 
    PERSON(Person.class, "findPersonByname");

    private final Class<?> entityClass;

    private final String findByNameQueryName;

    private NamedEntityType(Class<?> entityClass, String findByNameQueryName) {
         this.entityClass = entityClass;
         this.findByNameQueryName = findByNameQueryName;
    }

    public Class<?> getEntityClass() {
        return entityClass;
    }

    public String getFindByNameQueryName() {
        return findByNameQueryName;
    }
}


0 commentaires

0
votes

La manière évidente serait de passer des valeurs de classes concrètes à la superclasse abstraite à l'aide de abstrait méthode xxx

ou comme argument de constructeur: < Pré> xxx

Bien que cela nécessite une nommage cohérente de paramètres de requête pour différentes entités.

Notez également les améliorations mineures de ces extraits.


0 commentaires

13
votes

La convention de dénomination pour les requêtes nommées est généralement .Findby , "City.FindbyName" dans votre exemple, je vais donc essayer de changer les requêtes nommées pour suivre ce modèle. . Le paramètre de cette requête doit alors également avoir le même nom, ou vous pouvez utiliser des paramètres de position. Votre méthode de recherche serait alors devenu xxx


0 commentaires

0
votes

Ce que vous semblez essentiellement vouloir, c'est annoter les annotations qui définissent les requêtes nommées, de manière à pouvoir découvrir par programme ce que la requête "FindbyName" est (et d'autres requêtes possibles).

Puisque ce n'est pas Possible en Java, vous pouvez utiliser le fait que @NameDQuéry prend en charge les astuces requises, qui sont définies comme étant spécifiques au fournisseur. Les notes inconnues sont ignorées. Vous pouvez ajouter vos propres données ici, que le générique DAO peut lire à partir de EntityClass code>: p>

@NamedQuery(
    name="findCityByname",
    query="FROM CITY c WHERE name = :CityName",
    hints=@QueryHint(name="genericDAO.type", value="findByName")
)


0 commentaires