Java Reference
In-Depth Information
The
find
method works by inspecting the details of the entity class passed in as the first
parameter and generating a
SELECT
statement to retrieve the entity data. This generated
SELECT
statement is populated with the primary key values specified in the second para-
a
SELECT
statement that looks something like this:
SELECT * FROM SELLERS WHERE seller_id = 1
Note that if an entity instance matching the specified key doesn't exist in the database,
the
find
method won't throw any exceptions. Instead, the
EntityManager
will return
null
or an empty entity, and your application must handle this situation. It isn't strictly
necessary to call the
find
method in a transactional context. But the retrieved entity is de-
tached unless a transaction context is available, so it's generally advisable to call the
find
method inside a transaction. One of the most important features of the
find
method is
that it utilizes
EntityManager
caching. If your persistence provider supports caching
and the entity already exists in the cache, then the
EntityManager
returns a cached in-
stance of the entity instead of retrieving it from the database. Most persistence providers
like Hibernate and Oracle TopLink support caching, so you can more or less count on this
extremely valuable optimization.
There's one more important JPA feature geared toward application optimization—lazy and
eager loading. The generated
SELECT
statement in the example attempts to retrieve all of
the entity field data when the
find
method is invoked. In general, this is exactly what will
happen for entity retrieval because it's the default behavior for JPA. But in some cases, this
isn't desirable behavior. Fetch modes allow you to change this behavior to optimize applic-
ation performance when needed.
Entity fetch modes
We briefly mentioned fetch modes in previous chapters but haven't discussed them in great
detail. Discussing entity retrieval is an ideal place to fully explore fetch modes.
As we suggested, the
EntityManager
normally loads all entity instance data when an
entity is retrieved from the database. In ORM-speak, this is called eager fetching, or eager
loading. If you've ever dealt with application performance problems due to premature or
inappropriate caching, you probably already know that eager fetching isn't always a good
thing. The classic example we used in previous chapters is loading large binary objects