From f9424b548ad476f1cffb7b013ea832d620963925 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 10 Dec 2019 11:21:41 -0500 Subject: [PATCH 01/48] Spring Boot 2.2.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aab683b24..bf5ab1bf6 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.1.RELEASE + 2.2.2.RELEASE petclinic From 5d57e0d5e25fa5ff633719f36f8c4ce67ec1893c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Jan 2020 05:29:11 -0500 Subject: [PATCH 02/48] Re-organise mysql scripts so the app runs without root access It works better that way with test containers and in k8s. --- docker-compose.yml | 5 ++++- src/main/resources/application-mysql.properties | 2 +- .../resources/db/mysql/petclinic_db_setup_mysql.txt | 8 +++++--- src/main/resources/db/mysql/schema.sql | 10 ---------- src/main/resources/db/mysql/user.sql | 7 +++++++ 5 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/db/mysql/user.sql diff --git a/docker-compose.yml b/docker-compose.yml index 0f4a7fc30..5166fe90f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,10 @@ mysql: ports: - "3306:3306" environment: - - MYSQL_ROOT_PASSWORD=petclinic + - MYSQL_ROOT_PASSWORD= + - MYSQL_ALLOW_EMPTY_PASSWORD=true + - MYSQL_USER=petclinic + - MYSQL_PASSWORD=petclinic - MYSQL_DATABASE=petclinic volumes: - "./conf.d:/etc/mysql/conf.d:ro" diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index 38d81f99f..6d54ddad7 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -1,7 +1,7 @@ # database init, supports mysql too database=mysql spring.datasource.url=jdbc:mysql://localhost/petclinic -spring.datasource.username=root +spring.datasource.username=petclinic spring.datasource.password=petclinic # SQL is written to be idempotent so this is safe spring.datasource.initialization-mode=always diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt index 920906687..f6ce6523c 100644 --- a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt +++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt @@ -18,12 +18,14 @@ mysql_1_eedb4818d817 | MySQL init process done. Ready for start up. ... -2) Create the PetClinic database and user by executing the "db/mysql/{schema,data}.sql" - scripts (or set "spring.datasource.initialization-mode=always" the first time you run the app). +2) (Once only) create the PetClinic database and user by executing the "db/mysql/user.sql" + scripts. You can connect to the database running in the docker container using + `mysql -u root -h localhost --protocol tcp`, but you don't need to run the script there + because the petclinic user is already set up if you use the provided `docker-compose.yaml`. 3) Run the app with `spring.profiles.active=mysql` (e.g. as a System property via the command line, but any way that sets that property in a Spring Boot app should work). N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value as it is configured by default. This condition is taken care of by the docker-compose -configuration provided, or by the `schema.sql` if you can run that as root. \ No newline at end of file +configuration provided, or by the `schema.sql` if you can run that as root. diff --git a/src/main/resources/db/mysql/schema.sql b/src/main/resources/db/mysql/schema.sql index 6a9825983..eb5d7d5d0 100644 --- a/src/main/resources/db/mysql/schema.sql +++ b/src/main/resources/db/mysql/schema.sql @@ -1,13 +1,3 @@ -CREATE DATABASE IF NOT EXISTS petclinic; - -ALTER DATABASE petclinic - DEFAULT CHARACTER SET utf8 - DEFAULT COLLATE utf8_general_ci; - -GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc'; - -USE petclinic; - CREATE TABLE IF NOT EXISTS vets ( id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(30), diff --git a/src/main/resources/db/mysql/user.sql b/src/main/resources/db/mysql/user.sql new file mode 100644 index 000000000..60abcee72 --- /dev/null +++ b/src/main/resources/db/mysql/user.sql @@ -0,0 +1,7 @@ +CREATE DATABASE IF NOT EXISTS petclinic; + +ALTER DATABASE petclinic + DEFAULT CHARACTER SET utf8 + DEFAULT COLLATE utf8_general_ci; + +GRANT ALL PRIVILEGES ON petclinic.* TO 'petclinic@%' IDENTIFIED BY 'petclinic'; From 82cb521d636b282340378d80a6307a08e3d4a4c4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Jan 2020 05:59:32 -0500 Subject: [PATCH 03/48] Fix MySQL docker command line in readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 34c8e8b84..77de7dc77 100644 --- a/readme.md +++ b/readme.md @@ -42,7 +42,7 @@ Note that whenever the database type is changed, the app needs to be run with a You could start MySql locally with whatever installer works for your OS, or with docker: ``` -docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 +docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 ``` Further documentation is provided [here](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt). From 4e1f87407d80cdb4a5a293de89d62034fdcbb847 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Jan 2020 11:22:05 +0000 Subject: [PATCH 04/48] Apply spring-format plugin --- pom.xml | 15 + .../petclinic/PetClinicApplication.java | 6 +- .../samples/petclinic/model/BaseEntity.java | 25 +- .../samples/petclinic/model/NamedEntity.java | 29 +- .../samples/petclinic/model/Person.java | 36 +-- .../samples/petclinic/model/package-info.java | 1 - .../samples/petclinic/owner/Owner.java | 172 ++++++----- .../petclinic/owner/OwnerController.java | 175 +++++------ .../petclinic/owner/OwnerRepository.java | 54 ++-- .../samples/petclinic/owner/Pet.java | 95 +++--- .../petclinic/owner/PetController.java | 128 ++++---- .../petclinic/owner/PetRepository.java | 46 +-- .../samples/petclinic/owner/PetType.java | 3 +- .../petclinic/owner/PetTypeFormatter.java | 46 +-- .../samples/petclinic/owner/PetValidator.java | 54 ++-- .../petclinic/owner/VisitController.java | 86 +++--- .../petclinic/system/CacheConfiguration.java | 36 +-- .../petclinic/system/CrashController.java | 10 +- .../petclinic/system/WelcomeController.java | 10 +- .../samples/petclinic/vet/Vet.java | 50 +-- .../samples/petclinic/vet/VetController.java | 42 +-- .../samples/petclinic/vet/VetRepository.java | 23 +- .../samples/petclinic/vet/Vets.java | 20 +- .../samples/petclinic/visit/Visit.java | 64 ++-- .../petclinic/visit/VisitRepository.java | 22 +- .../petclinic/PetclinicIntegrationTests.java | 15 +- .../petclinic/model/ValidatorTests.java | 37 ++- .../petclinic/owner/OwnerControllerTests.java | 284 ++++++++---------- .../petclinic/owner/PetControllerTests.java | 134 ++++----- .../owner/PetTypeFormatterTests.java | 91 +++--- .../petclinic/owner/VisitControllerTests.java | 63 ++-- .../petclinic/service/ClinicServiceTests.java | 279 ++++++++--------- .../petclinic/service/EntityUtils.java | 39 ++- .../system/CrashControllerTests.java | 17 +- .../petclinic/vet/VetControllerTests.java | 66 ++-- .../samples/petclinic/vet/VetTests.java | 23 +- 36 files changed, 1128 insertions(+), 1168 deletions(-) diff --git a/pom.xml b/pom.xml index bf5ab1bf6..7cb6a8faf 100644 --- a/pom.xml +++ b/pom.xml @@ -28,6 +28,7 @@ 1.8.0 0.8.5 + 0.0.17 @@ -130,6 +131,20 @@ + + io.spring.javaformat + spring-javaformat-maven-plugin + ${spring-format.version} + + + + validate + + validate + + + + org.springframework.boot spring-boot-maven-plugin diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java index e09f0bdeb..191253587 100644 --- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java +++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java @@ -28,8 +28,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(proxyBeanMethods = false) public class PetClinicApplication { - public static void main(String[] args) { - SpringApplication.run(PetClinicApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(PetClinicApplication.class, args); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java index 8350eb744..4cb9ffc0c 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java @@ -31,20 +31,21 @@ import javax.persistence.MappedSuperclass; */ @MappedSuperclass public class BaseEntity implements Serializable { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Integer id; - public Integer getId() { - return id; - } + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; - public void setId(Integer id) { - this.id = id; - } + public Integer getId() { + return id; + } - public boolean isNew() { - return this.id == null; - } + public void setId(Integer id) { + this.id = id; + } + + public boolean isNew() { + return this.id == null; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java index cc596a194..088e52e81 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java +++ b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java @@ -18,10 +18,9 @@ package org.springframework.samples.petclinic.model; import javax.persistence.Column; import javax.persistence.MappedSuperclass; - /** - * Simple JavaBean domain object adds a name property to BaseEntity. Used as a base class for objects - * needing these properties. + * Simple JavaBean domain object adds a name property to BaseEntity. Used as + * a base class for objects needing these properties. * * @author Ken Krebs * @author Juergen Hoeller @@ -29,20 +28,20 @@ import javax.persistence.MappedSuperclass; @MappedSuperclass public class NamedEntity extends BaseEntity { - @Column(name = "name") - private String name; + @Column(name = "name") + private String name; - public String getName() { - return this.name; - } + public String getName() { + return this.name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - @Override - public String toString() { - return this.getName(); - } + @Override + public String toString() { + return this.getName(); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Person.java b/src/main/java/org/springframework/samples/petclinic/model/Person.java index 883376fbc..15fabacc3 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Person.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Person.java @@ -27,28 +27,28 @@ import javax.validation.constraints.NotEmpty; @MappedSuperclass public class Person extends BaseEntity { - @Column(name = "first_name") - @NotEmpty - private String firstName; + @Column(name = "first_name") + @NotEmpty + private String firstName; - @Column(name = "last_name") - @NotEmpty - private String lastName; + @Column(name = "last_name") + @NotEmpty + private String lastName; - public String getFirstName() { - return this.firstName; - } + public String getFirstName() { + return this.firstName; + } - public void setFirstName(String firstName) { - this.firstName = firstName; - } + public void setFirstName(String firstName) { + this.firstName = firstName; + } - public String getLastName() { - return this.lastName; - } + public String getLastName() { + return this.lastName; + } - public void setLastName(String lastName) { - this.lastName = lastName; - } + public void setLastName(String lastName) { + this.lastName = lastName; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/model/package-info.java b/src/main/java/org/springframework/samples/petclinic/model/package-info.java index 13c1673d5..37d6295e8 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/package-info.java +++ b/src/main/java/org/springframework/samples/petclinic/model/package-info.java @@ -18,4 +18,3 @@ * The classes in this package represent utilities used by the domain. */ package org.springframework.samples.petclinic.model; - diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java index 5b1b7fb36..61083bc8d 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java @@ -45,108 +45,106 @@ import org.springframework.samples.petclinic.model.Person; @Entity @Table(name = "owners") public class Owner extends Person { - @Column(name = "address") - @NotEmpty - private String address; - @Column(name = "city") - @NotEmpty - private String city; + @Column(name = "address") + @NotEmpty + private String address; - @Column(name = "telephone") - @NotEmpty - @Digits(fraction = 0, integer = 10) - private String telephone; + @Column(name = "city") + @NotEmpty + private String city; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") - private Set pets; + @Column(name = "telephone") + @NotEmpty + @Digits(fraction = 0, integer = 10) + private String telephone; - public String getAddress() { - return this.address; - } + @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") + private Set pets; - public void setAddress(String address) { - this.address = address; - } + public String getAddress() { + return this.address; + } - public String getCity() { - return this.city; - } + public void setAddress(String address) { + this.address = address; + } - public void setCity(String city) { - this.city = city; - } + public String getCity() { + return this.city; + } - public String getTelephone() { - return this.telephone; - } + public void setCity(String city) { + this.city = city; + } - public void setTelephone(String telephone) { - this.telephone = telephone; - } + public String getTelephone() { + return this.telephone; + } - protected Set getPetsInternal() { - if (this.pets == null) { - this.pets = new HashSet<>(); - } - return this.pets; - } + public void setTelephone(String telephone) { + this.telephone = telephone; + } - protected void setPetsInternal(Set pets) { - this.pets = pets; - } + protected Set getPetsInternal() { + if (this.pets == null) { + this.pets = new HashSet<>(); + } + return this.pets; + } - public List getPets() { - List sortedPets = new ArrayList<>(getPetsInternal()); - PropertyComparator.sort(sortedPets, - new MutableSortDefinition("name", true, true)); - return Collections.unmodifiableList(sortedPets); - } + protected void setPetsInternal(Set pets) { + this.pets = pets; + } - public void addPet(Pet pet) { - if (pet.isNew()) { - getPetsInternal().add(pet); - } - pet.setOwner(this); - } + public List getPets() { + List sortedPets = new ArrayList<>(getPetsInternal()); + PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true)); + return Collections.unmodifiableList(sortedPets); + } - /** - * Return the Pet with the given name, or null if none found for this Owner. - * - * @param name to test - * @return true if pet name is already in use - */ - public Pet getPet(String name) { - return getPet(name, false); - } + public void addPet(Pet pet) { + if (pet.isNew()) { + getPetsInternal().add(pet); + } + pet.setOwner(this); + } - /** - * Return the Pet with the given name, or null if none found for this Owner. - * - * @param name to test - * @return true if pet name is already in use - */ - public Pet getPet(String name, boolean ignoreNew) { - name = name.toLowerCase(); - for (Pet pet : getPetsInternal()) { - if (!ignoreNew || !pet.isNew()) { - String compName = pet.getName(); - compName = compName.toLowerCase(); - if (compName.equals(name)) { - return pet; - } - } - } - return null; - } + /** + * Return the Pet with the given name, or null if none found for this Owner. + * @param name to test + * @return true if pet name is already in use + */ + public Pet getPet(String name) { + return getPet(name, false); + } - @Override - public String toString() { - return new ToStringCreator(this) + /** + * Return the Pet with the given name, or null if none found for this Owner. + * @param name to test + * @return true if pet name is already in use + */ + public Pet getPet(String name, boolean ignoreNew) { + name = name.toLowerCase(); + for (Pet pet : getPetsInternal()) { + if (!ignoreNew || !pet.isNew()) { + String compName = pet.getName(); + compName = compName.toLowerCase(); + if (compName.equals(name)) { + return pet; + } + } + } + return null; + } + + @Override + public String toString() { + return new ToStringCreator(this) + + .append("id", this.getId()).append("new", this.isNew()).append("lastName", this.getLastName()) + .append("firstName", this.getFirstName()).append("address", this.address).append("city", this.city) + .append("telephone", this.telephone).toString(); + } - .append("id", this.getId()).append("new", this.isNew()) - .append("lastName", this.getLastName()) - .append("firstName", this.getFirstName()).append("address", this.address) - .append("city", this.city).append("telephone", this.telephone).toString(); - } } 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 afc2c937e..79aa4cd9b 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java @@ -39,102 +39,107 @@ import java.util.Map; @Controller class OwnerController { - private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; - private final OwnerRepository owners; - private VisitRepository visits; + private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; + private final OwnerRepository owners; - public OwnerController(OwnerRepository clinicService, VisitRepository visits) { - this.owners = clinicService; - this.visits = visits; - } + private VisitRepository visits; - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } + public OwnerController(OwnerRepository clinicService, VisitRepository visits) { + this.owners = clinicService; + this.visits = visits; + } - @GetMapping("/owners/new") - public String initCreationForm(Map model) { - Owner owner = new Owner(); - model.put("owner", owner); - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } - @PostMapping("/owners/new") - public String processCreationForm(@Valid Owner owner, BindingResult result) { - if (result.hasErrors()) { - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } else { - this.owners.save(owner); - return "redirect:/owners/" + owner.getId(); - } - } + @GetMapping("/owners/new") + public String initCreationForm(Map model) { + Owner owner = new Owner(); + model.put("owner", owner); + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } - @GetMapping("/owners/find") - public String initFindForm(Map model) { - model.put("owner", new Owner()); - return "owners/findOwners"; - } + @PostMapping("/owners/new") + public String processCreationForm(@Valid Owner owner, BindingResult result) { + if (result.hasErrors()) { + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } + else { + this.owners.save(owner); + return "redirect:/owners/" + owner.getId(); + } + } - @GetMapping("/owners") - public String processFindForm(Owner owner, BindingResult result, Map model) { + @GetMapping("/owners/find") + public String initFindForm(Map model) { + model.put("owner", new Owner()); + return "owners/findOwners"; + } - // allow parameterless GET request for /owners to return all records - if (owner.getLastName() == null) { - owner.setLastName(""); // empty string signifies broadest possible search - } + @GetMapping("/owners") + public String processFindForm(Owner owner, BindingResult result, Map model) { - // find owners by last name - Collection results = this.owners.findByLastName(owner.getLastName()); - if (results.isEmpty()) { - // no owners found - result.rejectValue("lastName", "notFound", "not found"); - return "owners/findOwners"; - } else if (results.size() == 1) { - // 1 owner found - owner = results.iterator().next(); - return "redirect:/owners/" + owner.getId(); - } else { - // multiple owners found - model.put("selections", results); - return "owners/ownersList"; - } - } + // allow parameterless GET request for /owners to return all records + if (owner.getLastName() == null) { + owner.setLastName(""); // empty string signifies broadest possible search + } - @GetMapping("/owners/{ownerId}/edit") - public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { - Owner owner = this.owners.findById(ownerId); - model.addAttribute(owner); - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } + // find owners by last name + Collection results = this.owners.findByLastName(owner.getLastName()); + if (results.isEmpty()) { + // no owners found + result.rejectValue("lastName", "notFound", "not found"); + return "owners/findOwners"; + } + else if (results.size() == 1) { + // 1 owner found + owner = results.iterator().next(); + return "redirect:/owners/" + owner.getId(); + } + else { + // multiple owners found + model.put("selections", results); + return "owners/ownersList"; + } + } - @PostMapping("/owners/{ownerId}/edit") - public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, @PathVariable("ownerId") int ownerId) { - if (result.hasErrors()) { - return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; - } else { - owner.setId(ownerId); - this.owners.save(owner); - return "redirect:/owners/{ownerId}"; - } - } + @GetMapping("/owners/{ownerId}/edit") + public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) { + Owner owner = this.owners.findById(ownerId); + model.addAttribute(owner); + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } - /** - * Custom handler for displaying an owner. - * - * @param ownerId the ID of the owner to display - * @return a ModelMap with the model attributes for the view - */ - @GetMapping("/owners/{ownerId}") - public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { - ModelAndView mav = new ModelAndView("owners/ownerDetails"); - Owner owner = this.owners.findById(ownerId); - for (Pet pet : owner.getPets()) { - pet.setVisitsInternal(visits.findByPetId(pet.getId())); - } - mav.addObject(owner); - return mav; - } + @PostMapping("/owners/{ownerId}/edit") + public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, + @PathVariable("ownerId") int ownerId) { + if (result.hasErrors()) { + return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; + } + else { + owner.setId(ownerId); + this.owners.save(owner); + return "redirect:/owners/{ownerId}"; + } + } + + /** + * Custom handler for displaying an owner. + * @param ownerId the ID of the owner to display + * @return a ModelMap with the model attributes for the view + */ + @GetMapping("/owners/{ownerId}") + public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) { + ModelAndView mav = new ModelAndView("owners/ownerDetails"); + 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/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java index a5803f36a..0613e928a 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java @@ -23,9 +23,10 @@ import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; /** - * Repository class for Owner domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data. - * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation + * Repository class for Owner domain objects All method names are compliant + * with Spring Data naming conventions so this interface can easily be extended for Spring + * Data. See: + * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller @@ -34,31 +35,30 @@ import org.springframework.transaction.annotation.Transactional; */ public interface OwnerRepository extends Repository { - /** - * Retrieve {@link Owner}s from the data store by last name, returning all owners - * whose last name starts with the given name. - * @param lastName Value to search for - * @return a Collection of matching {@link Owner}s (or an empty Collection if none - * found) - */ - @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%") - @Transactional(readOnly = true) - Collection findByLastName(@Param("lastName") String lastName); + /** + * Retrieve {@link Owner}s from the data store by last name, returning all owners + * whose last name starts with the given name. + * @param lastName Value to search for + * @return a Collection of matching {@link Owner}s (or an empty Collection if none + * found) + */ + @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%") + @Transactional(readOnly = true) + Collection findByLastName(@Param("lastName") String lastName); - /** - * Retrieve an {@link Owner} from the data store by id. - * @param id the id to search for - * @return the {@link Owner} if found - */ - @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") - @Transactional(readOnly = true) - Owner findById(@Param("id") Integer id); - - /** - * Save an {@link Owner} to the data store, either inserting or updating it. - * @param owner the {@link Owner} to save - */ - void save(Owner owner); + /** + * Retrieve an {@link Owner} from the data store by id. + * @param id the id to search for + * @return the {@link Owner} if found + */ + @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") + @Transactional(readOnly = true) + Owner findById(@Param("id") Integer id); + /** + * Save an {@link Owner} to the data store, either inserting or updating it. + * @param owner the {@link Owner} to save + */ + void save(Owner owner); } 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 0bd04b772..2b68005fd 100755 --- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java @@ -48,66 +48,65 @@ import org.springframework.samples.petclinic.visit.Visit; @Table(name = "pets") public class Pet extends NamedEntity { - @Column(name = "birth_date") - @DateTimeFormat(pattern = "yyyy-MM-dd") - private LocalDate birthDate; + @Column(name = "birth_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate birthDate; - @ManyToOne - @JoinColumn(name = "type_id") - private PetType type; + @ManyToOne + @JoinColumn(name = "type_id") + private PetType type; - @ManyToOne - @JoinColumn(name = "owner_id") - private Owner owner; + @ManyToOne + @JoinColumn(name = "owner_id") + private Owner owner; - @Transient - private Set visits = new LinkedHashSet<>(); + @Transient + private Set visits = new LinkedHashSet<>(); - public void setBirthDate(LocalDate birthDate) { - this.birthDate = birthDate; - } + public void setBirthDate(LocalDate birthDate) { + this.birthDate = birthDate; + } - public LocalDate getBirthDate() { - return this.birthDate; - } + public LocalDate getBirthDate() { + return this.birthDate; + } - public PetType getType() { - return this.type; - } + public PetType getType() { + return this.type; + } - public void setType(PetType type) { - this.type = type; - } + public void setType(PetType type) { + this.type = type; + } - public Owner getOwner() { - return this.owner; - } + public Owner getOwner() { + return this.owner; + } - protected void setOwner(Owner owner) { - this.owner = owner; - } + protected void setOwner(Owner owner) { + this.owner = owner; + } - protected Set getVisitsInternal() { - if (this.visits == null) { - this.visits = new HashSet<>(); - } - return this.visits; - } + protected Set getVisitsInternal() { + if (this.visits == null) { + this.visits = new HashSet<>(); + } + return this.visits; + } - protected void setVisitsInternal(Collection visits) { - this.visits = new LinkedHashSet<>(visits); - } + protected void setVisitsInternal(Collection visits) { + this.visits = new LinkedHashSet<>(visits); + } - public List getVisits() { - List sortedVisits = new ArrayList<>(getVisitsInternal()); - PropertyComparator.sort(sortedVisits, - new MutableSortDefinition("date", false, false)); - return Collections.unmodifiableList(sortedVisits); - } + public List getVisits() { + List sortedVisits = new ArrayList<>(getVisitsInternal()); + PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false)); + return Collections.unmodifiableList(sortedVisits); + } - public void addVisit(Visit visit) { - getVisitsInternal().add(visit); - visit.setPetId(this.getId()); - } + public void addVisit(Visit visit) { + getVisitsInternal().add(visit); + visit.setPetId(this.getId()); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java index 0107aa8a9..a55e599af 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java @@ -34,76 +34,80 @@ import java.util.Collection; @RequestMapping("/owners/{ownerId}") class PetController { - private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm"; - private final PetRepository pets; - private final OwnerRepository owners; + private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm"; - public PetController(PetRepository pets, OwnerRepository owners) { - this.pets = pets; - this.owners = owners; - } + private final PetRepository pets; - @ModelAttribute("types") - public Collection populatePetTypes() { - return this.pets.findPetTypes(); - } + private final OwnerRepository owners; - @ModelAttribute("owner") - public Owner findOwner(@PathVariable("ownerId") int ownerId) { - return this.owners.findById(ownerId); - } + public PetController(PetRepository pets, OwnerRepository owners) { + this.pets = pets; + this.owners = owners; + } - @InitBinder("owner") - public void initOwnerBinder(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } + @ModelAttribute("types") + public Collection populatePetTypes() { + return this.pets.findPetTypes(); + } - @InitBinder("pet") - public void initPetBinder(WebDataBinder dataBinder) { - dataBinder.setValidator(new PetValidator()); - } + @ModelAttribute("owner") + public Owner findOwner(@PathVariable("ownerId") int ownerId) { + return this.owners.findById(ownerId); + } - @GetMapping("/pets/new") - public String initCreationForm(Owner owner, ModelMap model) { - Pet pet = new Pet(); - owner.addPet(pet); - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } + @InitBinder("owner") + public void initOwnerBinder(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } - @PostMapping("/pets/new") - public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) { - if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){ - result.rejectValue("name", "duplicate", "already exists"); - } - owner.addPet(pet); - if (result.hasErrors()) { - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } else { - this.pets.save(pet); - return "redirect:/owners/{ownerId}"; - } - } + @InitBinder("pet") + public void initPetBinder(WebDataBinder dataBinder) { + dataBinder.setValidator(new PetValidator()); + } - @GetMapping("/pets/{petId}/edit") - public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) { - Pet pet = this.pets.findById(petId); - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } + @GetMapping("/pets/new") + public String initCreationForm(Owner owner, ModelMap model) { + Pet pet = new Pet(); + owner.addPet(pet); + model.put("pet", pet); + return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + } - @PostMapping("/pets/{petId}/edit") - public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) { - if (result.hasErrors()) { - pet.setOwner(owner); - model.put("pet", pet); - return VIEWS_PETS_CREATE_OR_UPDATE_FORM; - } else { - owner.addPet(pet); - this.pets.save(pet); - return "redirect:/owners/{ownerId}"; - } - } + @PostMapping("/pets/new") + public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) { + if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) { + result.rejectValue("name", "duplicate", "already exists"); + } + owner.addPet(pet); + if (result.hasErrors()) { + model.put("pet", pet); + return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + } + else { + this.pets.save(pet); + return "redirect:/owners/{ownerId}"; + } + } + + @GetMapping("/pets/{petId}/edit") + public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) { + Pet pet = this.pets.findById(petId); + model.put("pet", pet); + return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + } + + @PostMapping("/pets/{petId}/edit") + public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) { + if (result.hasErrors()) { + pet.setOwner(owner); + model.put("pet", pet); + return VIEWS_PETS_CREATE_OR_UPDATE_FORM; + } + else { + owner.addPet(pet); + this.pets.save(pet); + return "redirect:/owners/{ownerId}"; + } + } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java index 0d483b7ad..9d25b095b 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java @@ -22,9 +22,10 @@ import org.springframework.data.repository.Repository; import org.springframework.transaction.annotation.Transactional; /** - * Repository class for Pet domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data. - * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation + * Repository class for Pet domain objects All method names are compliant + * with Spring Data naming conventions so this interface can easily be extended for Spring + * Data. See: + * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller @@ -33,27 +34,26 @@ import org.springframework.transaction.annotation.Transactional; */ public interface PetRepository extends Repository { - /** - * Retrieve all {@link PetType}s from the data store. - * @return a Collection of {@link PetType}s. - */ - @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name") - @Transactional(readOnly = true) - List findPetTypes(); + /** + * Retrieve all {@link PetType}s from the data store. + * @return a Collection of {@link PetType}s. + */ + @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name") + @Transactional(readOnly = true) + List findPetTypes(); - /** - * Retrieve a {@link Pet} from the data store by id. - * @param id the id to search for - * @return the {@link Pet} if found - */ - @Transactional(readOnly = true) - Pet findById(Integer id); + /** + * Retrieve a {@link Pet} from the data store by id. + * @param id the id to search for + * @return the {@link Pet} if found + */ + @Transactional(readOnly = true) + Pet findById(Integer id); - /** - * Save a {@link Pet} to the data store, either inserting or updating it. - * @param pet the {@link Pet} to save - */ - void save(Pet pet); + /** + * Save a {@link Pet} to the data store, either inserting or updating it. + * @param pet the {@link Pet} to save + */ + void save(Pet pet); } - diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java index 19c27bee3..6f0aa58d3 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java @@ -21,8 +21,7 @@ import javax.persistence.Table; import org.springframework.samples.petclinic.model.NamedEntity; /** - * @author Juergen Hoeller - * Can be Cat, Dog, Hamster... + * @author Juergen Hoeller Can be Cat, Dog, Hamster... */ @Entity @Table(name = "types") diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java index 4423482a3..4940bcb38 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java @@ -24,9 +24,10 @@ import org.springframework.format.Formatter; import org.springframework.stereotype.Component; /** - * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting from Spring 3.0, Formatters have - * come as an improvement in comparison to legacy PropertyEditors. See the following links for more details: - The - * Spring ref doc: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#format + * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting + * from Spring 3.0, Formatters have come as an improvement in comparison to legacy + * PropertyEditors. See the following links for more details: - The Spring ref doc: + * https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#format * * @author Mark Fisher * @author Juergen Hoeller @@ -35,28 +36,27 @@ import org.springframework.stereotype.Component; @Component public class PetTypeFormatter implements Formatter { - private final PetRepository pets; + private final PetRepository pets; + @Autowired + public PetTypeFormatter(PetRepository pets) { + this.pets = pets; + } - @Autowired - public PetTypeFormatter(PetRepository pets) { - this.pets = pets; - } + @Override + public String print(PetType petType, Locale locale) { + return petType.getName(); + } - @Override - public String print(PetType petType, Locale locale) { - return petType.getName(); - } - - @Override - public PetType parse(String text, Locale locale) throws ParseException { - Collection findPetTypes = this.pets.findPetTypes(); - for (PetType type : findPetTypes) { - if (type.getName().equals(text)) { - return type; - } - } - throw new ParseException("type not found: " + text, 0); - } + @Override + public PetType parse(String text, Locale locale) throws ParseException { + Collection findPetTypes = this.pets.findPetTypes(); + for (PetType type : findPetTypes) { + if (type.getName().equals(text)) { + return type; + } + } + throw new ParseException("type not found: " + text, 0); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java index 3e8438b33..e1370b428 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java @@ -22,7 +22,8 @@ import org.springframework.validation.Validator; /** * Validator for Pet forms. *

- * We're not using Bean Validation annotations here because it is easier to define such validation rule in Java. + * We're not using Bean Validation annotations here because it is easier to define such + * validation rule in Java. *

* * @author Ken Krebs @@ -30,35 +31,34 @@ import org.springframework.validation.Validator; */ public class PetValidator implements Validator { - private static final String REQUIRED = "required"; + private static final String REQUIRED = "required"; - @Override - public void validate(Object obj, Errors errors) { - Pet pet = (Pet) obj; - String name = pet.getName(); - // name validation - if (!StringUtils.hasLength(name)) { - errors.rejectValue("name", REQUIRED, REQUIRED); - } + @Override + public void validate(Object obj, Errors errors) { + Pet pet = (Pet) obj; + String name = pet.getName(); + // name validation + if (!StringUtils.hasLength(name)) { + errors.rejectValue("name", REQUIRED, REQUIRED); + } - // type validation - if (pet.isNew() && pet.getType() == null) { - errors.rejectValue("type", REQUIRED, REQUIRED); - } + // type validation + if (pet.isNew() && pet.getType() == null) { + errors.rejectValue("type", REQUIRED, REQUIRED); + } - // birth date validation - if (pet.getBirthDate() == null) { - errors.rejectValue("birthDate", REQUIRED, REQUIRED); - } - } - - /** - * This Validator validates *just* Pet instances - */ - @Override - public boolean supports(Class clazz) { - return Pet.class.isAssignableFrom(clazz); - } + // birth date validation + if (pet.getBirthDate() == null) { + errors.rejectValue("birthDate", REQUIRED, REQUIRED); + } + } + /** + * This Validator validates *just* Pet instances + */ + @Override + public boolean supports(Class clazz) { + return Pet.class.isAssignableFrom(clazz); + } } 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 c6dfc7fc7..375980312 100644 --- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java @@ -40,55 +40,53 @@ import org.springframework.web.bind.annotation.PostMapping; @Controller class VisitController { - private final VisitRepository visits; - private final PetRepository pets; + private final VisitRepository visits; + private final PetRepository pets; - public VisitController(VisitRepository visits, PetRepository pets) { - this.visits = visits; - this.pets = pets; - } + public VisitController(VisitRepository visits, PetRepository pets) { + this.visits = visits; + this.pets = pets; + } - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } + @InitBinder + public void setAllowedFields(WebDataBinder dataBinder) { + dataBinder.setDisallowedFields("id"); + } - /** - * Called before each and every @RequestMapping annotated method. - * 2 goals: - * - Make sure we always have fresh data - * - Since we do not use the session scope, make sure that Pet object always has an id - * (Even though id is not part of the form fields) - * - * @param petId - * @return Pet - */ - @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); - return visit; - } + /** + * Called before each and every @RequestMapping annotated method. 2 goals: - Make sure + * we always have fresh data - Since we do not use the session scope, make sure that + * Pet object always has an id (Even though id is not part of the form fields) + * @param petId + * @return Pet + */ + @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); + return visit; + } - // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called - @GetMapping("/owners/*/pets/{petId}/visits/new") - public String initNewVisitForm(@PathVariable("petId") int petId, Map model) { - return "pets/createOrUpdateVisitForm"; - } + // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called + @GetMapping("/owners/*/pets/{petId}/visits/new") + public String initNewVisitForm(@PathVariable("petId") int petId, Map model) { + return "pets/createOrUpdateVisitForm"; + } - // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called - @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") - public String processNewVisitForm(@Valid Visit visit, BindingResult result) { - if (result.hasErrors()) { - return "pets/createOrUpdateVisitForm"; - } else { - this.visits.save(visit); - return "redirect:/owners/{ownerId}"; - } - } + // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called + @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") + public String processNewVisitForm(@Valid Visit visit, BindingResult result) { + if (result.hasErrors()) { + return "pets/createOrUpdateVisitForm"; + } + else { + this.visits.save(visit); + return "redirect:/owners/{ownerId}"; + } + } } diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java index 4c083a41b..0a96582c9 100755 --- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java @@ -32,24 +32,24 @@ import org.springframework.context.annotation.Configuration; @EnableCaching class CacheConfiguration { - @Bean - public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() { - return cm -> { - cm.createCache("vets", cacheConfiguration()); - }; - } + @Bean + public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() { + return cm -> { + cm.createCache("vets", cacheConfiguration()); + }; + } - /** - * Create a simple configuration that enable statistics via the JCache programmatic - * configuration API. - *

- * Within the configuration object that is provided by the JCache API standard, there - * is only a very limited set of configuration options. The really relevant - * configuration options (like the size limit) must be set via a configuration - * mechanism that is provided by the selected JCache implementation. - */ - private javax.cache.configuration.Configuration cacheConfiguration() { - return new MutableConfiguration<>().setStatisticsEnabled(true); - } + /** + * Create a simple configuration that enable statistics via the JCache programmatic + * configuration API. + *

+ * Within the configuration object that is provided by the JCache API standard, there + * is only a very limited set of configuration options. The really relevant + * configuration options (like the size limit) must be set via a configuration + * mechanism that is provided by the selected JCache implementation. + */ + private javax.cache.configuration.Configuration cacheConfiguration() { + return new MutableConfiguration<>().setStatisticsEnabled(true); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java index 05be70429..2b28600fd 100644 --- a/src/main/java/org/springframework/samples/petclinic/system/CrashController.java +++ b/src/main/java/org/springframework/samples/petclinic/system/CrashController.java @@ -28,10 +28,10 @@ import org.springframework.web.bind.annotation.GetMapping; @Controller class CrashController { - @GetMapping("/oups") - public String triggerException() { - throw new RuntimeException("Expected: controller used to showcase what " - + "happens when an exception is thrown"); - } + @GetMapping("/oups") + public String triggerException() { + throw new RuntimeException( + "Expected: controller used to showcase what " + "happens when an exception is thrown"); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java b/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java index 7e96848b6..9224015bc 100644 --- a/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java +++ b/src/main/java/org/springframework/samples/petclinic/system/WelcomeController.java @@ -16,15 +16,15 @@ package org.springframework.samples.petclinic.system; - import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller class WelcomeController { - @GetMapping("/") - public String welcome() { - return "welcome"; - } + @GetMapping("/") + public String welcome() { + return "welcome"; + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java b/src/main/java/org/springframework/samples/petclinic/vet/Vet.java index 33b449129..014becfce 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/Vet.java @@ -45,35 +45,35 @@ import org.springframework.samples.petclinic.model.Person; @Table(name = "vets") public class Vet extends Person { - @ManyToMany(fetch = FetchType.EAGER) - @JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"), inverseJoinColumns = @JoinColumn(name = "specialty_id")) - private Set specialties; + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"), + inverseJoinColumns = @JoinColumn(name = "specialty_id")) + private Set specialties; - protected Set getSpecialtiesInternal() { - if (this.specialties == null) { - this.specialties = new HashSet<>(); - } - return this.specialties; - } + protected Set getSpecialtiesInternal() { + if (this.specialties == null) { + this.specialties = new HashSet<>(); + } + return this.specialties; + } - protected void setSpecialtiesInternal(Set specialties) { - this.specialties = specialties; - } + protected void setSpecialtiesInternal(Set specialties) { + this.specialties = specialties; + } - @XmlElement - public List getSpecialties() { - List sortedSpecs = new ArrayList<>(getSpecialtiesInternal()); - PropertyComparator.sort(sortedSpecs, - new MutableSortDefinition("name", true, true)); - return Collections.unmodifiableList(sortedSpecs); - } + @XmlElement + public List getSpecialties() { + List sortedSpecs = new ArrayList<>(getSpecialtiesInternal()); + PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true)); + return Collections.unmodifiableList(sortedSpecs); + } - public int getNrOfSpecialties() { - return getSpecialtiesInternal().size(); - } + public int getNrOfSpecialties() { + return getSpecialtiesInternal().size(); + } - public void addSpecialty(Specialty specialty) { - getSpecialtiesInternal().add(specialty); - } + public void addSpecialty(Specialty specialty) { + getSpecialtiesInternal().add(specialty); + } } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java index f15f40b2c..fb5e321ba 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetController.java @@ -30,29 +30,29 @@ import java.util.Map; @Controller class VetController { - private final VetRepository vets; + private final VetRepository vets; - public VetController(VetRepository clinicService) { - this.vets = clinicService; - } + public VetController(VetRepository clinicService) { + this.vets = clinicService; + } - @GetMapping("/vets.html") - public String showVetList(Map model) { - // Here we are returning an object of type 'Vets' rather than a collection of Vet - // objects so it is simpler for Object-Xml mapping - Vets vets = new Vets(); - vets.getVetList().addAll(this.vets.findAll()); - model.put("vets", vets); - return "vets/vetList"; - } + @GetMapping("/vets.html") + public String showVetList(Map model) { + // Here we are returning an object of type 'Vets' rather than a collection of Vet + // objects so it is simpler for Object-Xml mapping + Vets vets = new Vets(); + vets.getVetList().addAll(this.vets.findAll()); + model.put("vets", vets); + return "vets/vetList"; + } - @GetMapping({ "/vets" }) - public @ResponseBody Vets showResourcesVetList() { - // Here we are returning an object of type 'Vets' rather than a collection of Vet - // objects so it is simpler for JSon/Object mapping - Vets vets = new Vets(); - vets.getVetList().addAll(this.vets.findAll()); - return vets; - } + @GetMapping({ "/vets" }) + public @ResponseBody Vets showResourcesVetList() { + // Here we are returning an object of type 'Vets' rather than a collection of Vet + // objects so it is simpler for JSon/Object mapping + Vets vets = new Vets(); + vets.getVetList().addAll(this.vets.findAll()); + return vets; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java index 1f70182fd..549b1c229 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java @@ -23,9 +23,10 @@ import org.springframework.data.repository.Repository; import org.springframework.transaction.annotation.Transactional; /** - * Repository class for Vet domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data. - * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation + * Repository class for Vet domain objects All method names are compliant + * with Spring Data naming conventions so this interface can easily be extended for Spring + * Data. See: + * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller @@ -34,14 +35,12 @@ import org.springframework.transaction.annotation.Transactional; */ public interface VetRepository extends Repository { - /** - * Retrieve all Vets from the data store. - * - * @return a Collection of Vets - */ - @Transactional(readOnly = true) - @Cacheable("vets") - Collection findAll() throws DataAccessException; - + /** + * Retrieve all Vets from the data store. + * @return a Collection of Vets + */ + @Transactional(readOnly = true) + @Cacheable("vets") + Collection findAll() throws DataAccessException; } diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java b/src/main/java/org/springframework/samples/petclinic/vet/Vets.java index ab29f7a54..cea665629 100644 --- a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java +++ b/src/main/java/org/springframework/samples/petclinic/vet/Vets.java @@ -22,22 +22,22 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** - * Simple domain object representing a list of veterinarians. Mostly here to be used for the 'vets' {@link - * org.springframework.web.servlet.view.xml.MarshallingView}. + * Simple domain object representing a list of veterinarians. Mostly here to be used for + * the 'vets' {@link org.springframework.web.servlet.view.xml.MarshallingView}. * * @author Arjen Poutsma */ @XmlRootElement public class Vets { - private List vets; + private List vets; - @XmlElement - public List getVetList() { - if (vets == null) { - vets = new ArrayList<>(); - } - return vets; - } + @XmlElement + public List getVetList() { + if (vets == null) { + vets = new ArrayList<>(); + } + return vets; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java index 03c9deedf..df9f25fe0 100755 --- a/src/main/java/org/springframework/samples/petclinic/visit/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/Visit.java @@ -35,46 +35,46 @@ import org.springframework.samples.petclinic.model.BaseEntity; @Table(name = "visits") public class Visit extends BaseEntity { - @Column(name = "visit_date") - @DateTimeFormat(pattern = "yyyy-MM-dd") - private LocalDate date; + @Column(name = "visit_date") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate date; - @NotEmpty - @Column(name = "description") - private String description; + @NotEmpty + @Column(name = "description") + private String description; - @Column(name = "pet_id") - private Integer petId; + @Column(name = "pet_id") + private Integer petId; - /** - * Creates a new instance of Visit for the current date - */ - public Visit() { - this.date = LocalDate.now(); - } + /** + * Creates a new instance of Visit for the current date + */ + public Visit() { + this.date = LocalDate.now(); + } - public LocalDate getDate() { - return this.date; - } + public LocalDate getDate() { + return this.date; + } - public void setDate(LocalDate date) { - this.date = date; - } + public void setDate(LocalDate date) { + this.date = date; + } - public String getDescription() { - return this.description; - } + public String getDescription() { + return this.description; + } - public void setDescription(String description) { - this.description = description; - } + public void setDescription(String description) { + this.description = description; + } - public Integer getPetId() { - return this.petId; - } + public Integer getPetId() { + return this.petId; + } - public void setPetId(Integer petId) { - this.petId = petId; - } + public void setPetId(Integer petId) { + this.petId = petId; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java index 42b58618b..d5a3334c6 100644 --- a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java @@ -22,9 +22,10 @@ import org.springframework.data.repository.Repository; import org.springframework.samples.petclinic.model.BaseEntity; /** - * Repository class for Visit domain objects All method names are compliant with Spring Data naming - * conventions so this interface can easily be extended for Spring Data. - * See: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation + * Repository class for Visit domain objects All method names are compliant + * with Spring Data naming conventions so this interface can easily be extended for Spring + * Data. See: + * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation * * @author Ken Krebs * @author Juergen Hoeller @@ -33,14 +34,13 @@ import org.springframework.samples.petclinic.model.BaseEntity; */ public interface VisitRepository extends Repository { - /** - * Save a Visit to the data store, either inserting or updating it. - * - * @param visit the Visit to save - * @see BaseEntity#isNew - */ - void save(Visit visit) throws DataAccessException; + /** + * Save a Visit to the data store, either inserting or updating it. + * @param visit the Visit to save + * @see BaseEntity#isNew + */ + void save(Visit visit) throws DataAccessException; - List findByPetId(Integer petId); + List findByPetId(Integer petId); } diff --git a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java index 217d552f4..226db01fe 100644 --- a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java +++ b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java @@ -24,12 +24,13 @@ import org.springframework.samples.petclinic.vet.VetRepository; @SpringBootTest class PetclinicIntegrationTests { - @Autowired - private VetRepository vets; + @Autowired + private VetRepository vets; + + @Test + void testFindAll() throws Exception { + vets.findAll(); + vets.findAll(); // served from cache + } - @Test - void testFindAll() throws Exception { - vets.findAll(); - vets.findAll(); // served from cache - } } diff --git a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java index 4be38f714..8d754900d 100644 --- a/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java +++ b/src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java @@ -34,28 +34,27 @@ import static org.assertj.core.api.Assertions.assertThat; */ class ValidatorTests { - private Validator createValidator() { - LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); - localValidatorFactoryBean.afterPropertiesSet(); - return localValidatorFactoryBean; - } + private Validator createValidator() { + LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); + localValidatorFactoryBean.afterPropertiesSet(); + return localValidatorFactoryBean; + } - @Test - void shouldNotValidateWhenFirstNameEmpty() { + @Test + void shouldNotValidateWhenFirstNameEmpty() { - LocaleContextHolder.setLocale(Locale.ENGLISH); - Person person = new Person(); - person.setFirstName(""); - person.setLastName("smith"); + LocaleContextHolder.setLocale(Locale.ENGLISH); + Person person = new Person(); + person.setFirstName(""); + person.setLastName("smith"); - Validator validator = createValidator(); - Set> constraintViolations = validator - .validate(person); + Validator validator = createValidator(); + Set> constraintViolations = validator.validate(person); - assertThat(constraintViolations).hasSize(1); - ConstraintViolation violation = constraintViolations.iterator().next(); - assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName"); - assertThat(violation.getMessage()).isEqualTo("must not be empty"); - } + assertThat(constraintViolations).hasSize(1); + ConstraintViolation violation = constraintViolations.iterator().next(); + assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName"); + assertThat(violation.getMessage()).isEqualTo("must not be empty"); + } } 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 1956e2a24..1d6249c5d 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java @@ -51,181 +51,149 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @WebMvcTest(OwnerController.class) class OwnerControllerTests { - private static final int TEST_OWNER_ID = 1; + private static final int TEST_OWNER_ID = 1; - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean - private OwnerRepository owners; + @MockBean + private OwnerRepository owners; - @MockBean - private VisitRepository visits; + @MockBean + private VisitRepository visits; - private Owner george; + private Owner george; - @BeforeEach - void setup() { - george = new Owner(); - george.setId(TEST_OWNER_ID); - george.setFirstName("George"); - george.setLastName("Franklin"); - 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)); - } + @BeforeEach + void setup() { + george = new Owner(); + george.setId(TEST_OWNER_ID); + george.setFirstName("George"); + george.setLastName("Franklin"); + 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 - void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/new")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } + @Test + void testInitCreationForm() throws Exception { + mockMvc.perform(get("/owners/new")).andExpect(status().isOk()).andExpect(model().attributeExists("owner")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } - @Test - void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/new") - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "01316761638") - ) - .andExpect(status().is3xxRedirection()); - } + @Test + void testProcessCreationFormSuccess() throws Exception { + mockMvc.perform(post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs") + .param("address", "123 Caramel Street").param("city", "London").param("telephone", "01316761638")) + .andExpect(status().is3xxRedirection()); + } - @Test - void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/new") - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("city", "London") - ) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } + @Test + void testProcessCreationFormHasErrors() throws Exception { + mockMvc.perform( + post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs").param("city", "London")) + .andExpect(status().isOk()).andExpect(model().attributeHasErrors("owner")) + .andExpect(model().attributeHasFieldErrors("owner", "address")) + .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } - @Test - void testInitFindForm() throws Exception { - mockMvc.perform(get("/owners/find")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(view().name("owners/findOwners")); - } + @Test + void testInitFindForm() throws Exception { + mockMvc.perform(get("/owners/find")).andExpect(status().isOk()).andExpect(model().attributeExists("owner")) + .andExpect(view().name("owners/findOwners")); + } - @Test - void testProcessFindFormSuccess() throws Exception { - given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner())); - mockMvc.perform(get("/owners")) - .andExpect(status().isOk()) - .andExpect(view().name("owners/ownersList")); - } + @Test + void testProcessFindFormSuccess() throws Exception { + given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner())); + mockMvc.perform(get("/owners")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList")); + } - @Test - void testProcessFindFormByLastName() throws Exception { - given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); - mockMvc.perform(get("/owners") - .param("lastName", "Franklin") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); - } + @Test + void testProcessFindFormByLastName() throws Exception { + given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george)); + mockMvc.perform(get("/owners").param("lastName", "Franklin")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID)); + } - @Test - void testProcessFindFormNoOwnersFound() throws Exception { - mockMvc.perform(get("/owners") - .param("lastName", "Unknown Surname") - ) - .andExpect(status().isOk()) - .andExpect(model().attributeHasFieldErrors("owner", "lastName")) - .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) - .andExpect(view().name("owners/findOwners")); - } + @Test + void testProcessFindFormNoOwnersFound() throws Exception { + mockMvc.perform(get("/owners").param("lastName", "Unknown Surname")).andExpect(status().isOk()) + .andExpect(model().attributeHasFieldErrors("owner", "lastName")) + .andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound")) + .andExpect(view().name("owners/findOwners")); + } - @Test - void testInitUpdateOwnerForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("owner")) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .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(view().name("owners/createOrUpdateOwnerForm")); - } + @Test + void testInitUpdateOwnerForm() throws Exception { + mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)).andExpect(status().isOk()) + .andExpect(model().attributeExists("owner")) + .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) + .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) + .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(view().name("owners/createOrUpdateOwnerForm")); + } - @Test - void testProcessUpdateOwnerFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("address", "123 Caramel Street") - .param("city", "London") - .param("telephone", "01616291589") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } + @Test + void testProcessUpdateOwnerFormSuccess() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") + .param("lastName", "Bloggs").param("address", "123 Caramel Street").param("city", "London") + .param("telephone", "01616291589")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } - @Test - void testProcessUpdateOwnerFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID) - .param("firstName", "Joe") - .param("lastName", "Bloggs") - .param("city", "London") - ) - .andExpect(status().isOk()) - .andExpect(model().attributeHasErrors("owner")) - .andExpect(model().attributeHasFieldErrors("owner", "address")) - .andExpect(model().attributeHasFieldErrors("owner", "telephone")) - .andExpect(view().name("owners/createOrUpdateOwnerForm")); - } + @Test + void testProcessUpdateOwnerFormHasErrors() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe") + .param("lastName", "Bloggs").param("city", "London")).andExpect(status().isOk()) + .andExpect(model().attributeHasErrors("owner")) + .andExpect(model().attributeHasFieldErrors("owner", "address")) + .andExpect(model().attributeHasFieldErrors("owner", "telephone")) + .andExpect(view().name("owners/createOrUpdateOwnerForm")); + } - @Test - void testShowOwner() throws Exception { - mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) - .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) - .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>() { + @Test + void testShowOwner() throws Exception { + mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)).andExpect(status().isOk()) + .andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin")))) + .andExpect(model().attribute("owner", hasProperty("firstName", is("George")))) + .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 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")); - } + @Override + public void describeTo(Description description) { + description.appendText("Max did not have any visits"); + } + }))).andExpect(view().name("owners/ownerDetails")); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java index f7c8fe726..47c444a78 100755 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java @@ -39,97 +39,75 @@ import org.springframework.test.web.servlet.MockMvc; * @author Colin But */ @WebMvcTest(value = PetController.class, - includeFilters = @ComponentScan.Filter( - value = PetTypeFormatter.class, - type = FilterType.ASSIGNABLE_TYPE)) + includeFilters = @ComponentScan.Filter(value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE)) class PetControllerTests { - private static final int TEST_OWNER_ID = 1; - private static final int TEST_PET_ID = 1; + private static final int TEST_OWNER_ID = 1; + private static final int TEST_PET_ID = 1; - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean - private PetRepository pets; + @MockBean + private PetRepository pets; - @MockBean - private OwnerRepository owners; + @MockBean + private OwnerRepository owners; - @BeforeEach - void setup() { - PetType cat = new PetType(); - cat.setId(3); - cat.setName("hamster"); - given(this.pets.findPetTypes()).willReturn(Lists.newArrayList(cat)); - given(this.owners.findById(TEST_OWNER_ID)).willReturn(new Owner()); - given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); + @BeforeEach + void setup() { + PetType cat = new PetType(); + cat.setId(3); + cat.setName("hamster"); + given(this.pets.findPetTypes()).willReturn(Lists.newArrayList(cat)); + given(this.owners.findById(TEST_OWNER_ID)).willReturn(new Owner()); + given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); - } + } - @Test - void testInitCreationForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")) - .andExpect(model().attributeExists("pet")); - } + @Test + void testInitCreationForm() throws Exception { + mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdatePetForm")).andExpect(model().attributeExists("pet")); + } - @Test - void testProcessCreationFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) - .param("name", "Betty") - .param("type", "hamster") - .param("birthDate", "2015-02-12") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } + @Test + void testProcessCreationFormSuccess() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty") + .param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } - @Test - void testProcessCreationFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID) - .param("name", "Betty") - .param("birthDate", "2015-02-12") - ) - .andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")) - .andExpect(model().attributeHasFieldErrors("pet", "type")) - .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); - } + @Test + void testProcessCreationFormHasErrors() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty").param("birthDate", + "2015-02-12")).andExpect(model().attributeHasNoErrors("owner")) + .andExpect(model().attributeHasErrors("pet")).andExpect(model().attributeHasFieldErrors("pet", "type")) + .andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdatePetForm")); + } - @Test - void testInitUpdateForm() throws Exception { - mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("pet")) - .andExpect(view().name("pets/createOrUpdatePetForm")); - } + @Test + void testInitUpdateForm() throws Exception { + mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID)) + .andExpect(status().isOk()).andExpect(model().attributeExists("pet")) + .andExpect(view().name("pets/createOrUpdatePetForm")); + } - @Test - void testProcessUpdateFormSuccess() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) - .param("name", "Betty") - .param("type", "hamster") - .param("birthDate", "2015-02-12") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } + @Test + void testProcessUpdateFormSuccess() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty") + .param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } - @Test - void testProcessUpdateFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID) - .param("name", "Betty") - .param("birthDate", "2015/02/12") - ) - .andExpect(model().attributeHasNoErrors("owner")) - .andExpect(model().attributeHasErrors("pet")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdatePetForm")); - } + @Test + void testProcessUpdateFormHasErrors() throws Exception { + mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty") + .param("birthDate", "2015/02/12")).andExpect(model().attributeHasNoErrors("owner")) + .andExpect(model().attributeHasErrors("pet")).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdatePetForm")); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java index e27fce21e..adb96b69d 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java @@ -40,57 +40,56 @@ import static org.mockito.BDDMockito.given; @ExtendWith(MockitoExtension.class) class PetTypeFormatterTests { - @Mock - private PetRepository pets; + @Mock + private PetRepository pets; - private PetTypeFormatter petTypeFormatter; + private PetTypeFormatter petTypeFormatter; - @BeforeEach - void setup() { - this.petTypeFormatter = new PetTypeFormatter(pets); - } + @BeforeEach + void setup() { + this.petTypeFormatter = new PetTypeFormatter(pets); + } - @Test - void testPrint() { - PetType petType = new PetType(); - petType.setName("Hamster"); - String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH); - assertThat(petTypeName).isEqualTo("Hamster"); - } + @Test + void testPrint() { + PetType petType = new PetType(); + petType.setName("Hamster"); + String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH); + assertThat(petTypeName).isEqualTo("Hamster"); + } - @Test - void shouldParse() throws ParseException { - given(this.pets.findPetTypes()).willReturn(makePetTypes()); - PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); - assertThat(petType.getName()).isEqualTo("Bird"); - } + @Test + void shouldParse() throws ParseException { + given(this.pets.findPetTypes()).willReturn(makePetTypes()); + PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH); + assertThat(petType.getName()).isEqualTo("Bird"); + } - @Test - void shouldThrowParseException() throws ParseException { - given(this.pets.findPetTypes()).willReturn(makePetTypes()); - Assertions.assertThrows(ParseException.class, () -> { - petTypeFormatter.parse("Fish", Locale.ENGLISH); - }); - } + @Test + void shouldThrowParseException() throws ParseException { + given(this.pets.findPetTypes()).willReturn(makePetTypes()); + Assertions.assertThrows(ParseException.class, () -> { + petTypeFormatter.parse("Fish", Locale.ENGLISH); + }); + } - /** - * Helper method to produce some sample pet types just for test purpose - * - * @return {@link Collection} of {@link PetType} - */ - private List makePetTypes() { - List petTypes = new ArrayList<>(); - petTypes.add(new PetType() { - { - setName("Dog"); - } - }); - petTypes.add(new PetType() { - { - setName("Bird"); - } - }); - return petTypes; - } + /** + * Helper method to produce some sample pet types just for test purpose + * @return {@link Collection} of {@link PetType} + */ + private List makePetTypes() { + List petTypes = new ArrayList<>(); + petTypes.add(new PetType() { + { + setName("Dog"); + } + }); + petTypes.add(new PetType() { + { + setName("Bird"); + } + }); + return petTypes; + } } diff --git a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java index f61d34c9c..84bee72df 100644 --- a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java @@ -39,47 +39,40 @@ import org.springframework.test.web.servlet.MockMvc; @WebMvcTest(VisitController.class) class VisitControllerTests { - private static final int TEST_PET_ID = 1; + private static final int TEST_PET_ID = 1; - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean - private VisitRepository visits; + @MockBean + private VisitRepository visits; - @MockBean - private PetRepository pets; + @MockBean + private PetRepository pets; - @BeforeEach - void init() { - given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); - } + @BeforeEach + void init() { + given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet()); + } - @Test - void testInitNewVisitForm() throws Exception { - mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdateVisitForm")); - } + @Test + void testInitNewVisitForm() throws Exception { + mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdateVisitForm")); + } - @Test - void testProcessNewVisitFormSuccess() throws Exception { - mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID) - .param("name", "George") - .param("description", "Visit Description") - ) - .andExpect(status().is3xxRedirection()) - .andExpect(view().name("redirect:/owners/{ownerId}")); - } + @Test + void testProcessNewVisitFormSuccess() throws Exception { + mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George") + .param("description", "Visit Description")).andExpect(status().is3xxRedirection()) + .andExpect(view().name("redirect:/owners/{ownerId}")); + } - @Test - void testProcessNewVisitFormHasErrors() throws Exception { - mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID) - .param("name", "George") - ) - .andExpect(model().attributeHasErrors("visit")) - .andExpect(status().isOk()) - .andExpect(view().name("pets/createOrUpdateVisitForm")); - } + @Test + void testProcessNewVisitFormHasErrors() throws Exception { + mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George")) + .andExpect(model().attributeHasErrors("visit")).andExpect(status().isOk()) + .andExpect(view().name("pets/createOrUpdateVisitForm")); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java index f11f98373..a7f3d9d24 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java @@ -40,15 +40,24 @@ import org.springframework.transaction.annotation.Transactional; /** * Integration test of the Service and the Repository layer. *

- * ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided by the Spring - * TestContext Framework:

  • Spring IoC container caching which spares us unnecessary set up - * time between test execution.
  • Dependency Injection of test fixture instances, meaning that - * we don't need to perform application context lookups. See the use of {@link Autowired @Autowired} on the {@link - * ClinicServiceTests#clinicService clinicService} instance variable, which uses autowiring by - * type.
  • Transaction management, meaning each test method is executed in its own transaction, - * which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there - * is no need for a teardown or cleanup script.
  • An {@link org.springframework.context.ApplicationContext - * ApplicationContext} is also inherited and can be used for explicit bean lookup if necessary.
+ * ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided + * by the Spring TestContext Framework: + *

+ *
    + *
  • Spring IoC container caching which spares us unnecessary set up + * time between test execution.
  • + *
  • Dependency Injection of test fixture instances, meaning that we + * don't need to perform application context lookups. See the use of + * {@link Autowired @Autowired} on the {@link + * ClinicServiceTests#clinicService clinicService} instance variable, which uses + * autowiring by type. + *
  • Transaction management, meaning each test method is executed in + * its own transaction, which is automatically rolled back by default. Thus, even if tests + * insert or otherwise change database state, there is no need for a teardown or cleanup + * script. + *
  • An {@link org.springframework.context.ApplicationContext ApplicationContext} is + * also inherited and can be used for explicit bean lookup if necessary.
  • + *
* * @author Ken Krebs * @author Rod Johnson @@ -60,159 +69,159 @@ import org.springframework.transaction.annotation.Transactional; @DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class)) class ClinicServiceTests { - @Autowired - protected OwnerRepository owners; + @Autowired + protected OwnerRepository owners; - @Autowired - protected PetRepository pets; + @Autowired + protected PetRepository pets; - @Autowired - protected VisitRepository visits; + @Autowired + protected VisitRepository visits; - @Autowired - protected VetRepository vets; + @Autowired + protected VetRepository vets; - @Test - void shouldFindOwnersByLastName() { - Collection owners = this.owners.findByLastName("Davis"); - assertThat(owners).hasSize(2); + @Test + void shouldFindOwnersByLastName() { + Collection owners = this.owners.findByLastName("Davis"); + assertThat(owners).hasSize(2); - owners = this.owners.findByLastName("Daviss"); - assertThat(owners).isEmpty(); - } + owners = this.owners.findByLastName("Daviss"); + assertThat(owners).isEmpty(); + } - @Test - void shouldFindSingleOwnerWithPet() { - Owner owner = this.owners.findById(1); - assertThat(owner.getLastName()).startsWith("Franklin"); - assertThat(owner.getPets()).hasSize(1); - assertThat(owner.getPets().get(0).getType()).isNotNull(); - assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat"); - } + @Test + void shouldFindSingleOwnerWithPet() { + Owner owner = this.owners.findById(1); + assertThat(owner.getLastName()).startsWith("Franklin"); + assertThat(owner.getPets()).hasSize(1); + assertThat(owner.getPets().get(0).getType()).isNotNull(); + assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat"); + } - @Test - @Transactional - void shouldInsertOwner() { - Collection owners = this.owners.findByLastName("Schultz"); - int found = owners.size(); + @Test + @Transactional + void shouldInsertOwner() { + Collection owners = this.owners.findByLastName("Schultz"); + int found = owners.size(); - Owner owner = new Owner(); - owner.setFirstName("Sam"); - owner.setLastName("Schultz"); - owner.setAddress("4, Evans Street"); - owner.setCity("Wollongong"); - owner.setTelephone("4444444444"); - this.owners.save(owner); - assertThat(owner.getId().longValue()).isNotEqualTo(0); + Owner owner = new Owner(); + owner.setFirstName("Sam"); + owner.setLastName("Schultz"); + owner.setAddress("4, Evans Street"); + owner.setCity("Wollongong"); + owner.setTelephone("4444444444"); + this.owners.save(owner); + assertThat(owner.getId().longValue()).isNotEqualTo(0); - owners = this.owners.findByLastName("Schultz"); - assertThat(owners.size()).isEqualTo(found + 1); - } + owners = this.owners.findByLastName("Schultz"); + assertThat(owners.size()).isEqualTo(found + 1); + } - @Test - @Transactional - void shouldUpdateOwner() { - Owner owner = this.owners.findById(1); - String oldLastName = owner.getLastName(); - String newLastName = oldLastName + "X"; + @Test + @Transactional + void shouldUpdateOwner() { + Owner owner = this.owners.findById(1); + String oldLastName = owner.getLastName(); + String newLastName = oldLastName + "X"; - owner.setLastName(newLastName); - this.owners.save(owner); + owner.setLastName(newLastName); + this.owners.save(owner); - // retrieving new name from database - owner = this.owners.findById(1); - assertThat(owner.getLastName()).isEqualTo(newLastName); - } + // retrieving new name from database + owner = this.owners.findById(1); + assertThat(owner.getLastName()).isEqualTo(newLastName); + } - @Test - void shouldFindPetWithCorrectId() { - Pet pet7 = this.pets.findById(7); - assertThat(pet7.getName()).startsWith("Samantha"); - assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean"); + @Test + void shouldFindPetWithCorrectId() { + Pet pet7 = this.pets.findById(7); + assertThat(pet7.getName()).startsWith("Samantha"); + assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean"); - } + } - @Test - void shouldFindAllPetTypes() { - Collection petTypes = this.pets.findPetTypes(); + @Test + void shouldFindAllPetTypes() { + Collection petTypes = this.pets.findPetTypes(); - PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1); - assertThat(petType1.getName()).isEqualTo("cat"); - PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4); - assertThat(petType4.getName()).isEqualTo("snake"); - } + PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1); + assertThat(petType1.getName()).isEqualTo("cat"); + PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4); + assertThat(petType4.getName()).isEqualTo("snake"); + } - @Test - @Transactional - void shouldInsertPetIntoDatabaseAndGenerateId() { - Owner owner6 = this.owners.findById(6); - int found = owner6.getPets().size(); + @Test + @Transactional + void shouldInsertPetIntoDatabaseAndGenerateId() { + Owner owner6 = this.owners.findById(6); + int found = owner6.getPets().size(); - Pet pet = new Pet(); - pet.setName("bowser"); - Collection types = this.pets.findPetTypes(); - pet.setType(EntityUtils.getById(types, PetType.class, 2)); - pet.setBirthDate(LocalDate.now()); - owner6.addPet(pet); - assertThat(owner6.getPets().size()).isEqualTo(found + 1); + Pet pet = new Pet(); + pet.setName("bowser"); + Collection types = this.pets.findPetTypes(); + pet.setType(EntityUtils.getById(types, PetType.class, 2)); + pet.setBirthDate(LocalDate.now()); + owner6.addPet(pet); + assertThat(owner6.getPets().size()).isEqualTo(found + 1); - this.pets.save(pet); - this.owners.save(owner6); + this.pets.save(pet); + this.owners.save(owner6); - owner6 = this.owners.findById(6); - assertThat(owner6.getPets().size()).isEqualTo(found + 1); - // checks that id has been generated - assertThat(pet.getId()).isNotNull(); - } + owner6 = this.owners.findById(6); + assertThat(owner6.getPets().size()).isEqualTo(found + 1); + // checks that id has been generated + assertThat(pet.getId()).isNotNull(); + } - @Test - @Transactional - void shouldUpdatePetName() throws Exception { - Pet pet7 = this.pets.findById(7); - String oldName = pet7.getName(); + @Test + @Transactional + void shouldUpdatePetName() throws Exception { + Pet pet7 = this.pets.findById(7); + String oldName = pet7.getName(); - String newName = oldName + "X"; - pet7.setName(newName); - this.pets.save(pet7); + String newName = oldName + "X"; + pet7.setName(newName); + this.pets.save(pet7); - pet7 = this.pets.findById(7); - assertThat(pet7.getName()).isEqualTo(newName); - } + pet7 = this.pets.findById(7); + assertThat(pet7.getName()).isEqualTo(newName); + } - @Test - void shouldFindVets() { - Collection vets = this.vets.findAll(); + @Test + void shouldFindVets() { + Collection vets = this.vets.findAll(); - Vet vet = EntityUtils.getById(vets, Vet.class, 3); - assertThat(vet.getLastName()).isEqualTo("Douglas"); - assertThat(vet.getNrOfSpecialties()).isEqualTo(2); - assertThat(vet.getSpecialties().get(0).getName()).isEqualTo("dentistry"); - assertThat(vet.getSpecialties().get(1).getName()).isEqualTo("surgery"); - } + Vet vet = EntityUtils.getById(vets, Vet.class, 3); + assertThat(vet.getLastName()).isEqualTo("Douglas"); + assertThat(vet.getNrOfSpecialties()).isEqualTo(2); + assertThat(vet.getSpecialties().get(0).getName()).isEqualTo("dentistry"); + assertThat(vet.getSpecialties().get(1).getName()).isEqualTo("surgery"); + } - @Test - @Transactional - void shouldAddNewVisitForPet() { - Pet pet7 = this.pets.findById(7); - int found = pet7.getVisits().size(); - Visit visit = new Visit(); - pet7.addVisit(visit); - visit.setDescription("test"); - this.visits.save(visit); - this.pets.save(pet7); + @Test + @Transactional + void shouldAddNewVisitForPet() { + Pet pet7 = this.pets.findById(7); + int found = pet7.getVisits().size(); + Visit visit = new Visit(); + pet7.addVisit(visit); + visit.setDescription("test"); + this.visits.save(visit); + this.pets.save(pet7); - pet7 = this.pets.findById(7); - assertThat(pet7.getVisits().size()).isEqualTo(found + 1); - assertThat(visit.getId()).isNotNull(); - } + pet7 = this.pets.findById(7); + assertThat(pet7.getVisits().size()).isEqualTo(found + 1); + assertThat(visit.getId()).isNotNull(); + } - @Test - void shouldFindVisitsByPetId() throws Exception { - Collection visits = this.visits.findByPetId(7); - assertThat(visits).hasSize(2); - Visit[] visitArr = visits.toArray(new Visit[visits.size()]); - assertThat(visitArr[0].getDate()).isNotNull(); - assertThat(visitArr[0].getPetId()).isEqualTo(7); - } + @Test + void shouldFindVisitsByPetId() throws Exception { + Collection visits = this.visits.findByPetId(7); + assertThat(visits).hasSize(2); + Visit[] visitArr = visits.toArray(new Visit[visits.size()]); + assertThat(visitArr[0].getDate()).isNotNull(); + assertThat(visitArr[0].getPetId()).isEqualTo(7); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java b/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java index 8890cc59a..ca8bc41fc 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java +++ b/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java @@ -22,8 +22,8 @@ import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.samples.petclinic.model.BaseEntity; /** - * Utility methods for handling entities. Separate from the BaseEntity class mainly because of dependency on the - * ORM-associated ObjectRetrievalFailureException. + * Utility methods for handling entities. Separate from the BaseEntity class mainly + * because of dependency on the ORM-associated ObjectRetrievalFailureException. * * @author Juergen Hoeller * @author Sam Brannen @@ -32,23 +32,22 @@ import org.springframework.samples.petclinic.model.BaseEntity; */ public abstract class EntityUtils { - /** - * Look up the entity of the given class with the given id in the given collection. - * - * @param entities the collection to search - * @param entityClass the entity class to look up - * @param entityId the entity id to look up - * @return the found entity - * @throws ObjectRetrievalFailureException if the entity was not found - */ - public static T getById(Collection entities, Class entityClass, int entityId) - throws ObjectRetrievalFailureException { - for (T entity : entities) { - if (entity.getId() == entityId && entityClass.isInstance(entity)) { - return entity; - } - } - throw new ObjectRetrievalFailureException(entityClass, entityId); - } + /** + * Look up the entity of the given class with the given id in the given collection. + * @param entities the collection to search + * @param entityClass the entity class to look up + * @param entityId the entity id to look up + * @return the found entity + * @throws ObjectRetrievalFailureException if the entity was not found + */ + public static T getById(Collection entities, Class entityClass, int entityId) + throws ObjectRetrievalFailureException { + for (T entity : entities) { + if (entity.getId() == entityId && entityClass.isInstance(entity)) { + return entity; + } + } + throw new ObjectRetrievalFailureException(entityClass, entityId); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java index f15689ce2..6bafc7499 100644 --- a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java @@ -38,13 +38,14 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @WebMvcTest(controllers = CrashController.class) class CrashControllerTests { - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; + + @Test + void testTriggerException() throws Exception { + mockMvc.perform(get("/oups")).andExpect(view().name("exception")) + .andExpect(model().attributeExists("exception")).andExpect(forwardedUrl("exception")) + .andExpect(status().isOk()); + } - @Test - void testTriggerException() throws Exception { - mockMvc.perform(get("/oups")).andExpect(view().name("exception")) - .andExpect(model().attributeExists("exception")) - .andExpect(forwardedUrl("exception")).andExpect(status().isOk()); - } } diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java index 5b6d387e7..fd537bee2 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java @@ -40,43 +40,41 @@ import org.springframework.test.web.servlet.ResultActions; @WebMvcTest(VetController.class) class VetControllerTests { - @Autowired - private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean - private VetRepository vets; + @MockBean + private VetRepository vets; - @BeforeEach - void setup() { - Vet james = new Vet(); - james.setFirstName("James"); - james.setLastName("Carter"); - james.setId(1); - Vet helen = new Vet(); - helen.setFirstName("Helen"); - helen.setLastName("Leary"); - helen.setId(2); - Specialty radiology = new Specialty(); - radiology.setId(1); - radiology.setName("radiology"); - helen.addSpecialty(radiology); - given(this.vets.findAll()).willReturn(Lists.newArrayList(james, helen)); - } + @BeforeEach + void setup() { + Vet james = new Vet(); + james.setFirstName("James"); + james.setLastName("Carter"); + james.setId(1); + Vet helen = new Vet(); + helen.setFirstName("Helen"); + helen.setLastName("Leary"); + helen.setId(2); + Specialty radiology = new Specialty(); + radiology.setId(1); + radiology.setName("radiology"); + helen.addSpecialty(radiology); + given(this.vets.findAll()).willReturn(Lists.newArrayList(james, helen)); + } - @Test - void testShowVetListHtml() throws Exception { - mockMvc.perform(get("/vets.html")) - .andExpect(status().isOk()) - .andExpect(model().attributeExists("vets")) - .andExpect(view().name("vets/vetList")); - } + @Test + void testShowVetListHtml() throws Exception { + mockMvc.perform(get("/vets.html")).andExpect(status().isOk()).andExpect(model().attributeExists("vets")) + .andExpect(view().name("vets/vetList")); + } - @Test - void testShowResourcesVetList() throws Exception { - ResultActions actions = mockMvc.perform(get("/vets") - .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); - actions.andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.vetList[0].id").value(1)); - } + @Test + void testShowResourcesVetList() throws Exception { + ResultActions actions = mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + actions.andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.vetList[0].id").value(1)); + } } diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java index 82163eb14..d8df78b85 100644 --- a/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java +++ b/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java @@ -25,17 +25,16 @@ import static org.assertj.core.api.Assertions.assertThat; */ class VetTests { - @Test - void testSerialization() { - Vet vet = new Vet(); - vet.setFirstName("Zaphod"); - vet.setLastName("Beeblebrox"); - vet.setId(123); - Vet other = (Vet) SerializationUtils - .deserialize(SerializationUtils.serialize(vet)); - assertThat(other.getFirstName()).isEqualTo(vet.getFirstName()); - assertThat(other.getLastName()).isEqualTo(vet.getLastName()); - assertThat(other.getId()).isEqualTo(vet.getId()); - } + @Test + void testSerialization() { + Vet vet = new Vet(); + vet.setFirstName("Zaphod"); + vet.setLastName("Beeblebrox"); + vet.setId(123); + Vet other = (Vet) SerializationUtils.deserialize(SerializationUtils.serialize(vet)); + assertThat(other.getFirstName()).isEqualTo(vet.getFirstName()); + assertThat(other.getLastName()).isEqualTo(vet.getLastName()); + assertThat(other.getId()).isEqualTo(vet.getId()); + } } From 108a81b946fc12c22dcaf10d7b500daf6969a1be Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 25 Jan 2020 20:30:18 +0100 Subject: [PATCH 05/48] Upgrade to Spring Boot 2.2.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7cb6a8faf..ba704794a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.2.RELEASE + 2.2.4.RELEASE petclinic From 93873665453584deb891569c02e3acc7283cf394 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 25 Jan 2020 20:31:07 +0100 Subject: [PATCH 06/48] Upgrade to spring javaformat 0.0.19 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ba704794a..de722ff91 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ 1.8.0 0.8.5 - 0.0.17 + 0.0.19 From 5742ecd6ce5bd1fd88e04699e8e16c59cf1efd92 Mon Sep 17 00:00:00 2001 From: vbadipat <42500186+vbadipat@users.noreply.github.com> Date: Fri, 31 Jan 2020 06:30:24 -0500 Subject: [PATCH 07/48] Use https for Maven XSD See gh-522 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index de722ff91..f79e7c012 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 org.springframework.samples spring-petclinic From 400e3028f48a6c23f5156f6598dd10cb5e6a2849 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 31 Jan 2020 16:53:53 +0100 Subject: [PATCH 08/48] Polish "Use https for Maven XSD" See gh-522 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f79e7c012..cf9a9493e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.springframework.samples spring-petclinic From 1cc942a4ad75ad844202f6f18e352b4a624e8879 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 31 Jan 2020 17:31:19 +0100 Subject: [PATCH 09/48] Add nohttp check --- .mvn/wrapper/MavenWrapperDownloader.java | 2 +- mvnw | 2 +- mvnw.cmd | 2 +- pom.xml | 36 ++++++++++++++++++- .../nohttp-checkstyle-suppressions.xml | 8 +++++ src/checkstyle/nohttp-checkstyle.xml | 7 ++++ 6 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 src/checkstyle/nohttp-checkstyle-suppressions.xml create mode 100644 src/checkstyle/nohttp-checkstyle.xml diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index c32394f14..c01806e55 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0' * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/mvnw b/mvnw index d2f0ea380..05f3faa58 100755 --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0' # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an diff --git a/mvnw.cmd b/mvnw.cmd index b26ab24f0..ddd991886 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -7,7 +7,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM https://www.apache.org/licenses/LICENSE-2.0' @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an diff --git a/pom.xml b/pom.xml index cf9a9493e..ebaf8c43c 100644 --- a/pom.xml +++ b/pom.xml @@ -28,8 +28,8 @@ 1.8.0 0.8.5 + 0.0.4.RELEASE 0.0.19 - @@ -145,6 +145,40 @@
+ + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.0 + + + com.puppycrawl.tools + checkstyle + 8.25 + + + io.spring.nohttp + nohttp-checkstyle + ${nohttp-checkstyle.version} + + + + + nohttp-checkstyle-validation + validate + + src/checkstyle/nohttp-checkstyle.xml + src/checkstyle/nohttp-checkstyle-suppressions.xml + UTF-8 + ${basedir} + **/* + **/.git/**/*,**/.idea/**/*,**/target/**/,**/.flattened-pom.xml,**/*.class + + + check + + + + org.springframework.boot spring-boot-maven-plugin diff --git a/src/checkstyle/nohttp-checkstyle-suppressions.xml b/src/checkstyle/nohttp-checkstyle-suppressions.xml new file mode 100644 index 000000000..1b40e8b3f --- /dev/null +++ b/src/checkstyle/nohttp-checkstyle-suppressions.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/checkstyle/nohttp-checkstyle.xml b/src/checkstyle/nohttp-checkstyle.xml new file mode 100644 index 000000000..e6205127b --- /dev/null +++ b/src/checkstyle/nohttp-checkstyle.xml @@ -0,0 +1,7 @@ + + + + + From ac3e64208e3bcf85eaeff2f870083212f526676f Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 3 Feb 2020 09:20:37 +0000 Subject: [PATCH 10/48] Update checkstyle plugin for security scan warning --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ebaf8c43c..799b66e98 100644 --- a/pom.xml +++ b/pom.xml @@ -153,7 +153,7 @@ com.puppycrawl.tools checkstyle - 8.25 + 8.29 io.spring.nohttp From 5c35771a20ec29fd49a6cb54512159d3d7c0aa94 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 10 Mar 2020 08:29:36 +0000 Subject: [PATCH 11/48] Wrong name for user.sql script --- src/main/resources/db/mysql/petclinic_db_setup_mysql.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt index f6ce6523c..29bb601fe 100644 --- a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt +++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt @@ -27,5 +27,6 @@ line, but any way that sets that property in a Spring Boot app should work). N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value -as it is configured by default. This condition is taken care of by the docker-compose -configuration provided, or by the `schema.sql` if you can run that as root. +as it is configured by default. This condition is taken care of automatically by the +docker-compose configuration provided, or by the `user.sql` script if you run that as +root. From e0eec8e3a6075634e4e95f7cc44cf9d73b3dc5e6 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:17:34 +0100 Subject: [PATCH 12/48] Add m2e profile for well-known plugins See gh-519 --- pom.xml | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/pom.xml b/pom.xml index 799b66e98..28c86da1d 100644 --- a/pom.xml +++ b/pom.xml @@ -323,4 +323,60 @@ + + + m2e + + + m2e.version + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + [1,) + + check + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + [1,) + + build-info + + + + + + + + + + + + + + + + From a79cb9a008022de37ad93a03f89157d32b432c9c Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:17:58 +0100 Subject: [PATCH 13/48] Upgrade to Spring Boot 2.2.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 28c86da1d..0ed90e06b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.4.RELEASE + 2.2.5.RELEASE petclinic From e62458833c10be5c91e5f8923af56bed93851c04 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:18:28 +0100 Subject: [PATCH 14/48] Upgrade to spring javaformat 0.0.20 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0ed90e06b..978803473 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 0.8.5 0.0.4.RELEASE - 0.0.19 + 0.0.20 From c0847b7571e58a18333addaa691691edebb7491c Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:24:24 +0100 Subject: [PATCH 15/48] Add support for H2 Closes gh-584 --- pom.xml | 6 +-- readme.md | 7 ++- src/main/resources/application.properties | 2 +- src/main/resources/db/h2/data.sql | 53 +++++++++++++++++++ src/main/resources/db/h2/schema.sql | 64 +++++++++++++++++++++++ 5 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 src/main/resources/db/h2/data.sql create mode 100644 src/main/resources/db/h2/schema.sql diff --git a/pom.xml b/pom.xml index 978803473..becd05b79 100644 --- a/pom.xml +++ b/pom.xml @@ -66,10 +66,10 @@ - + - org.hsqldb - hsqldb + com.h2database + h2 runtime diff --git a/readme.md b/readme.md index 77de7dc77..286e525d1 100644 --- a/readme.md +++ b/readme.md @@ -35,8 +35,11 @@ Our issue tracker is available here: https://github.com/spring-projects/spring-p ## Database configuration -In its default configuration, Petclinic uses an in-memory database (HSQLDB) which -gets populated at startup with data. A similar setup is provided for MySql in case a persistent database configuration is needed. +In its default configuration, Petclinic uses an in-memory database (H2) which +gets populated at startup with data. The h2 console is automatically exposed at `http://localhost:8080/h2-console` +and it is possibl to inspect the content of the database using the `jdbc:h2:mem:testdb` url. + +A similar setup is provided for MySql in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. You could start MySql locally with whatever installer works for your OS, or with docker: diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b93ff4de3..c87dbf7a9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ # database init, supports mysql too -database=hsqldb +database=h2 spring.datasource.schema=classpath*:db/${database}/schema.sql spring.datasource.data=classpath*:db/${database}/data.sql diff --git a/src/main/resources/db/h2/data.sql b/src/main/resources/db/h2/data.sql new file mode 100644 index 000000000..16dda3e84 --- /dev/null +++ b/src/main/resources/db/h2/data.sql @@ -0,0 +1,53 @@ +INSERT INTO vets VALUES (1, 'James', 'Carter'); +INSERT INTO vets VALUES (2, 'Helen', 'Leary'); +INSERT INTO vets VALUES (3, 'Linda', 'Douglas'); +INSERT INTO vets VALUES (4, 'Rafael', 'Ortega'); +INSERT INTO vets VALUES (5, 'Henry', 'Stevens'); +INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins'); + +INSERT INTO specialties VALUES (1, 'radiology'); +INSERT INTO specialties VALUES (2, 'surgery'); +INSERT INTO specialties VALUES (3, 'dentistry'); + +INSERT INTO vet_specialties VALUES (2, 1); +INSERT INTO vet_specialties VALUES (3, 2); +INSERT INTO vet_specialties VALUES (3, 3); +INSERT INTO vet_specialties VALUES (4, 2); +INSERT INTO vet_specialties VALUES (5, 1); + +INSERT INTO types VALUES (1, 'cat'); +INSERT INTO types VALUES (2, 'dog'); +INSERT INTO types VALUES (3, 'lizard'); +INSERT INTO types VALUES (4, 'snake'); +INSERT INTO types VALUES (5, 'bird'); +INSERT INTO types VALUES (6, 'hamster'); + +INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023'); +INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749'); +INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763'); +INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198'); +INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765'); +INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654'); +INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387'); +INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683'); +INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); +INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); + +INSERT INTO pets VALUES (1, 'Leo', '2010-09-07', 1, 1); +INSERT INTO pets VALUES (2, 'Basil', '2012-08-06', 6, 2); +INSERT INTO pets VALUES (3, 'Rosy', '2011-04-17', 2, 3); +INSERT INTO pets VALUES (4, 'Jewel', '2010-03-07', 2, 3); +INSERT INTO pets VALUES (5, 'Iggy', '2010-11-30', 3, 4); +INSERT INTO pets VALUES (6, 'George', '2010-01-20', 4, 5); +INSERT INTO pets VALUES (7, 'Samantha', '2012-09-04', 1, 6); +INSERT INTO pets VALUES (8, 'Max', '2012-09-04', 1, 6); +INSERT INTO pets VALUES (9, 'Lucky', '2011-08-06', 5, 7); +INSERT INTO pets VALUES (10, 'Mulligan', '2007-02-24', 2, 8); +INSERT INTO pets VALUES (11, 'Freddy', '2010-03-09', 5, 9); +INSERT INTO pets VALUES (12, 'Lucky', '2010-06-24', 2, 10); +INSERT INTO pets VALUES (13, 'Sly', '2012-06-08', 1, 10); + +INSERT INTO visits VALUES (1, 7, '2013-01-01', 'rabies shot'); +INSERT INTO visits VALUES (2, 8, '2013-01-02', 'rabies shot'); +INSERT INTO visits VALUES (3, 8, '2013-01-03', 'neutered'); +INSERT INTO visits VALUES (4, 7, '2013-01-04', 'spayed'); diff --git a/src/main/resources/db/h2/schema.sql b/src/main/resources/db/h2/schema.sql new file mode 100644 index 000000000..f3c6947b7 --- /dev/null +++ b/src/main/resources/db/h2/schema.sql @@ -0,0 +1,64 @@ +DROP TABLE vet_specialties IF EXISTS; +DROP TABLE vets IF EXISTS; +DROP TABLE specialties IF EXISTS; +DROP TABLE visits IF EXISTS; +DROP TABLE pets IF EXISTS; +DROP TABLE types IF EXISTS; +DROP TABLE owners IF EXISTS; + + +CREATE TABLE vets ( + id INTEGER IDENTITY PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR(30) +); +CREATE INDEX vets_last_name ON vets (last_name); + +CREATE TABLE specialties ( + id INTEGER IDENTITY PRIMARY KEY, + name VARCHAR(80) +); +CREATE INDEX specialties_name ON specialties (name); + +CREATE TABLE vet_specialties ( + vet_id INTEGER NOT NULL, + specialty_id INTEGER NOT NULL +); +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id); +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id); + +CREATE TABLE types ( + id INTEGER IDENTITY PRIMARY KEY, + name VARCHAR(80) +); +CREATE INDEX types_name ON types (name); + +CREATE TABLE owners ( + id INTEGER IDENTITY PRIMARY KEY, + first_name VARCHAR(30), + last_name VARCHAR_IGNORECASE(30), + address VARCHAR(255), + city VARCHAR(80), + telephone VARCHAR(20) +); +CREATE INDEX owners_last_name ON owners (last_name); + +CREATE TABLE pets ( + id INTEGER IDENTITY PRIMARY KEY, + name VARCHAR(30), + birth_date DATE, + type_id INTEGER NOT NULL, + owner_id INTEGER NOT NULL +); +ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners (id); +ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id); +CREATE INDEX pets_name ON pets (name); + +CREATE TABLE visits ( + id INTEGER IDENTITY PRIMARY KEY, + pet_id INTEGER NOT NULL, + visit_date DATE, + description VARCHAR(255) +); +ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id); +CREATE INDEX visits_pet_id ON visits (pet_id); From 8805eaa721a6ce59cbd7870653dc28afda806c0a Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 20 Mar 2020 18:26:24 +0100 Subject: [PATCH 16/48] Disable open-in-view explicitly to remove warning on startup --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c87dbf7a9..4f2c86834 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,6 +8,7 @@ spring.thymeleaf.mode=HTML # JPA spring.jpa.hibernate.ddl-auto=none +spring.jpa.open-in-view=false # Internationalization spring.messages.basename=messages/messages From 8db8c272c102127664d8896ebe63d9d2af76359e Mon Sep 17 00:00:00 2001 From: James Artz Date: Sun, 29 Mar 2020 16:12:22 -0500 Subject: [PATCH 17/48] Fix typo in readme See gh-586 --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 286e525d1..716676ed3 100644 --- a/readme.md +++ b/readme.md @@ -37,7 +37,7 @@ Our issue tracker is available here: https://github.com/spring-projects/spring-p In its default configuration, Petclinic uses an in-memory database (H2) which gets populated at startup with data. The h2 console is automatically exposed at `http://localhost:8080/h2-console` -and it is possibl to inspect the content of the database using the `jdbc:h2:mem:testdb` url. +and it is possible to inspect the content of the database using the `jdbc:h2:mem:testdb` url. A similar setup is provided for MySql in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. From d9f37ece5c865ded91b6582828142ccc33e9d54f Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 2 May 2020 07:51:21 +0200 Subject: [PATCH 18/48] Upgrade to Spring Boot 2.3.0.RC1 --- pom.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index becd05b79..2c4ddf801 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.2.0.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT org.springframework.boot spring-boot-starter-parent - 2.2.5.RELEASE + 2.3.0.RC1 petclinic @@ -50,6 +50,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-validation + org.springframework.boot spring-boot-starter-thymeleaf From 628862206bd20efcce9ae5f97b89aad59bb2c9ca Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 2 May 2020 08:02:49 +0200 Subject: [PATCH 19/48] Switch actuator to standard path --- src/main/resources/application.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4f2c86834..4d4784e36 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -13,8 +13,7 @@ spring.jpa.open-in-view=false # Internationalization spring.messages.basename=messages/messages -# Actuator / Management -management.endpoints.web.base-path=/manage +# Actuator management.endpoints.web.exposure.include=* # Logging From 6a18eecc9b74f67dbcc8a7b7e11044db2f6907d7 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 3 May 2020 08:55:22 +0200 Subject: [PATCH 20/48] Upgrade to spring javaformat 0.0.21 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2c4ddf801..41689d542 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 0.8.5 0.0.4.RELEASE - 0.0.20 + 0.0.21 From adab01ef624418db4a9677c5c641a039d39b7a18 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 3 May 2020 08:55:49 +0200 Subject: [PATCH 21/48] Upgrade to maven checkstyle plugin 3.1.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 41689d542..2baea5a12 100644 --- a/pom.xml +++ b/pom.xml @@ -152,7 +152,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.0 + 3.1.1 com.puppycrawl.tools From c9230c37b9e6aac71d0724eccf3236dde034ce27 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 27 May 2020 13:40:44 +0000 Subject: [PATCH 22/48] Bump to Spring Boot 2.3.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2baea5a12..ef1417bf6 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.0.RC1 + 2.3.0.RELEASE petclinic From 907eea340b7d51faf8f668cd15a1ae3b001fb7ef Mon Sep 17 00:00:00 2001 From: Kristof Neirynck Date: Sat, 16 May 2020 16:32:48 +0200 Subject: [PATCH 23/48] Upgrade to Maven 3.6.3 and Maven Wrapper 0.5.6 --- .mvn/wrapper/MavenWrapperDownloader.java | 2 +- .mvn/wrapper/maven-wrapper.jar | Bin 50710 -> 50710 bytes .mvn/wrapper/maven-wrapper.properties | 5 +++-- mvnw | 8 ++++---- mvnw.cmd | 8 ++++---- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index c01806e55..89964d141 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -20,7 +20,7 @@ import java.util.Properties; public class MavenWrapperDownloader { - private static final String WRAPPER_VERSION = "0.5.5"; + private static final String WRAPPER_VERSION = "0.5.6"; /** * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. */ diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index 0d5e649888a4843c1520054d9672f80c62ebbb48..2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054 100644 GIT binary patch delta 3148 zcmV-S472l=j02X81CVcj!Y~j;_kr9Y7f7fTMY^-DDhPtbt%PKXL)#=wW5wIsR#d1f zcf zy__;pIHO)tEBCe@*KSmDNtfx|J72@u6HrSB2uq>eF|!*1M*#ujlVbuf3QV*>1v&r# z0674YApsn-xdP=I0ade~9+M3U<)K>#+z$W%h#!+tNgT6SER_O(CC#v9TgqtCG)aeS zE5z}v?bvnF)?DPXtyH>GPN$3x3Z+0gv=u)G)3zY(Y%Z{rj)nH83$Adk`j%yK1U}anQK zEa2_TQ}`E$ zm@wiRMV9gicMrgyv`um4^ z`r6#^PM_-w_x2p_>vZD+fkoVrjQZPqy4_eMuyAK!cVMT0TYl&b4IFf1jlktIoa!u^ zorQg-Xsg-YYCaa#12;qyWVb&Oi|SG9a)FBahCzYKR%29i!AILmecFRCK5Bz9yp|O~){Y^nL z0s^j+GH^X(B`h7ZlxMjf+Z1fa4uPuuS*vTysWa%t#dJk55Z@sW?N)FJ_VAE|s6Hyt zJTDuv{<7unRj?2H>2J$$J_=k=Uq;7jFsKR^qKf!`>Wu1IcPf5NGY8aTF-_v!h^Vna z)r`uuz3D*(TBK3ysIWB=O$s!2&O6nZCY5nM1yJs z7Z0`WP|%4k(r0BIQccEg+Qz66JP?g(`y^$Lf?ixDuslnd#YR-4?ibb<)0a8kuV6qP zcbSHNVYNj~xi_d_NV<1PmgS&kCaISjO!V3T^?G{DXWQ<}8t?PqD6Vzk8iDn*daKhI zAJYjY&M)YGE2ni{8eCvn<^Qv&s~dNvz{@M$fQvJ7%P zgB$3`e74M~llmzSZpN)LGoLH4wM@Y%mu@aRkL7GuX}zj75lSYtIE}S& z{{jWK%cNUu(;a3_K4_QZ+wdYOIpM*Lc!_*_sqMnq&B*D$Z+4<0>9(>jV=0`KyoKqR zw78Ikrr%OcOX_?FS|mVTso+(3HIrC>vjf5iN6R69c4cw_nuDgC26j!WRPAJ|DI<|J zq!?-3NR)taS#n0YtSF!QEaIn%fk!aSAEdlz`=jH!YNbqyJv5Knuzx-{yPW8Mt3YU0 zJ=hZjOG`ql5s$0-sJxTdIi1v;aNdO$7v3%qn3Gq**Y| z=ws1w+s>VH0JSVPyP(~T_b7NT-X{xMEM}ZKtY5Da)jiJDC9tD@j_OdJtz`NE1s}v& z_Fs1476_LQ!knCKcB2LS_es<5SMUHn#1x1)?i6VIABNB5(=fB~aUsomPy`Ccy-vsk zTIUurpSTm4%Oj=k64>_tI@pDi8ee8TH^3_>>Euq)M}DRBGoz zsuq*C{iAq{7~UtUN($Oii+z_&$E%IE1dS2r=eUo8feg8>f4oBrBE~wax@fX~_OZ z_=yWYW^Xq)rGlU0XO7?G4AO6tzces^G#s=03jT;cG5Iaya9{h3W9dB14*nOv0L6)gil`DUiX(koCEhMAgSVq)G$;qS^VmkCg+~#KrlBvJ z3yH*SF2S*RO`#+D&*+wVI_FakQL$VgmlVf?E+J&rbuk!ieX?7u zCU&|FpDoar7s8OF^wEIq@_9#2h;@p%P^@R@Wrvo>Q3*Q^tzv_mik;C%p5EdXn`kOU zWH)`fJx%(O2`v&Gi)y33sO~!^$5fxGMYL$b;?uDx;1OFyy-RGJp7@G?#VMjePMixP zF(awD1;_MFtwxG`ieWYltgL+6bY3(w9|Y%j|J((uFhiJm<_u5QmUYAQUvUb{c5MOM zJPtU^iHjAnOa6(Xim}x6lbl|iqT%#;wWZ^7K=Q!`Hr^Egs!=Bgb-vZX#V3Ku_XYO; zqJp);^^$`1Qm&U3te10t?JZc>aD73+x|Zt|1?!bu*A=W+!^5|=SjU|UxpRfB9k6B! z>xaD?GPo#%hDijyJJZ;e#-$J7vit0VSMb-vC*UKKW?X6Sf^4?um<9P1d@l4)B9uQ? zWpA#xk0=fSTG3{EC5!{4dIsMs`Q@O^<|%6E;xm@Pq0Yt(y1V#))7PEB;k}i%npac7 zx=KgE431AGXsYV2^=i35uxefz-t01po4ACc*R%JKCGl>jUUPj1#1P_vbgGY}1*~lIxCmFZ~`g#ge z(u3ZICUGup%Q=epoA+O7JbfqXLA~{?5AUq1ROBR4A8Kc zh+f5<@ZmT%GiREaDccdJz6NPe@Vvp(308p<#D_^PNe0=nE%(!wYP5-<*k=2oS!`#< z2=b^~6C3EY1*BBygB^C%ZqG%{poY@R+r8DSX&wGYq1X|S?)NGgv2(bia7(`2kIU@f zpeQJ3_1WTda mF|$Rq7XbuJv_J*3V6{gB1m&Sy2a~I~r34XhbG@@vxxx%M3nM-N delta 3147 zcmV-R47Br>j02X81CVcjgD?<9_kr9Y7f8^BAns~c7KB2j+Y*wI4r&s{)Y98mEp5TB zx*Pr<-s9KWVGCoFXP^<* zBXh+G=vy4gPdK0AU2#_4u#d8QEO6HnSk6uX47OOr9OtTvSM*#ullVbuf3fanwIywLV z0674YApsn-xdP=I0a3G`9+M3U7#^fv+z$W%h#!+tNgT6SER_O(W!thX#YvNON~pP`4+InXsYJP__}?(Pe_v4m28>>Wwc73$>HvZ<|}P+#9* zcW<%;uxaEhQQ2!w})(9M!;Z$eQ z=q&6r)3zGzt;XX~J#a%bL3aBiv8W!k4hWRh)(r@hw-_Uu3qIOj?9=8{G&Z7{Zfq2& z%sI(}&DiRH!j@?v>pPpYw77z8sHH7qn$=?(jIMQ7U~BEnVAajs^1zP<7wV_8wZAE7 zL_olGN(Qcbw1}mHmeMTOW4nST>=3BfpS8NWlsW@$TtZg_1Mwa5&~62nVh;~Vi0UH( zjq|c0>n~gGUIqKGpZ>NC=cB+ywIy_{1cRzzAu5P}ua2m$b*19RHM3tm9@8Ywjfff> zP|c`Z+nXMgp;;QWjtX1j(WF3q$GlUGX;L2NQ(#5yu~Lo@@PyAqw1gF9wz$wHP?e|3 zeeqE1b_E^iBz;!aVbx^prfiHF!GqD5wog)aE9k*h0?V_MS!_f#>V9$Ubovs<`xNxc z<1W*GFs#<7Dfb2x3`+Md$+8^K%p~=4gNa_t^k9K*FPTqCf4R&R9} zV`G}B;5vzz@~A#)NU%Rsfr{hI<2L97Sl`@o+aR)m9ABP z8&y*=tJOHI#|+i3j?b1kbxJ?&!Ogf;X6ADRwv{LtrP9rX=dqm4Dy>Jg#zV=Z7N@Z` z?q8tbcA0dGZMq|@$%pKcd>dXQB_}+%5igN%FST7byBRtC_svc;O}ee@%UB9$C2wYW zCM_;xq3N?!(~>&hfo2JiS1NcFUd<$b*6e^V!qHO5pIw<;faahnrGZ`3%2hkrs!B*? z4VjKKZX}ApxGXs%T~?G%eHQW4(}71Y%^#$^XZxaKx@x6Niak7!+OU5`}%#KB#7r-FNb@h;jK zG4#>sm~H3IIe=P{n_bZE#(NaJ7w?k=EfzCQAJMPZiRy0W>Jr#dJ4baW%~mq~fPxR= z9Q!Z3a0`S>2VqXmHoK7m{`;iq_bYe+A7Tnb9Cr$|{tv@v@~NBI__&Z}J(vax$GuL- z1X|`6GM~5;n9C!@?h@Gk|2o){;xiI|#3QndeN14}>^DKKjC$}1e9DDSQl(inDz@_w zRg1~n{!u(e4DoWGc`2?h-JKL%%#-+xg2(NWEZYOs)O1Ud$}gW&@Ojy!ROY_O-7hNm zlH7H1w@Z!F17G3YeNEtmYHoJpYiysVIl_-`DEKD6MZcL^BBn;PgHba{@a&mO-xX7; zEuO@!9z22Xx$s>UtUN(WOii+z_&$E%IE1dS2r=eUtKoEw8>f1nBrBE~wax~MX~_OZ z_=yWYW^Xq)rGlU0XO7?G4AN(lzBDj@6dber3jT;cG5IayNN?MWV{HWRp9NOuJ=UAj zt!P{;XpAr5uM)UV%Kosx_xyLkMNbq_&2YvQ5#Ku z{6`TGf>6;;rqo!nXp)(lf{waH87GPsRo4y6H=;3lpGY% z3sECr*>i%kZk#F;2_rr&|DF(kD-^L(ta37X#bP}}FFUk6j*8fEXcZgeRP2mC^7K}>*i2I? zBD?9+?P=1NOlXnlXjB{VMRnhCIi~tdEuuve7N3qq0gu=!YF%R6)WkP`U7RB7XL4l`YTRh*{&{N zo5ulXIdO?1cF8|cR4|sBeu~qpQ#71Duex|#4oE)Oz{a}_KqYGApw71%xcDS6`M$v3 zUsSMGxL#7QUdr{dg7tELuDu28Dy}aoSXXnsqF}v}>zab~YIyjz7VEfkF?X)8wFA~n zV*QYJLk62NsGC60yEBblXF9oXjA#x1y%PKZzTMCUNtS_m-OS2|Q;Kw+&_R z{0Y2p0xzD#9YYg%c^a?CYa3uZfbG<$iTdqeG%lf+cVQbYMFaNmZ7(jvel+89&dvvH zs}4E(;x%}!ZOJ%)I`BH$Q;7&(&$k8Savl2lRz_Y!7^F|i$?ZzK0e8|H&8*RH#GAP5 zk)uE9-)!si7TX^wo{~}8Hi^5a?%O&haW|j$bk;Yd@eclf_h5a4KaKaNao;2O@VT5R zE65rM(Vfi%Q47J*%GiZ%m32vynYUPBL(H^z|er zr3bwaP2hY6AE(Q+oBo2Wyg!%Ng4!tjFly0WfPy;PBNA5qxGF1XR~ABxXwRpee|dWx zAaxb6SY$g|vgpaN2xaM3+B&82S^ocm_sia|rt$R&e7l%kZvnfNId&cB%(A=kKzCygI}rt$MMe%pR87BdhRhUzEqm-7_yH}AjFc=}G%$jvITp!^|}4VC%(GNOD! zxX(Mvh{_3}oU>&ug;y-jYO>m{3|Dh+i1;|l{Je&~x|Zk~&IM~J%EVH!jH|T>WZ$Y# zDV7Vbo!x`Pq@(eZ#Fh;FQLm^HRcTS(?tctR9JOkH99_nTCd8VKdMdQGzDoGgVq<4R zj%JgjY1muNuUl%$&vnUXyqu)Ov8qQN6A2mN{*NztY>JZ;M?Wbdr1ROBJ4A8Kc zh+f5<@ZkiuFlQQ>DNTq|UxTzKdEVgZ1gpSF;=?4DB!g_(miuW-C0a#LY`6W;D4Lit zf;?(k#0Gk80Vx&wV22&G+jCJfsG;<7ledyJt=<196gvXa{az&_b`G@{ZpoMXak(8F zObg0c{@wujw~;E`#7cKFw&Io?WGYZkp^{FB-SVWk^uJI`2MCtwdEc`?Is$qG`j5*@ lvqiKQ0R-8~i#oGlwMPR47#^fvldHI;1eWP}-?LP?!VH=^7bXAz diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 7d59a01f2..2743cab67 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,3 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar + diff --git a/mvnw b/mvnw index 05f3faa58..2c90d17e4 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script +# Maven Start Up Batch script # # Required ENV vars: # ------------------ @@ -212,9 +212,9 @@ else echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." fi if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" fi while IFS="=" read key value; do case "$key" in (wrapperUrl) jarUrl="$value"; break ;; @@ -246,7 +246,7 @@ else else curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f fi - + else if [ "$MVNW_VERBOSE" = true ]; then echo "Falling back to using Java to download" diff --git a/mvnw.cmd b/mvnw.cmd index ddd991886..0d34af450 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -18,7 +18,7 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script +@REM Maven Start Up Batch script @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @@ -26,7 +26,7 @@ @REM Optional ENV vars @REM M2_HOME - location of maven2's installed home dir @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM e.g. to debug Maven itself, use @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -120,7 +120,7 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B @@ -134,7 +134,7 @@ if exist %WRAPPER_JAR% ( ) ) else ( if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... From d94b995db23e9251a865b85bcb2d8ed99f45d8bb Mon Sep 17 00:00:00 2001 From: Kristof Neirynck Date: Thu, 21 May 2020 14:51:47 +0200 Subject: [PATCH 24/48] Change EditorConfig to be consistent with spring-javaformat spring-javaformat uses tabs to indent java files --- .editorconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.editorconfig b/.editorconfig index 8d67bc7a5..44e7e6703 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,3 +10,5 @@ indent_style = space [*.{java,xml}] indent_size = 4 trim_trailing_whitespace = true +indent_style = tab +tab_width = 4 From 9873188e291a2f81f7d5f27dea09ba5e66fede14 Mon Sep 17 00:00:00 2001 From: Kristof Neirynck Date: Sat, 23 May 2020 12:38:08 +0200 Subject: [PATCH 25/48] Change EditorConfig to reflect some files are indented with 2 spaces --- .editorconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.editorconfig b/.editorconfig index 44e7e6703..2513d2a34 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,3 +12,10 @@ indent_size = 4 trim_trailing_whitespace = true indent_style = tab tab_width = 4 + +[{pom,wro}.xml] +indent_size = 2 +indent_style = space + +[*.{html,sql,less}] +indent_size = 2 From 410abc21f3cb89977e16cb8c1c3947b31dcff7af Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 19 Apr 2020 21:56:57 +0900 Subject: [PATCH 26/48] remove trailing slash --- .../resources/templates/owners/ownerDetails.html | 12 ++++++------ .../templates/pets/createOrUpdateVisitForm.html | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/resources/templates/owners/ownerDetails.html b/src/main/resources/templates/owners/ownerDetails.html index fa2b71ee9..383fa929f 100644 --- a/src/main/resources/templates/owners/ownerDetails.html +++ b/src/main/resources/templates/owners/ownerDetails.html @@ -16,15 +16,15 @@ Address - + City - + Telephone - + @@ -44,12 +44,12 @@
Name
-
+
Birth Date
+ th:text="${#temporals.format(pet.birthDate, 'yyyy-MM-dd')}">
Type
-
+
diff --git a/src/main/resources/templates/pets/createOrUpdateVisitForm.html b/src/main/resources/templates/pets/createOrUpdateVisitForm.html index d7589c3bc..ddcbb9d59 100644 --- a/src/main/resources/templates/pets/createOrUpdateVisitForm.html +++ b/src/main/resources/templates/pets/createOrUpdateVisitForm.html @@ -19,12 +19,12 @@ - + - + th:text="${#temporals.format(pet.birthDate, 'yyyy-MM-dd')}"> + + th:text="${pet.owner?.firstName + ' ' + pet.owner?.lastName}"> @@ -52,8 +52,8 @@ Description - - + + From d17355505678e29d397c82f7b6d4405f01abef39 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 13 Jun 2020 14:09:36 +0100 Subject: [PATCH 27/48] Update to Boot 2.3.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ef1417bf6..510c933f3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.3.0.BUILD-SNAPSHOT + 2.3.1.BUILD-SNAPSHOT org.springframework.boot spring-boot-starter-parent - 2.3.0.RELEASE + 2.3.1.RELEASE petclinic From 07b9d5aa45a51ce6d2372c46880cad2192da9d07 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 13 Jun 2020 14:56:10 +0100 Subject: [PATCH 28/48] Ensure fragment for menu items is not itself rendered Formerly there was a "ghost" menu item with no text and no icon because Thymeleaf had not been instructed to remove the fragment definition. This change tidies that up and also removes the use of the "path" variable, which Thymeleaf populates from the current request context, and poses a potential security threat as a result (if users type malicious characters in the URL). --- .../resources/templates/fragments/layout.html | 136 ++++++++++-------- 1 file changed, 73 insertions(+), 63 deletions(-) diff --git a/src/main/resources/templates/fragments/layout.html b/src/main/resources/templates/fragments/layout.html index 7cb5f4697..f3b207483 100755 --- a/src/main/resources/templates/fragments/layout.html +++ b/src/main/resources/templates/fragments/layout.html @@ -1,88 +1,98 @@ - + - - - - + + + + - + - PetClinic :: a Spring Framework demonstration + PetClinic :: a Spring Framework demonstration - - + - +
-
- - +
-
-
-
-
-
- Sponsored by Pivotal
-
+ + +
+
+
+
+
+ Sponsored by Pivotal
+
From 73ede82651bf1e733b26e6c630f2aac9c855e900 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 13 Jun 2020 15:16:31 +0100 Subject: [PATCH 29/48] Replace references to main branch --- readme.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 716676ed3..eb8aa7d7e 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=master)](https://travis-ci.org/spring-projects/spring-petclinic/) +# Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=main)](https://travis-ci.org/spring-projects/spring-petclinic/) Deploy this sample application to Pivotal Web Services: @@ -48,7 +48,7 @@ You could start MySql locally with whatever installer works for your OS, or with docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 ``` -Further documentation is provided [here](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt). +Further documentation is provided [here](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt). ## Working with Petclinic in your IDE @@ -96,13 +96,13 @@ Visit [http://localhost:8080](http://localhost:8080) in your browser. |Spring Boot Configuration | Class or Java property files | |--------------------------|---| -|The Main Class | [PetClinicApplication](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java) | -|Properties Files | [application.properties](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/resources) | -|Caching | [CacheConfiguration](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) | +|The Main Class | [PetClinicApplication](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java) | +|Properties Files | [application.properties](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources) | +|Caching | [CacheConfiguration](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) | ## Interesting Spring Petclinic branches and forks -The Spring Petclinic master branch in the main [spring-projects](https://github.com/spring-projects/spring-petclinic) +The Spring Petclinic "main" branch in the [spring-projects](https://github.com/spring-projects/spring-petclinic) GitHub org is the "canonical" implementation, currently based on Spring Boot and Thymeleaf. There are [quite a few forks](https://spring-petclinic.github.io/docs/forks.html) in a special GitHub org [spring-petclinic](https://github.com/spring-petclinic). If you have a special interest in a different technology stack From d367e2b4b41a2de899b0f438bc984a7c1c011b77 Mon Sep 17 00:00:00 2001 From: Alex Hatzenbuhler Date: Mon, 30 Mar 2020 09:11:48 -0500 Subject: [PATCH 30/48] Updating spacing on step list --- readme.md | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/readme.md b/readme.md index eb8aa7d7e..8460e2de6 100644 --- a/readme.md +++ b/readme.md @@ -39,8 +39,7 @@ In its default configuration, Petclinic uses an in-memory database (H2) which gets populated at startup with data. The h2 console is automatically exposed at `http://localhost:8080/h2-console` and it is possible to inspect the content of the database using the `jdbc:h2:mem:testdb` url. -A similar setup is provided for MySql in case a persistent database configuration is needed. -Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. +A similar setup is provided for MySql in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. You could start MySql locally with whatever installer works for your OS, or with docker: @@ -66,30 +65,26 @@ The following items should be installed in your system: ### Steps: 1) On the command line -``` -git clone https://github.com/spring-projects/spring-petclinic.git -``` + ``` + git clone https://github.com/spring-projects/spring-petclinic.git + ``` 2) Inside Eclipse or STS -``` -File -> Import -> Maven -> Existing Maven project -``` + ``` + File -> Import -> Maven -> Existing Maven project + ``` -Then either build on the command line `./mvnw generate-resources` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`. + Then either build on the command line `./mvnw generate-resources` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`. 3) Inside IntelliJ IDEA + In the main menu, choose `File -> Open` and select the Petclinic [pom.xml](pom.xml). Click on the `Open` button. -In the main menu, choose `File -> Open` and select the Petclinic [pom.xml](pom.xml). Click on the `Open` button. + CSS files are generated from the Maven build. You can either build them on the command line `./mvnw generate-resources` or right click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders`. -CSS files are generated from the Maven build. You can either build them on the command line `./mvnw generate-resources` -or right click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders`. - -A run configuration named `PetClinicApplication` should have been created for you if you're using a recent Ultimate -version. Otherwise, run the application by right clicking on the `PetClinicApplication` main class and choosing -`Run 'PetClinicApplication'`. + A run configuration named `PetClinicApplication` should have been created for you if you're using a recent Ultimate version. Otherwise, run the application by right clicking on the `PetClinicApplication` main class and choosing `Run 'PetClinicApplication'`. 4) Navigate to Petclinic -Visit [http://localhost:8080](http://localhost:8080) in your browser. + Visit [http://localhost:8080](http://localhost:8080) in your browser. ## Looking for something in particular? From 0390e85c252a58917954ec682775c6672159b58c Mon Sep 17 00:00:00 2001 From: aleVeD Date: Mon, 1 Jun 2020 16:45:57 -0400 Subject: [PATCH 31/48] adding new message in Spanish --- src/main/resources/messages/messages_es.properties | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/resources/messages/messages_es.properties diff --git a/src/main/resources/messages/messages_es.properties b/src/main/resources/messages/messages_es.properties new file mode 100644 index 000000000..33ee867b5 --- /dev/null +++ b/src/main/resources/messages/messages_es.properties @@ -0,0 +1,8 @@ +welcome=Bienvenido +required=Es requerido +notFound=No ha sido encontrado +duplicate=Ya se encuentra en uso +nonNumeric=Sólo debe contener numeros +duplicateFormSubmission=No se permite el envío de formularios duplicados +typeMismatch.date=Fecha invalida +typeMismatch.birthDate=Fecha invalida From 4953f87917b449a404a7f1f4e2457836b9eafbbc Mon Sep 17 00:00:00 2001 From: Rognetta <38105584+Rognetta@users.noreply.github.com> Date: Thu, 21 Nov 2019 16:39:14 +0100 Subject: [PATCH 32/48] Update application-mysql.properties Add some environment variables with defaults for the MySQL credentials. Closes #506 --- src/main/resources/application-mysql.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index 6d54ddad7..d388c9e6d 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -1,7 +1,7 @@ # database init, supports mysql too database=mysql -spring.datasource.url=jdbc:mysql://localhost/petclinic -spring.datasource.username=petclinic -spring.datasource.password=petclinic +spring.datasource.url=${MYSQL_URL:jdbc:mysql://localhost/petclinic} +spring.datasource.username=${MYSQL_USER:petclinic} +spring.datasource.password=${MYSQL_PASS:petclinic} # SQL is written to be idempotent so this is safe spring.datasource.initialization-mode=always From 5ad6bc3ccde1c61379d751f0751a1731114761af Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 11 Jul 2020 08:56:32 +0200 Subject: [PATCH 33/48] Upgrade to spring javaformat 0.0.22 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 510c933f3..2c92f7746 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 0.8.5 0.0.4.RELEASE - 0.0.21 + 0.0.22 From 02cc84223b296e7b401cdba74905b2e18a87e51e Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sat, 11 Jul 2020 08:57:33 +0200 Subject: [PATCH 34/48] Polish --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2c92f7746..5ac0cc4c6 100644 --- a/pom.xml +++ b/pom.xml @@ -139,7 +139,6 @@ io.spring.javaformat spring-javaformat-maven-plugin ${spring-format.version} - validate @@ -281,7 +280,6 @@ - Apache License, Version 2.0 From c42f95980a943634106e7584575c053265906978 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Wed, 29 Jul 2020 16:43:31 +0200 Subject: [PATCH 35/48] remove push-to-pws button from guide, since pws free trials end --- push-to-pws/button.yml | 1 - readme.md | 5 ----- 2 files changed, 6 deletions(-) delete mode 100644 push-to-pws/button.yml diff --git a/push-to-pws/button.yml b/push-to-pws/button.yml deleted file mode 100644 index e85329d59..000000000 --- a/push-to-pws/button.yml +++ /dev/null @@ -1 +0,0 @@ -repo: https://github.com/spring-projects/spring-petclinic.git diff --git a/readme.md b/readme.md index 8460e2de6..ff6d2be15 100644 --- a/readme.md +++ b/readme.md @@ -1,9 +1,4 @@ # Spring PetClinic Sample Application [![Build Status](https://travis-ci.org/spring-projects/spring-petclinic.png?branch=main)](https://travis-ci.org/spring-projects/spring-petclinic/) -Deploy this sample application to Pivotal Web Services: - - - Push - ## Understanding the Spring Petclinic application with a few diagrams See the presentation here From d19963e1744f56ff330be879d35672733d66f641 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 27 Aug 2020 15:03:32 +0200 Subject: [PATCH 36/48] Upgrade to Spring Boot 2.3.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5ac0cc4c6..44c406725 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.1.RELEASE + 2.3.3.RELEASE petclinic From 2e5be53533d3a5cd7950ada623ade5e87d059784 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 27 Aug 2020 15:03:51 +0200 Subject: [PATCH 37/48] Upgrade to spring javaformat 0.0.25 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 44c406725..a30a98e01 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 0.8.5 0.0.4.RELEASE - 0.0.22 + 0.0.25 From be0f161453c0a986450affb901d0cf4445c0a740 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 27 Aug 2020 15:04:12 +0200 Subject: [PATCH 38/48] Upgrade to Checkstyle 8.32 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a30a98e01..38232a26c 100644 --- a/pom.xml +++ b/pom.xml @@ -156,7 +156,7 @@ com.puppycrawl.tools checkstyle - 8.29 + 8.32 io.spring.nohttp From 27109010a52600eb9bf227d631fac3f81ed6ba15 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 27 Aug 2020 15:05:30 +0200 Subject: [PATCH 39/48] Restore version to 2.3.0.BUILD-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 38232a26c..e4e74747a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.3.1.BUILD-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT org.springframework.boot From e5ef4d34e301fb03dd3097d1da0beccfa3ce8df6 Mon Sep 17 00:00:00 2001 From: Akash Solanki Date: Wed, 2 Sep 2020 16:57:51 +0530 Subject: [PATCH 40/48] Remove redundant junits dependencies See gh-670 --- pom.xml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/pom.xml b/pom.xml index e4e74747a..006f05bb8 100644 --- a/pom.xml +++ b/pom.xml @@ -114,18 +114,6 @@ - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.mockito - mockito-junit-jupiter - test - - org.springframework.boot spring-boot-devtools From a1eaaa687869ad1f83aa1575a02ad81ee546e39c Mon Sep 17 00:00:00 2001 From: Piyush Garg Date: Wed, 22 Jul 2020 18:24:23 +0530 Subject: [PATCH 41/48] Upgrade to wro4j 1.9.0 See gh-650 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 006f05bb8..a10caa34c 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 3.3.6 1.11.4 2.2.4 - 1.8.0 + 1.9.0 0.8.5 0.0.4.RELEASE From 7615395b1f07fda4fe20afa2e39928a6449524ad Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 6 Nov 2020 08:30:48 +0100 Subject: [PATCH 42/48] Upgrade to Spring Boot 2.3.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a10caa34c..16c314d13 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.3.RELEASE + 2.3.5.RELEASE petclinic From 8b1ac6736e3347f34d79620170983fc4c99746cb Mon Sep 17 00:00:00 2001 From: Cesarion Pshebytski Date: Wed, 19 Aug 2020 23:00:24 +0300 Subject: [PATCH 43/48] Updated user for mysql Updated creation of user for mysql db. Previously lack of quotes resulted in creation of incorrect user (petclinic@% instead of just petclinic) --- src/main/resources/db/mysql/user.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/mysql/user.sql b/src/main/resources/db/mysql/user.sql index 60abcee72..d2c7b88a0 100644 --- a/src/main/resources/db/mysql/user.sql +++ b/src/main/resources/db/mysql/user.sql @@ -4,4 +4,4 @@ ALTER DATABASE petclinic DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; -GRANT ALL PRIVILEGES ON petclinic.* TO 'petclinic@%' IDENTIFIED BY 'petclinic'; +GRANT ALL PRIVILEGES ON petclinic.* TO 'petclinic'@'%' IDENTIFIED BY 'petclinic'; From ab9135ad9bbc8631221caf0a7ee3eadd0561311d Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 24 Nov 2020 10:44:41 +0000 Subject: [PATCH 44/48] Upgrade to Spring Boot 2.4.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 16c314d13..ae20ee24a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.springframework.samples spring-petclinic - 2.3.0.BUILD-SNAPSHOT + 2.4.0.BUILD-SNAPSHOT org.springframework.boot spring-boot-starter-parent - 2.3.5.RELEASE + 2.4.0 petclinic From 949278cd46971a2170d749be0cfe2a1223161001 Mon Sep 17 00:00:00 2001 From: Arka Bandyopadhyay Date: Sun, 29 Nov 2020 14:21:33 +0530 Subject: [PATCH 45/48] remove .vscode folder from project repository --- .vscode/launch.json | 26 -------------------------- .vscode/settings.json | 3 --- .vscode/tasks.json | 19 ------------------- 3 files changed, 48 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 559c53805..000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "java", - "name": "Debug (Launch)-PetClinicApplication", - "request": "launch", - "cwd": "${workspaceFolder}", - "console": "internalConsole", - "stopOnEntry": false, - "mainClass": "org.springframework.samples.petclinic.PetClinicApplication", - "projectName": "spring-petclinic", - "args": "" - }, - { - "type": "java", - "name": "Debug (Attach)", - "request": "attach", - "hostName": "localhost", - "port": 0 - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c5f3f6b9c..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "java.configuration.updateBuildConfiguration": "interactive" -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index fabd5c416..000000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "verify", - "type": "shell", - "command": "mvn -B verify", - "group": "build" - }, - { - "label": "test", - "type": "shell", - "command": "mvn -B test", - "group": "test" - } - ] -} From 502870d6c031692b2111602a3eae5ae00e24efd9 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Sun, 29 Nov 2020 11:38:26 +0100 Subject: [PATCH 46/48] Remove IDE specific configuration files Closes gh-706 --- .gitignore | 6 +----- .vscode/launch.json | 26 -------------------------- .vscode/settings.json | 3 --- .vscode/tasks.json | 19 ------------------- 4 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json diff --git a/.gitignore b/.gitignore index 559982f3d..191769767 100644 --- a/.gitignore +++ b/.gitignore @@ -8,9 +8,5 @@ target/* *.iml /target .sts4-cache/ -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json +.vscode _site/ diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 559c53805..000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "java", - "name": "Debug (Launch)-PetClinicApplication", - "request": "launch", - "cwd": "${workspaceFolder}", - "console": "internalConsole", - "stopOnEntry": false, - "mainClass": "org.springframework.samples.petclinic.PetClinicApplication", - "projectName": "spring-petclinic", - "args": "" - }, - { - "type": "java", - "name": "Debug (Attach)", - "request": "attach", - "hostName": "localhost", - "port": 0 - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c5f3f6b9c..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "java.configuration.updateBuildConfiguration": "interactive" -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index fabd5c416..000000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "verify", - "type": "shell", - "command": "mvn -B verify", - "group": "build" - }, - { - "label": "test", - "type": "shell", - "command": "mvn -B test", - "group": "test" - } - ] -} From 0573cda3c2b07d37424b27a63f4514d63fbb3cfb Mon Sep 17 00:00:00 2001 From: Arka Bandyopadhyay Date: Sun, 29 Nov 2020 15:47:35 +0530 Subject: [PATCH 47/48] Downgrade to wro4j 1.8.0 This commit downgrades the wro4j plugin to 1.8.0 as the latest version requires Java 11. See gh-707 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ae20ee24a..2dbb637d3 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 3.3.6 1.11.4 2.2.4 - 1.9.0 + 1.8.0 0.8.5 0.0.4.RELEASE From 02babdd8cb0d494d043fdf35a24dd2127c5d5167 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 25 Dec 2020 13:02:48 +0100 Subject: [PATCH 48/48] Upgrade to Spring Boot 2.4.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2dbb637d3..4941843ad 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 2.4.0 + 2.4.1 petclinic