|
Project Information
Featured
Links
|
LIQUidFORM stands for Language Integrated QUeries For Object Relational Mapping and is a Java library that provides a Java Domain Specific Language for building type-safe and refactoring proof JPA queries. The project draws its inspiration from the LINQ project, but its aim is only to help in writting JPA queries against your domain model. See the Scope section for a thorough understanding of what LIQUidFORM is and what it is not. The ProblemHave you ever created a domain model and related JPA queries in your favorite IDE, just to find that you can't refactor it ? Suppose you have the following persistent class : @Entity
public class Person {
private String firstName;
private String surname;
public String getFirstName() {
return firstName;
}
public String getSurname() {
return surname;
}
// setters omitted
}and somewhere in your code, you query the model using for example List people = em.createQuery(
"SELECT FROM Person p WHERE p.surname LIKE 'Smith%'")
.getResultList();
Thanks to modern IDEs, if you ever happen to change the attribute surname to let's say lastName you'll update all java references but not the JPA query string ! Thus you'll end up querying for a surname property that doesn't exist anymore, a bug that will hopefully be detected early, but isn't it sad that the query did not get refactored ? The SolutionLIQUidFORM attempts to solve just that (and a little more). Its aim is to capture your intent when creating the query, so that when you change Person.getSurname() to Person.getLastName(), the query string gets updated as well. Here is how it goes : Person p = LiquidForm.use(Person.class, "p");
List people = em.createQuery(
select(p).from(Person.class).as(p).where(like(p.getSurname(), "Smith%")).toString())
.getResultList();As you can see, the framework offers a syntax that is very similar to the JPA query syntax. As a matter of fact, LIQUidFORM does very little : it just constructs a String representation of your query, just like you would by hand, that is in turn passed to your JPA engine of choice. But because in that construct p.getSurname() is an actual method call to the method named getSurname on the type Person, it will get refactored when you change surname to lastName. Of course, you also get other direct indications from your IDE when you perform other kinds of refactorings. For example, if you happen to delete the Person type, you'll be granted by a compile time error for sure. Something that would have gone unnoticed otherwise ! Additional benefitsBecause your queries are now built using actual java code, you get strong type safety. This manifests itself eg. when constructing WHERE clauses : // Won't compile if Person.age is a number select(p).from(Person.class).as(p).where(like(p.getAge(), "some string")) This support is not perfect, but that's still better than the plain string syntax that you're used to... ScopeIt is important to understand the following about LIQUidFORM's aim :
Status
|