initial commit
All checks were successful
Build and Publish TechDocs / build-and-publish (push) Successful in 1m4s
All checks were successful
Build and Publish TechDocs / build-and-publish (push) Successful in 1m4s
Change-Id: I83c7674b31ee747d97c4828579f45209910ebbd6
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.samples.petclinic;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ImportRuntimeHints;
|
||||
|
||||
/**
|
||||
* PetClinic Spring Boot Application.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@ImportRuntimeHints(PetClinicRuntimeHints.class)
|
||||
public class PetClinicApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PetClinicApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.samples.petclinic;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||
import org.springframework.samples.petclinic.model.Person;
|
||||
import org.springframework.samples.petclinic.vet.Vet;
|
||||
|
||||
public class PetClinicRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
hints.resources().registerPattern("db/*"); // https://github.com/spring-projects/spring-boot/issues/32654
|
||||
hints.resources().registerPattern("messages/*");
|
||||
hints.resources().registerPattern("mysql-default-conf");
|
||||
hints.serialization().registerType(BaseEntity.class);
|
||||
hints.serialization().registerType(Person.class);
|
||||
hints.serialization().registerType(Vet.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object with an id property. Used as a base class for objects
|
||||
* needing this property.
|
||||
*
|
||||
* @author Ken Krebs
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public class BaseEntity implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isNew() {
|
||||
return this.id == null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.model;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object adds a name property to <code>BaseEntity</code>. Used as
|
||||
* a base class for objects needing these properties.
|
||||
*
|
||||
* @author Ken Krebs
|
||||
* @author Juergen Hoeller
|
||||
* @author Wick Dynex
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public class NamedEntity extends BaseEntity {
|
||||
|
||||
@Column
|
||||
@NotBlank
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = this.getName();
|
||||
return name != null ? name : "<null>";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.model;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object representing an person.
|
||||
*
|
||||
* @author Ken Krebs
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public class Person extends BaseEntity {
|
||||
|
||||
@Column
|
||||
@NotBlank
|
||||
private String firstName;
|
||||
|
||||
@Column
|
||||
@NotBlank
|
||||
private String lastName;
|
||||
|
||||
public String getFirstName() {
|
||||
return this.firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return this.lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The classes in this package represent utilities used by the domain.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.model;
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.samples.petclinic.model.Person;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OrderBy;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object representing an owner.
|
||||
*
|
||||
* @author Ken Krebs
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @author Michael Isvy
|
||||
* @author Oliver Drotbohm
|
||||
* @author Wick Dynex
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "owners")
|
||||
public class Owner extends Person {
|
||||
|
||||
@Column
|
||||
@NotBlank
|
||||
private String address;
|
||||
|
||||
@Column
|
||||
@NotBlank
|
||||
private String city;
|
||||
|
||||
@Column
|
||||
@NotBlank
|
||||
@Pattern(regexp = "\\d{10}", message = "{telephone.invalid}")
|
||||
private String telephone;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "owner_id")
|
||||
@OrderBy("name")
|
||||
private final List<Pet> pets = new ArrayList<>();
|
||||
|
||||
public String getAddress() {
|
||||
return this.address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return this.city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getTelephone() {
|
||||
return this.telephone;
|
||||
}
|
||||
|
||||
public void setTelephone(String telephone) {
|
||||
this.telephone = telephone;
|
||||
}
|
||||
|
||||
public List<Pet> getPets() {
|
||||
return this.pets;
|
||||
}
|
||||
|
||||
public void addPet(Pet pet) {
|
||||
if (pet.isNew()) {
|
||||
getPets().add(pet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Pet with the given name, or null if none found for this Owner.
|
||||
* @param name to test
|
||||
* @return the Pet with the given name, or null if no such Pet exists for this Owner
|
||||
*/
|
||||
public Pet getPet(String name) {
|
||||
return getPet(name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Pet with the given id, or null if none found for this Owner.
|
||||
* @param id to test
|
||||
* @return the Pet with the given id, or null if no such Pet exists for this Owner
|
||||
*/
|
||||
public Pet getPet(Integer id) {
|
||||
for (Pet pet : getPets()) {
|
||||
if (!pet.isNew()) {
|
||||
Integer compId = pet.getId();
|
||||
if (Objects.equals(compId, id)) {
|
||||
return pet;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Pet with the given name, or null if none found for this Owner.
|
||||
* @param name to test
|
||||
* @param ignoreNew whether to ignore new pets (pets that are not saved yet)
|
||||
* @return the Pet with the given name, or null if no such Pet exists for this Owner
|
||||
*/
|
||||
public Pet getPet(String name, boolean ignoreNew) {
|
||||
for (Pet pet : getPets()) {
|
||||
String compName = pet.getName();
|
||||
if (compName != null && compName.equalsIgnoreCase(name)) {
|
||||
if (!ignoreNew || !pet.isNew()) {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given {@link Visit} to the {@link Pet} with the given identifier.
|
||||
* @param petId the identifier of the {@link Pet}, must not be {@literal null}.
|
||||
* @param visit the visit to add, must not be {@literal null}.
|
||||
*/
|
||||
public void addVisit(Integer petId, Visit visit) {
|
||||
|
||||
Assert.notNull(petId, "Pet identifier must not be null!");
|
||||
Assert.notNull(visit, "Visit must not be null!");
|
||||
|
||||
Pet pet = getPet(petId);
|
||||
|
||||
Assert.notNull(pet, "Invalid Pet identifier!");
|
||||
|
||||
pet.addVisit(visit);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Ken Krebs
|
||||
* @author Arjen Poutsma
|
||||
* @author Michael Isvy
|
||||
* @author Wick Dynex
|
||||
*/
|
||||
@Controller
|
||||
class OwnerController {
|
||||
|
||||
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
|
||||
|
||||
private final OwnerRepository owners;
|
||||
|
||||
public OwnerController(OwnerRepository owners) {
|
||||
this.owners = owners;
|
||||
}
|
||||
|
||||
@InitBinder
|
||||
public void setAllowedFields(WebDataBinder dataBinder) {
|
||||
dataBinder.setDisallowedFields("id", "*.id");
|
||||
}
|
||||
|
||||
@ModelAttribute("owner")
|
||||
public Owner findOwner(@PathVariable(name = "ownerId", required = false) Integer ownerId) {
|
||||
return ownerId == null ? new Owner()
|
||||
: this.owners.findById(ownerId)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Owner not found with id: " + ownerId
|
||||
+ ". Please ensure the ID is correct " + "and the owner exists in the database."));
|
||||
}
|
||||
|
||||
@GetMapping("/owners/new")
|
||||
public String initCreationForm() {
|
||||
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
||||
}
|
||||
|
||||
@PostMapping("/owners/new")
|
||||
public String processCreationForm(@Valid Owner owner, BindingResult result, RedirectAttributes redirectAttributes) {
|
||||
if (result.hasErrors()) {
|
||||
redirectAttributes.addFlashAttribute("error", "There was an error in creating the owner.");
|
||||
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
||||
}
|
||||
|
||||
this.owners.save(owner);
|
||||
redirectAttributes.addFlashAttribute("message", "New Owner Created");
|
||||
return "redirect:/owners/" + owner.getId();
|
||||
}
|
||||
|
||||
@GetMapping("/owners/find")
|
||||
public String initFindForm() {
|
||||
return "owners/findOwners";
|
||||
}
|
||||
|
||||
@GetMapping("/owners")
|
||||
public String processFindForm(@RequestParam(defaultValue = "1") int page, Owner owner, BindingResult result,
|
||||
Model model) {
|
||||
// allow parameterless GET request for /owners to return all records
|
||||
String lastName = owner.getLastName();
|
||||
if (lastName == null) {
|
||||
lastName = ""; // empty string signifies broadest possible search
|
||||
}
|
||||
|
||||
// find owners by last name
|
||||
Page<Owner> ownersResults = findPaginatedForOwnersLastName(page, lastName);
|
||||
if (ownersResults.isEmpty()) {
|
||||
// no owners found
|
||||
result.rejectValue("lastName", "notFound", "not found");
|
||||
return "owners/findOwners";
|
||||
}
|
||||
|
||||
if (ownersResults.getTotalElements() == 1) {
|
||||
// 1 owner found
|
||||
owner = ownersResults.iterator().next();
|
||||
return "redirect:/owners/" + owner.getId();
|
||||
}
|
||||
|
||||
// multiple owners found
|
||||
return addPaginationModel(page, model, ownersResults);
|
||||
}
|
||||
|
||||
private String addPaginationModel(int page, Model model, Page<Owner> paginated) {
|
||||
List<Owner> listOwners = paginated.getContent();
|
||||
model.addAttribute("currentPage", page);
|
||||
model.addAttribute("totalPages", paginated.getTotalPages());
|
||||
model.addAttribute("totalItems", paginated.getTotalElements());
|
||||
model.addAttribute("listOwners", listOwners);
|
||||
return "owners/ownersList";
|
||||
}
|
||||
|
||||
private Page<Owner> findPaginatedForOwnersLastName(int page, String lastname) {
|
||||
int pageSize = 5;
|
||||
Pageable pageable = PageRequest.of(page - 1, pageSize);
|
||||
return owners.findByLastNameStartingWith(lastname, pageable);
|
||||
}
|
||||
|
||||
@GetMapping("/owners/{ownerId}/edit")
|
||||
public String initUpdateOwnerForm() {
|
||||
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
||||
}
|
||||
|
||||
@PostMapping("/owners/{ownerId}/edit")
|
||||
public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, @PathVariable("ownerId") int ownerId,
|
||||
RedirectAttributes redirectAttributes) {
|
||||
if (result.hasErrors()) {
|
||||
redirectAttributes.addFlashAttribute("error", "There was an error in updating the owner.");
|
||||
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
||||
}
|
||||
|
||||
if (!Objects.equals(owner.getId(), ownerId)) {
|
||||
result.rejectValue("id", "mismatch", "The owner ID in the form does not match the URL.");
|
||||
redirectAttributes.addFlashAttribute("error", "Owner ID mismatch. Please try again.");
|
||||
return "redirect:/owners/{ownerId}/edit";
|
||||
}
|
||||
|
||||
owner.setId(ownerId);
|
||||
this.owners.save(owner);
|
||||
redirectAttributes.addFlashAttribute("message", "Owner Values Updated");
|
||||
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");
|
||||
Optional<Owner> optionalOwner = this.owners.findById(ownerId);
|
||||
Owner owner = optionalOwner.orElseThrow(() -> new IllegalArgumentException(
|
||||
"Owner not found with id: " + ownerId + ". Please ensure the ID is correct "));
|
||||
mav.addObject(owner);
|
||||
return mav;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* Repository class for <code>Owner</code> 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
|
||||
* @author Sam Brannen
|
||||
* @author Michael Isvy
|
||||
* @author Wick Dynex
|
||||
*/
|
||||
public interface OwnerRepository extends JpaRepository<Owner, Integer> {
|
||||
|
||||
/**
|
||||
* Retrieve {@link Owner}s from the data store by last name, returning all owners
|
||||
* whose last name <i>starts</i> 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)
|
||||
*/
|
||||
Page<Owner> findByLastNameStartingWith(String lastName, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Retrieve an {@link Owner} from the data store by id.
|
||||
* <p>
|
||||
* This method returns an {@link Optional} containing the {@link Owner} if found. If
|
||||
* no {@link Owner} is found with the provided id, it will return an empty
|
||||
* {@link Optional}.
|
||||
* </p>
|
||||
* @param id the id to search for
|
||||
* @return an {@link Optional} containing the {@link Owner} if found, or an empty
|
||||
* {@link Optional} if not found.
|
||||
* @throws IllegalArgumentException if the id is null (assuming null is not a valid
|
||||
* input for id)
|
||||
*/
|
||||
Optional<Owner> findById(Integer id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OrderBy;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
/**
|
||||
* Simple business object representing a pet.
|
||||
*
|
||||
* @author Ken Krebs
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @author Wick Dynex
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "pets")
|
||||
public class Pet extends NamedEntity {
|
||||
|
||||
@Column
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate birthDate;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "type_id")
|
||||
private PetType type;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "pet_id")
|
||||
@OrderBy("date ASC")
|
||||
private final Set<Visit> visits = new LinkedHashSet<>();
|
||||
|
||||
public void setBirthDate(LocalDate birthDate) {
|
||||
this.birthDate = birthDate;
|
||||
}
|
||||
|
||||
public LocalDate getBirthDate() {
|
||||
return this.birthDate;
|
||||
}
|
||||
|
||||
public PetType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(PetType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Collection<Visit> getVisits() {
|
||||
return this.visits;
|
||||
}
|
||||
|
||||
public void addVisit(Visit visit) {
|
||||
getVisits().add(visit);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Ken Krebs
|
||||
* @author Arjen Poutsma
|
||||
* @author Wick Dynex
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/owners/{ownerId}")
|
||||
class PetController {
|
||||
|
||||
private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
|
||||
|
||||
private final OwnerRepository owners;
|
||||
|
||||
private final PetTypeRepository types;
|
||||
|
||||
public PetController(OwnerRepository owners, PetTypeRepository types) {
|
||||
this.owners = owners;
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
@ModelAttribute("types")
|
||||
public Collection<PetType> populatePetTypes() {
|
||||
return this.types.findPetTypes();
|
||||
}
|
||||
|
||||
@ModelAttribute("owner")
|
||||
public Owner findOwner(@PathVariable("ownerId") int ownerId) {
|
||||
Optional<Owner> optionalOwner = this.owners.findById(ownerId);
|
||||
Owner owner = optionalOwner.orElseThrow(() -> new IllegalArgumentException(
|
||||
"Owner not found with id: " + ownerId + ". Please ensure the ID is correct "));
|
||||
return owner;
|
||||
}
|
||||
|
||||
@ModelAttribute("pet")
|
||||
public Pet findPet(@PathVariable("ownerId") int ownerId,
|
||||
@PathVariable(name = "petId", required = false) Integer petId) {
|
||||
|
||||
if (petId == null) {
|
||||
return new Pet();
|
||||
}
|
||||
|
||||
Optional<Owner> optionalOwner = this.owners.findById(ownerId);
|
||||
Owner owner = optionalOwner.orElseThrow(() -> new IllegalArgumentException(
|
||||
"Owner not found with id: " + ownerId + ". Please ensure the ID is correct "));
|
||||
return owner.getPet(petId);
|
||||
}
|
||||
|
||||
@InitBinder("owner")
|
||||
public void initOwnerBinder(WebDataBinder dataBinder) {
|
||||
dataBinder.setDisallowedFields("id", "*.id");
|
||||
}
|
||||
|
||||
@InitBinder("pet")
|
||||
public void initPetBinder(WebDataBinder dataBinder) {
|
||||
dataBinder.setValidator(new PetValidator());
|
||||
dataBinder.setDisallowedFields("id", "*.id");
|
||||
}
|
||||
|
||||
@GetMapping("/pets/new")
|
||||
public String initCreationForm(Owner owner, ModelMap model) {
|
||||
Pet pet = new Pet();
|
||||
owner.addPet(pet);
|
||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||
}
|
||||
|
||||
@PostMapping("/pets/new")
|
||||
public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result,
|
||||
RedirectAttributes redirectAttributes) {
|
||||
|
||||
if (StringUtils.hasText(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) {
|
||||
result.rejectValue("name", "duplicate", "already exists");
|
||||
}
|
||||
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
if (pet.getBirthDate() != null && pet.getBirthDate().isAfter(currentDate)) {
|
||||
result.rejectValue("birthDate", "typeMismatch.birthDate");
|
||||
}
|
||||
|
||||
if (result.hasErrors()) {
|
||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||
}
|
||||
|
||||
owner.addPet(pet);
|
||||
this.owners.save(owner);
|
||||
redirectAttributes.addFlashAttribute("message", "New Pet has been Added");
|
||||
return "redirect:/owners/{ownerId}";
|
||||
}
|
||||
|
||||
@GetMapping("/pets/{petId}/edit")
|
||||
public String initUpdateForm() {
|
||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||
}
|
||||
|
||||
@PostMapping("/pets/{petId}/edit")
|
||||
public String processUpdateForm(Owner owner, @Valid Pet pet, BindingResult result,
|
||||
RedirectAttributes redirectAttributes) {
|
||||
|
||||
String petName = pet.getName();
|
||||
|
||||
// checking if the pet name already exists for the owner
|
||||
if (StringUtils.hasText(petName)) {
|
||||
Pet existingPet = owner.getPet(petName, false);
|
||||
if (existingPet != null && !Objects.equals(existingPet.getId(), pet.getId())) {
|
||||
result.rejectValue("name", "duplicate", "already exists");
|
||||
}
|
||||
}
|
||||
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
if (pet.getBirthDate() != null && pet.getBirthDate().isAfter(currentDate)) {
|
||||
result.rejectValue("birthDate", "typeMismatch.birthDate");
|
||||
}
|
||||
|
||||
if (result.hasErrors()) {
|
||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||
}
|
||||
|
||||
updatePetDetails(owner, pet);
|
||||
redirectAttributes.addFlashAttribute("message", "Pet details has been edited");
|
||||
return "redirect:/owners/{ownerId}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the pet details if it exists or adds a new pet to the owner.
|
||||
* @param owner The owner of the pet
|
||||
* @param pet The pet with updated details
|
||||
*/
|
||||
private void updatePetDetails(Owner owner, Pet pet) {
|
||||
Integer id = pet.getId();
|
||||
Assert.state(id != null, "'pet.getId()' must not be null");
|
||||
Pet existingPet = owner.getPet(id);
|
||||
if (existingPet != null) {
|
||||
// Update existing pet's properties
|
||||
existingPet.setName(pet.getName());
|
||||
existingPet.setBirthDate(pet.getBirthDate());
|
||||
existingPet.setType(pet.getType());
|
||||
}
|
||||
else {
|
||||
owner.addPet(pet);
|
||||
}
|
||||
this.owners.save(owner);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller Can be Cat, Dog, Hamster...
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "types")
|
||||
public class PetType extends NamedEntity {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @author Michael Isvy
|
||||
*/
|
||||
@Component
|
||||
public class PetTypeFormatter implements Formatter<PetType> {
|
||||
|
||||
private final PetTypeRepository types;
|
||||
|
||||
public PetTypeFormatter(PetTypeRepository types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String print(PetType petType, Locale locale) {
|
||||
String name = petType.getName();
|
||||
return name != null ? name : "<null>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public PetType parse(String text, Locale locale) throws ParseException {
|
||||
Collection<PetType> findPetTypes = this.types.findPetTypes();
|
||||
for (PetType type : findPetTypes) {
|
||||
if (Objects.equals(type.getName(), text)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
throw new ParseException("type not found: " + text, 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
/**
|
||||
* Repository class for <code>PetType</code> domain objects.
|
||||
*
|
||||
* @author Patrick Baumgartner
|
||||
*/
|
||||
|
||||
public interface PetTypeRepository extends JpaRepository<PetType, Integer> {
|
||||
|
||||
/**
|
||||
* 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")
|
||||
List<PetType> findPetTypes();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
/**
|
||||
* <code>Validator</code> for <code>Pet</code> forms.
|
||||
* <p>
|
||||
* We're not using Bean Validation annotations here because it is easier to define such
|
||||
* validation rule in Java.
|
||||
* </p>
|
||||
*
|
||||
* @author Ken Krebs
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class PetValidator implements Validator {
|
||||
|
||||
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.hasText(name)) {
|
||||
errors.rejectValue("name", 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object representing a visit.
|
||||
*
|
||||
* @author Ken Krebs
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "visits")
|
||||
public class Visit extends BaseEntity {
|
||||
|
||||
@Column(name = "visit_date")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate date;
|
||||
|
||||
@NotBlank
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* Creates a new instance of Visit for the current date
|
||||
*/
|
||||
public Visit() {
|
||||
this.date = LocalDate.now();
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return this.date;
|
||||
}
|
||||
|
||||
public void setDate(LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Ken Krebs
|
||||
* @author Arjen Poutsma
|
||||
* @author Michael Isvy
|
||||
* @author Dave Syer
|
||||
* @author Wick Dynex
|
||||
*/
|
||||
@Controller
|
||||
class VisitController {
|
||||
|
||||
private final OwnerRepository owners;
|
||||
|
||||
public VisitController(OwnerRepository owners) {
|
||||
this.owners = owners;
|
||||
}
|
||||
|
||||
@InitBinder
|
||||
public void setAllowedFields(WebDataBinder dataBinder) {
|
||||
dataBinder.setDisallowedFields("id", "*.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("ownerId") int ownerId, @PathVariable("petId") int petId,
|
||||
Map<String, Object> model) {
|
||||
Optional<Owner> optionalOwner = owners.findById(ownerId);
|
||||
Owner owner = optionalOwner.orElseThrow(() -> new IllegalArgumentException(
|
||||
"Owner not found with id: " + ownerId + ". Please ensure the ID is correct "));
|
||||
|
||||
Pet pet = owner.getPet(petId);
|
||||
if (pet == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Pet with id " + petId + " not found for owner with id " + ownerId + ".");
|
||||
}
|
||||
model.put("pet", pet);
|
||||
model.put("owner", owner);
|
||||
|
||||
Visit visit = new Visit();
|
||||
pet.addVisit(visit);
|
||||
return visit;
|
||||
}
|
||||
|
||||
// Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is
|
||||
// called
|
||||
@GetMapping("/owners/{ownerId}/pets/{petId}/visits/new")
|
||||
public String initNewVisitForm() {
|
||||
return "pets/createOrUpdateVisitForm";
|
||||
}
|
||||
|
||||
// Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is
|
||||
// called
|
||||
@PostMapping("/owners/{ownerId}/pets/{petId}/visits/new")
|
||||
public String processNewVisitForm(@ModelAttribute Owner owner, @PathVariable int petId, @Valid Visit visit,
|
||||
BindingResult result, RedirectAttributes redirectAttributes) {
|
||||
if (result.hasErrors()) {
|
||||
return "pets/createOrUpdateVisitForm";
|
||||
}
|
||||
|
||||
owner.addVisit(petId, visit);
|
||||
this.owners.save(owner);
|
||||
redirectAttributes.addFlashAttribute("message", "Your visit has been booked");
|
||||
return "redirect:/owners/{ownerId}";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.owner;
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic;
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.samples.petclinic.system;
|
||||
|
||||
import org.springframework.boot.cache.autoconfigure.JCacheManagerCustomizer;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.cache.configuration.MutableConfiguration;
|
||||
|
||||
/**
|
||||
* Cache configuration intended for caches providing the JCache API. This configuration
|
||||
* creates the used cache for the application and enables statistics that become
|
||||
* accessible via JMX.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableCaching
|
||||
class CacheConfiguration {
|
||||
|
||||
@Bean
|
||||
public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() {
|
||||
return cm -> cm.createCache("vets", cacheConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple configuration that enable statistics via the JCache programmatic
|
||||
* configuration API.
|
||||
* <p>
|
||||
* 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<Object, Object> cacheConfiguration() {
|
||||
return new MutableConfiguration<>().setStatisticsEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.system;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
/**
|
||||
* Controller used to showcase what happens when an exception is thrown
|
||||
*
|
||||
* @author Michael Isvy
|
||||
* <p/>
|
||||
* Also see how a view that resolves to "error" has been added ("error.html").
|
||||
*/
|
||||
@Controller
|
||||
class CrashController {
|
||||
|
||||
@GetMapping("/oups")
|
||||
public String triggerException() {
|
||||
throw new RuntimeException(
|
||||
"Expected: controller used to showcase what " + "happens when an exception is thrown");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.springframework.samples.petclinic.system;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.LocaleResolver;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Configures internationalization (i18n) support for the application.
|
||||
*
|
||||
* <p>
|
||||
* Handles loading language-specific messages, tracking the user's language, and allowing
|
||||
* language changes via the URL parameter (e.g., <code>?lang=de</code>).
|
||||
* </p>
|
||||
*
|
||||
* @author Anuj Ashok Potdar
|
||||
*/
|
||||
@Configuration
|
||||
@SuppressWarnings("unused")
|
||||
public class WebConfiguration implements WebMvcConfigurer {
|
||||
|
||||
/**
|
||||
* Uses session storage to remember the user’s language setting across requests.
|
||||
* Defaults to English if nothing is specified.
|
||||
* @return session-based {@link LocaleResolver}
|
||||
*/
|
||||
@Bean
|
||||
public LocaleResolver localeResolver() {
|
||||
SessionLocaleResolver resolver = new SessionLocaleResolver();
|
||||
resolver.setDefaultLocale(Locale.ENGLISH);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the app to switch languages using a URL parameter like
|
||||
* <code>?lang=es</code>.
|
||||
* @return a {@link LocaleChangeInterceptor} that handles the change
|
||||
*/
|
||||
@Bean
|
||||
public LocaleChangeInterceptor localeChangeInterceptor() {
|
||||
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
|
||||
interceptor.setParamName("lang");
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the locale change interceptor so it can run on each request.
|
||||
* @param registry where interceptors are added
|
||||
*/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(localeChangeInterceptor());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.system;
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
/**
|
||||
* Models a {@link Vet Vet's} specialty (for example, dentistry).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "specialties")
|
||||
public class Specialty extends NamedEntity {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||
import org.springframework.samples.petclinic.model.Person;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object representing a veterinarian.
|
||||
*
|
||||
* @author Ken Krebs
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@Entity
|
||||
@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<Specialty> specialties;
|
||||
|
||||
protected Set<Specialty> getSpecialtiesInternal() {
|
||||
if (this.specialties == null) {
|
||||
this.specialties = new HashSet<>();
|
||||
}
|
||||
return this.specialties;
|
||||
}
|
||||
|
||||
@XmlElement
|
||||
public List<Specialty> getSpecialties() {
|
||||
return getSpecialtiesInternal().stream()
|
||||
.sorted(Comparator.comparing(NamedEntity::getName))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public int getNrOfSpecialties() {
|
||||
return getSpecialtiesInternal().size();
|
||||
}
|
||||
|
||||
public void addSpecialty(Specialty specialty) {
|
||||
getSpecialtiesInternal().add(specialty);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @author Ken Krebs
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@Controller
|
||||
class VetController {
|
||||
|
||||
private final VetRepository vetRepository;
|
||||
|
||||
public VetController(VetRepository vetRepository) {
|
||||
this.vetRepository = vetRepository;
|
||||
}
|
||||
|
||||
@GetMapping("/vets.html")
|
||||
public String showVetList(@RequestParam(defaultValue = "1") int page, Model 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();
|
||||
Page<Vet> paginated = findPaginated(page);
|
||||
vets.getVetList().addAll(paginated.toList());
|
||||
return addPaginationModel(page, paginated, model);
|
||||
}
|
||||
|
||||
private String addPaginationModel(int page, Page<Vet> paginated, Model model) {
|
||||
List<Vet> listVets = paginated.getContent();
|
||||
model.addAttribute("currentPage", page);
|
||||
model.addAttribute("totalPages", paginated.getTotalPages());
|
||||
model.addAttribute("totalItems", paginated.getTotalElements());
|
||||
model.addAttribute("listVets", listVets);
|
||||
return "vets/vetList";
|
||||
}
|
||||
|
||||
private Page<Vet> findPaginated(int page) {
|
||||
int pageSize = 5;
|
||||
Pageable pageable = PageRequest.of(page - 1, pageSize);
|
||||
return vetRepository.findAll(pageable);
|
||||
}
|
||||
|
||||
@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.vetRepository.findAll());
|
||||
return vets;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Repository class for <code>Vet</code> 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
|
||||
* @author Sam Brannen
|
||||
* @author Michael Isvy
|
||||
*/
|
||||
public interface VetRepository extends Repository<Vet, Integer> {
|
||||
|
||||
/**
|
||||
* Retrieve all <code>Vet</code>s from the data store.
|
||||
* @return a <code>Collection</code> of <code>Vet</code>s
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
@Cacheable("vets")
|
||||
Collection<Vet> findAll() throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Retrieve all <code>Vet</code>s from data store in Pages
|
||||
* @param pageable
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
@Cacheable("vets")
|
||||
Page<Vet> findAll(Pageable pageable) throws DataAccessException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.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}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@XmlRootElement
|
||||
public class Vets {
|
||||
|
||||
private List<Vet> vets;
|
||||
|
||||
@XmlElement
|
||||
public List<Vet> getVetList() {
|
||||
if (vets == null) {
|
||||
vets = new ArrayList<>();
|
||||
}
|
||||
return vets;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.vet;
|
||||
Reference in New Issue
Block a user