The JPA specification has the concept of named queries which is an attempt to ‘Don’t Repeat Yourself’ (DRY), but in my opinion it is more a ‘Mistake By Specification’.
The fact that a query is written as a string, and therefore is not compiler checkable, is a missed chance (solutions like QueryDSL offer great alternatives here), but not the point I would like to make. My issue is with the ‘named’ part.
The link to named queries above has the following example:
@NamedQuery( name="findAllEmployeesByFirstName", queryString="SELECT OBJECT(emp) FROM Employee emp WHERE emp.firstName = :firstname" )
What you see here is that there is a definition of a query (usually located at the top of the Entity class) and somewhere else the query is used to read employees from the database, like so:
Query queryEmployeesByFirstName = em.createNamedQuery("findAllEmployeesByFirstName"); queryEmployeeByFirstName.setParameter("firstName", "John"); Collection employees = queryEmployeesByFirstName.getResultList();
The problem is that the named query in no way enforces or even specifies the parameters it requires. In this case it requires one, and its name of course suggest that, but this is a very thin and unstable relation, and not something I would like to base the stability of my code upon. After all, we all know how easy the name may go out-of-sync to the contents of the query. (more…)