J'ai une classe abstraite DAO qui utilise des types paramétrés À titre d'exemple, imaginez l'entité suivante 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.
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;
}
}
// ...
}
4 Réponses :
La méthode la plus simple consiste à transmettre le nom de la requête sur le constructeur de l'abstrait DAO: 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;
}
}
La manière évidente serait de passer des valeurs de classes concrètes à la superclasse abstraite à l'aide de ou comme argument de constructeur: p> < Pré> xxx pré> Bien que cela nécessite une nommage cohérente de paramètres de requête pour différentes entités. P> Notez également les améliorations mineures de ces extraits. P> P> abstrait code> méthode
La convention de dénomination pour les requêtes nommées est généralement
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")
)