Java Reference
In-Depth Information
But again, because the testing infrastructure is already in place, it's easy to repro-
duce the problem. All we have to do is add a new
testGetUserByIdWithTelephones()
method:
6
@Test
@DataSets(setUpDataSet="/user-with-telephones.xml")
public void testGetUserByIdWithTelephones() throws Exception {
beginTransaction();
long id = ELFunctionMapperImpl.getId(User.class);
User user = dao.getUserById(id);
commitTransaction(true);
assertUserWithTelephones(user);
}
What about the issue itself? The solution is to use the
distinct
keyword in the query,
as shown here:
jql = "select distinct(user) from User user left join fetch " +
"user.telephones where id = ?";
Notice that having both
testGetUserByIdWithTelephone()
and
testGetUserById-
WithTelephones()
methods is redundant and would make the test cases harder to
maintain. Once we add
testGetUserByIdWithTelephones()
, we can safely remove
testGetUserByIdWithTelephone()
and its companion helpers
newUserWithTele-
phone()
and
assertUserWithTelephone()
, which would be replaced by
newUser-
WithTelephones()
and
assertUserWithTelephones()
, respectively.
Listing 18.21 shows the final version of
UserDaoJpaImpl
, with all issues fixed.
Listing 18.21
Final (and improved) version of
UserDaoJpaImpl
[...]
public class
UserDaoJpaImpl
implements
UserDao {
public void
addUser(User user) {
if ( user ==
null
) {
throw new
IllegalArgumentException("user cannot be null");
}
entityManager.persist(user);
}
public
User getUserById(
long
id) {
String jql = "select distinct(user) from User user left join fetch " +
"user.telephones where id = ?";
Query query = entityManager.createQuery(jql);
query.setParameter(1, id);
@SuppressWarnings("unchecked")
List<User> users = query.getResultList();
// sanity check assertion
6
We also need a new
assertUserWithTelephones()
method on
EntitiesHelper
and a new user-with-
telephones.xml dataset, but because they're very similar to the existing method and dataset, they aren't
shown here.