Java Reference
In-Depth Information
Using the Java Persistence Query Language
If you want to do anything more than find objects by their primary key, you'll need to
use
Java Persistence Query Language (
JPQL
)
:
@Override
public List<Food> getFoodsWhoseNameContains(String foodName,
int maxResults) {
String query = "SELECT f FROM FOOD f WHERE f.name LIKE '%" +
foodName + "%' ORDER BY f.quantity DESC";
Query q = em.createQuery(query);
q.setMaxResults(maxResults);
List<Food> list = q.getResultList();
return list;
}
@Override
public int getFoodCount() {
Query query = em.createQuery("SELECT COUNT(f) FROM FOOD f");
Number count = (Number) query.getSingleResult();
return count.intValue();
}
JPQL
may bring back unpleasant (or pleasant) memories of
SQL
for some of you. In
terms of syntax, it's much like
SQL
, but avoids most vendor-compliance compatibility
issues. It breaks the object-oriented abstraction provided by
JPA
and makes it clear that
there is a database involved in all this.
INITIALIZING THE DATABASE
One slight disadvantage of allowing
JPA
to create all your database tables for you in
memory is that the database will always be completely empty when you start the sys-
tem. This is fine for some applications, but it's not ideal for a food shop that's sup-
posed to have food. Use another Blueprint bean to initialize the database when the
system starts:
<bean
id="populator"
class="fancyfoods.persistence.InventoryPopulater"
init-method="populate"
activation="eager"
>
<property
name="inventory"
ref="inventory" />
</bean>
If you're familiar with
OSG
i bundle activators, you'll recognize that this bean plays a
similar role. It's activated as soon as the bundle starts, rather than waiting to be looked
up or injected into another bean. The advantage over a normal bundle activator is it
can be injected with any other Blueprint reference.
Another advantage of the
InventoryPopulater
over a bundle activator is that an
eager Blueprint bean isn't required to implement any special interface (see the