Construction de requêtes en Java : comment faire le bon choix ?

Dans toutes les applications, il faut à un moment ou un autre, aller requêter en base de données. Certaines requêtes sont relativement simples
mais d'autres peuvent être plus complexes et dans ce cas là, plusieurs frameworks sont disponibles pour écrire ces requêtes.
Parmi toutes les solutions de requêtage disponibles (Spring Data - JPA, Criteria Hibernate, Criteria JPA2, JPQL, QueryDSL), comment faire le bon choix ?