Skip to content
Snippets Groups Projects
Commit f44e3834 authored by Mic's avatar Mic
Browse files

fixed lazy loading issues

also renamed some local variables in Unit tests
parent 56c76719
No related branches found
No related tags found
No related merge requests found
......@@ -9,6 +9,7 @@ import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
......@@ -41,7 +42,7 @@ public class Pet extends NamedEntity {
@JoinColumn(name = "owner_id")
private Owner owner;
@OneToMany(cascade=CascadeType.ALL, mappedBy="pet")
@OneToMany(cascade=CascadeType.ALL, mappedBy="pet", fetch=FetchType.EAGER)
private Set<Visit> visits;
......
......@@ -120,16 +120,16 @@ public class JdbcOwnerRepositoryImpl implements OwnerRepository {
@Transactional
public void save(Owner owner) throws DataAccessException {
BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(owner);
if (owner.isNew()) {
Number newKey = this.insertOwner.executeAndReturnKey(
new BeanPropertySqlParameterSource(owner));
Number newKey = this.insertOwner.executeAndReturnKey(parameterSource);
owner.setId(newKey.intValue());
}
else {
this.namedParameterJdbcTemplate.update(
"UPDATE owners SET first_name=:firstName, last_name=:lastName, address=:address, " +
"city=:city, telephone=:telephone WHERE id=:id",
new BeanPropertySqlParameterSource(owner));
parameterSource);
}
}
......
......@@ -6,6 +6,7 @@ import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.hibernate.Hibernate;
import org.springframework.samples.petclinic.Owner;
import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.stereotype.Repository;
......@@ -32,13 +33,19 @@ public class JpaOwnerRepositoryImpl implements OwnerRepository {
@SuppressWarnings("unchecked")
public Collection<Owner> findByLastName(String lastName) {
Query query = this.em.createQuery("SELECT owner FROM Owner owner WHERE owner.lastName LIKE :lastName");
// using 'join fetch' because a single query should load both owners and pets
// using 'left join fetch' because it might happen that an owner does not have pets yet
Query query = this.em.createQuery("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName");
query.setParameter("lastName", lastName + "%");
return query.getResultList();
}
public Owner findById(int id) {
return this.em.find(Owner.class, id);
// using 'join fetch' because a single query should load both owners and pets
// using 'left join fetch' because it might happen that an owner does not have pets yet
Query query = this.em.createQuery("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id");
query.setParameter("id", id);
return (Owner) query.getSingleResult();
}
......
......@@ -29,7 +29,7 @@ public class JpaVetRepositoryImpl implements VetRepository {
@SuppressWarnings("unchecked")
public Collection<Vet> findAll() {
return this.em.createQuery("SELECT vet FROM Vet vet ORDER BY vet.lastName, vet.firstName").getResultList();
return this.em.createQuery("SELECT vet FROM Vet vet join fetch vet.specialties ORDER BY vet.lastName, vet.firstName").getResultList();
}
}
......@@ -97,22 +97,13 @@ public abstract class AbstractOwnerRepositoryTests {
}
@Test @Transactional
public void findOwner() {
Owner o1 = this.ownerRepository.findById(1);
assertTrue(o1.getLastName().startsWith("Franklin"));
Owner o10 = this.ownerRepository.findById(10);
assertEquals("Carlos", o10.getFirstName());
// XXX: Add programmatic support for ending transactions with the
// TestContext Framework.
// Check lazy loading, by ending the transaction:
// endTransaction();
public void findSingleOwner() {
Owner owner1 = this.ownerRepository.findById(1);
assertTrue(owner1.getLastName().startsWith("Franklin"));
Owner owner10 = this.ownerRepository.findById(10);
assertEquals("Carlos", owner10.getFirstName());
// Now Owners are "disconnected" from the data store.
// We might need to touch this collection if we switched to lazy loading
// in mapping files, but this test would pick this up.
o1.getPets();
assertEquals(owner1.getPets().size(), 1);
}
@Test @Transactional
......
......@@ -97,51 +97,51 @@ public abstract class AbstractPetRepositoryTests {
public void getPetTypes() {
Collection<PetType> petTypes = this.petRepository.findPetTypes();
PetType t1 = EntityUtils.getById(petTypes, PetType.class, 1);
assertEquals("cat", t1.getName());
PetType t4 = EntityUtils.getById(petTypes, PetType.class, 4);
assertEquals("snake", t4.getName());
PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1);
assertEquals("cat", petType1.getName());
PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4);
assertEquals("snake", petType4.getName());
}
@Test
public void findPet() {
Collection<PetType> types = this.petRepository.findPetTypes();
Pet p7 = this.petRepository.findById(7);
assertTrue(p7.getName().startsWith("Samantha"));
assertEquals(EntityUtils.getById(types, PetType.class, 1).getId(), p7.getType().getId());
assertEquals("Jean", p7.getOwner().getFirstName());
Pet p6 = this.petRepository.findById(6);
assertEquals("George", p6.getName());
assertEquals(EntityUtils.getById(types, PetType.class, 4).getId(), p6.getType().getId());
assertEquals("Peter", p6.getOwner().getFirstName());
Pet pet7 = this.petRepository.findById(7);
assertTrue(pet7.getName().startsWith("Samantha"));
assertEquals(EntityUtils.getById(types, PetType.class, 1).getId(), pet7.getType().getId());
assertEquals("Jean", pet7.getOwner().getFirstName());
Pet pet6 = this.petRepository.findById(6);
assertEquals("George", pet6.getName());
assertEquals(EntityUtils.getById(types, PetType.class, 4).getId(), pet6.getType().getId());
assertEquals("Peter", pet6.getOwner().getFirstName());
}
@Test @Transactional
public void insertPet() {
Owner o6 = this.ownerRepository.findById(6);
int found = o6.getPets().size();
Owner owner6 = this.ownerRepository.findById(6);
int found = owner6.getPets().size();
Pet pet = new Pet();
pet.setName("bowser");
Collection<PetType> types = this.petRepository.findPetTypes();
pet.setType(EntityUtils.getById(types, PetType.class, 2));
pet.setBirthDate(new DateTime());
o6.addPet(pet);
assertEquals(found + 1, o6.getPets().size());
owner6.addPet(pet);
assertEquals(found + 1, owner6.getPets().size());
// both storePet and storeOwner are necessary to cover all ORM tools
this.petRepository.save(pet);
this.ownerRepository.save(o6);
o6 = this.ownerRepository.findById(6);
assertEquals(found + 1, o6.getPets().size());
this.ownerRepository.save(owner6);
owner6 = this.ownerRepository.findById(6);
assertEquals(found + 1, owner6.getPets().size());
}
@Test @Transactional
public void updatePet() throws Exception {
Pet p7 = this.petRepository.findById(7);
String old = p7.getName();
p7.setName(old + "X");
this.petRepository.save(p7);
p7 = this.petRepository.findById(7);
assertEquals(old + "X", p7.getName());
Pet pet7 = this.petRepository.findById(7);
String old = pet7.getName();
pet7.setName(old + "X");
this.petRepository.save(pet7);
pet7 = this.petRepository.findById(7);
assertEquals(old + "X", pet7.getName());
}
}
......@@ -90,17 +90,16 @@ public abstract class AbstractVisitRepositoryTests {
@Test @Transactional
public void insertVisit() {
Pet p7 = this.petRepository.findById(7);
int found = p7.getVisits().size();
Pet pet7 = this.petRepository.findById(7);
int found = pet7.getVisits().size();
Visit visit = new Visit();
p7.addVisit(visit);
pet7.addVisit(visit);
visit.setDescription("test");
// both storeVisit and storePet are necessary to cover all ORM tools
this.visitRepository.save(visit);
this.petRepository.save(p7);
// assertTrue(!visit.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
p7 = this.petRepository.findById(7);
assertEquals(found + 1, p7.getVisits().size());
this.petRepository.save(pet7);
pet7 = this.petRepository.findById(7);
assertEquals(found + 1, pet7.getVisits().size());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment