Donc, après une pause de plus de 10 ans, je reviens en Java et j'essaye des trucs avec des génériques JPA et Java. J'ai créé une requête JPA findAll(other)
à base de génériques
SELECT * FROM source WHERE other_id = other.id;
C'est là que je suis en train de faire. Cela fonctionne, mais je me demande s’il existe une méthode plus efficace et plus propre. Utiliser ManagedType
était difficile, et il n’ya pas beaucoup de documentation complète ou d’exemples simples.
J'ai décidé de garder mon code aussi générique que possible (sans jeu de mots) donc j'utilise JPA2.
C'est la racine de toutes les classes d'entité. Je n'en ai probablement pas besoin, mais cela m'empêche d'avoir des erreurs élémentaires.
import Java.io.Serializable;
public abstract class DomainObject implements Serializable {
private static final long serialVersionUID = 1L;
public abstract void setId(Long id);
public abstract Long getId();
}
C'est la classe abstraite DAO. J'étends cela pour les classes d'implémentation car j'ai besoin d'être plus spécifique pour faire d'autres activités - en m'assurant surtout que les jeux paresseux sont chargés.
public abstract class GenericDAOImpl<T extends DomainObject, T2 extends DomainObject> implements GenericDAO<T, T2> {
private Class<T> type;
@PersistenceContext
protected EntityManager entityManager;
public GenericDAOImpl(Class<T> type) {
super();
this.type = type;
}
... save and delete classes go here
@Override
public List<T> findAll(T2 where) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type);
Root<T> rootQuery = criteriaQuery.from(type);
if (where != null) {
EntityType<T> entity = entityManager.getMetamodel().entity(type);
SingularAttribute<? super T, ?> attribute = null;
for (SingularAttribute<? super T, ?> singleAttribute: entity.getSingularAttributes()) {
// loop through all attributes that match this class
if (singleAttribute.getJavaType().equals(where.getClass())) {
// winner!
attribute = singleAttribute;
break;
}
}
// where t.object = object.getID()
criteriaQuery.where(criteriaBuilder.equal(rootQuery.get(attribute), where));
}
criteriaQuery.select(rootQuery);
TypedQuery<T> query = entityManager.createQuery(criteriaQuery);
// need this to make sure we have a clean list?
// entityManager.clear();
return query.getResultList();
}
Aucune suggestion? Si quelque chose, je veux ceci dehors là afin que d'autres personnes puissent l'utiliser.
Chapeau bas à Adam Bien si vous ne voulez pas utiliser createQuery
avec un String
et que vous voulez un type de sécurité:
@PersistenceContext EntityManager em; public List<ConfigurationEntry> allEntries() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<ConfigurationEntry> cq = cb.createQuery(ConfigurationEntry.class); Root<ConfigurationEntry> rootEntry = cq.from(ConfigurationEntry.class); CriteriaQuery<ConfigurationEntry> all = cq.select(rootEntry); TypedQuery<ConfigurationEntry> allQuery = em.createQuery(all); return allQuery.getResultList(); }
http://www.adam-bien.com/roller/abien/entry/selecting_all_jpa_entities_as
J'ai trouvé cette page très utile
public abstract class GenericDAOWithJPA<T, ID extends Serializable> {
private Class<T> persistentClass;
//This you might want to get injected by the container
protected EntityManager entityManager;
@SuppressWarnings("unchecked")
public GenericDAOWithJPA() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
@SuppressWarnings("unchecked")
public List<T> findAll() {
return entityManager.createQuery("Select t from " + persistentClass.getSimpleName() + " t").getResultList();
}
}
vous pouvez également utiliser une requête nommée findAll nommée findAll pour toutes vos entités et l'appeler dans votre FindAll générique avec entityManager.createNamedQuery(persistentClass.getSimpleName()+"findAll").getResultList();
}
`
Cela fonctionnera et si vous avez besoin de l'instruction where, vous pouvez l'ajouter comme paramètre.
class GenericDAOWithJPA<T, ID extends Serializable> {
.......
public List<T> findAll() {
return entityManager.createQuery("Select t from " + persistentClass.getSimpleName() + " t").getResultList();
}
}