diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java index fca15d8e5..afc2c937e 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -15,6 +15,7 @@ */ package org.springframework.samples.petclinic.owner; +import org.springframework.samples.petclinic.visit.VisitRepository; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -40,10 +41,12 @@ class OwnerController { private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; private final OwnerRepository owners; + private VisitRepository visits; - public OwnerController(OwnerRepository clinicService) { + public OwnerController(OwnerRepository clinicService, VisitRepository visits) { this.owners = clinicService; + this.visits = visits; } @InitBinder @@ -126,7 +129,11 @@ class OwnerController { @GetMapping("/owners/{ownerId}") public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { ModelAndView mav = new ModelAndView("owners/ownerDetails"); - mav.addObject(this.owners.findById(ownerId)); + Owner owner = this.owners.findById(ownerId); + for (Pet pet : owner.getPets()) { + pet.setVisitsInternal(visits.findByPetId(pet.getId())); + } + mav.addObject(owner); return mav; } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java index 7ded757bd..0bd04b772 100755 --- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java @@ -17,20 +17,19 @@ package org.springframework.samples.petclinic.owner; import java.time.LocalDate; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; 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; import javax.persistence.Table; +import javax.persistence.Transient; import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; @@ -61,7 +60,7 @@ public class Pet extends NamedEntity { @JoinColumn(name = "owner_id") private Owner owner; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "petId", fetch = FetchType.EAGER) + @Transient private Set visits = new LinkedHashSet<>(); public void setBirthDate(LocalDate birthDate) { @@ -95,8 +94,8 @@ public class Pet extends NamedEntity { return this.visits; } - protected void setVisitsInternal(Set visits) { - this.visits = visits; + protected void setVisitsInternal(Collection visits) { + this.visits = new LinkedHashSet<>(visits); } public List getVisits() { diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java index d4d674dc7..c6dfc7fc7 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java @@ -15,15 +15,20 @@ */ package org.springframework.samples.petclinic.owner; +import java.util.Map; + +import javax.validation.Valid; + import org.springframework.samples.petclinic.visit.Visit; import org.springframework.samples.petclinic.visit.VisitRepository; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import java.util.Map; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; /** * @author Juergen Hoeller @@ -62,6 +67,7 @@ class VisitController { @ModelAttribute("visit") public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map model) { Pet pet = this.pets.findById(petId); + pet.setVisitsInternal(this.visits.findByPetId(petId)); model.put("pet", pet); Visit visit = new Visit(); pet.addVisit(visit); diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java index c1ba09364..5084f4245 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -16,8 +16,29 @@ package org.springframework.samples.petclinic.owner; +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; + +import org.assertj.core.util.Lists; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.samples.petclinic.visit.Visit; +import org.springframework.samples.petclinic.visit.VisitRepository; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.mockito.BDDMockito.given; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -25,19 +46,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; -import org.assertj.core.util.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.samples.petclinic.owner.Owner; -import org.springframework.samples.petclinic.owner.OwnerController; -import org.springframework.samples.petclinic.owner.OwnerRepository; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; - /** * Test class for {@link OwnerController} * @@ -55,6 +63,9 @@ public class OwnerControllerTests { @MockBean private OwnerRepository owners; + @MockBean + private VisitRepository visits; + private Owner george; @Before @@ -66,7 +77,18 @@ public class OwnerControllerTests { george.setAddress("110 W. Liberty St."); george.setCity("Madison"); george.setTelephone("6085551023"); + Pet max = new Pet(); + PetType dog = new PetType(); + dog.setName("dog"); + max.setId(1); + max.setType(dog); + max.setName("Max"); + max.setBirthDate(LocalDate.now()); + george.setPetsInternal(Collections.singleton(max)); given(this.owners.findById(TEST_OWNER_ID)).willReturn(george); + Visit visit = new Visit(); + visit.setDate(LocalDate.now()); + given(this.visits.findByPetId(max.getId())).willReturn(Collections.singletonList(visit)); } @Test @@ -189,6 +211,24 @@ public class OwnerControllerTests { .andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St.")))) .andExpect(model().attribute("owner", hasProperty("city", is("Madison")))) .andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023")))) + .andExpect(model().attribute("owner", hasProperty("pets", not(empty())))) + .andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher>() { + + @Override + public boolean matches(Object item) { + @SuppressWarnings("unchecked") + List pets = (List) item; + Pet pet = pets.get(0); + if (pet.getVisits().isEmpty()) { + return false; + } + return true; + } + + @Override + public void describeTo(Description description) { + description.appendText("Max did not have any visits"); + }}))) .andExpect(view().name("owners/ownerDetails")); }