Java Reference
In-Depth Information
User user = dao.getUserById(id);
commitTransaction(true);
assertNull(user);
}
}
Notice that the workflow for
getUserById()
negative cases is the same for both sce-
narios, so we used a private helper method (
getUserReturnsNullTest()
) on both.
Now we have a fully tested
DAO
implementation, right? Well, not really. Once you
put this code into production (or hand it to the
QA
team for functional testing), a few
bugs are bound to happen.
To start with, the first time someone calls
UserFacade.getUserById()
(which in
turn calls the
DAO
method; see listing 18.4) on a user that has at least one telephone
and tries to call
user.getTelephones()
, the following exception will occur:
org.hibernate.LazyInitializationException: failed to lazily initialize
➥
a collection of role: com.manning.jia.chapter18.model.User.telephones,
➥
no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazy
➥
InitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.
➥
throwLazyInitializ ationExceptionIfNotConnected
➥
(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.
➥
readSize(Abstract PersistentCollection.java:97)
at org.hibernate.collection.PersistentBag.size(PersistentBag.java:225)
at com.manning.jia.chapter18.model.EntitiesHelper.
➥
assertUserWithTelephones(EntitiesHelper.java:39)
at com.manning.jia.chapter18.model.EntitiesHelper.assertUserWithTelephone
➥
(EntitiesHelper.java:29)
at com.manning.jia.chapter18.dao.UserDaoJpaImplTest.testGetUserByIdWith
➥
Telephone(UserDaoJpaImplTest.java:62)
When that happens, you, the developer, are going to curse Hibernate,
JPA
,
ORM
, and
(with a higher intensity) this topic's authors: you followed our advice and created
unit tests for both the Façade and
DAO
classes in isolation, but once one called the
other in real life, a
JPA
exception arose! Unfortunately, situations like these are com-
mon. Just because you wrote test cases, it doesn't mean your code is bug free. But on
the bright side, because you have a test case, it's much easier to reproduce and fix the
issue. In this case, the exception is caused because the
User
/
Telephone
relationship
is defined as lazy, which means the telephones were not fetched by the
JPA
queries
and are loaded on demand when
getTelephones()
is called. But if that method is
called outside the
JPA
context, an exception is thrown. So, to simulate the problem in
the test case, we change
testGetUserByIdWithTelephone()
to clear the context after
committing the transaction:
@Test
@DataSets(setUpDataSet="/user-with-telephone.xml")
public void testGetUserByIdWithTelephone() throws Exception {
beginTransaction();
long id = ELFunctionMapperImpl.getId(User.class);