added functionality to get and update a pet

This commit is contained in:
Shreyas Prayag 2025-05-20 18:53:57 +05:30
parent 3a931080d4
commit 76e57a6a35
6 changed files with 297 additions and 2 deletions

13
pom.xml
View file

@ -152,6 +152,19 @@
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
</dependencies>
<build>

View file

@ -0,0 +1,101 @@
package org.springframework.samples.petclinic.owner;
import jakarta.annotation.Nonnull;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
/**
* Simple business object representing a pet.
*
* @author Shreyas Prayag
*/
public class NewPet {
/**
* The unique identifier for the pet. This field is mapped to the "id" column in the
* "new_pet" table. It is automatically generated by the database when a new pet is
* created.
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
/**
* The name of the pet. This field is mapped to the "name" column in the "new_pet"
* table. It cannot be null and should not be empty.
*/
@NotNull
private String name;
/**
* The date of birth of the pet. This field is mapped to the "birth_date" column in
* the "new_pet" table. It cannot be null and should not be empty.
*/
private Date birthDate;
/**
* The owner of the pet.
* <p>
* This field represents a many-to-one relationship between pets and their owners
* each pet is associated with one owner, but an owner can have multiple pets.
* </p>
* <p>
* The relationship is mapped via the {@code owner_id} foreign key in the
* {@code new_pet} table.
* </p>
*
* @see Owner
*/
@ManyToOne
@JoinColumn(name = "owner_id")
private Owner owner;
/**
* The temperament of the pet.
* <p>
* This field represents a many-to-one relationship between pets and their
* temperaments each pet has one temperament, there can be more than one pets with
* one temperament.
* </p>
* <p>
* The relationship is mapped via the {@code temperament_id} foreign key in the
* {@code new_pet} table.
* </p>
*
* @see PetTemperament
*/
@ManyToOne()
@JoinColumn(name = "temperament_id")
private PetTemperament temperament;
/**
* The type of the pet.
* <p>
* This field represents a many-to-one relationship between pets and their owners
* each pet is associated with one type, but there can be multiple pets of a type.
* </p>
* <p>
* The relationship is mapped via the {@code type_id} foreign key in the
* {@code new_pet} table.
* </p>
*
* @see Owner
*/
@ManyToOne
@JoinColumn(name = "type_id")
private PetType type;
}

View file

@ -0,0 +1,92 @@
package org.springframework.samples.petclinic.owner;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
/**
* new Controller to handle requests relating pet
*
* The existing controller is not a REST API controller. So this controller is created to
* cater Rest endpoints relating Pet.
*
* @author Shreyas Prayag
* @since 1.0
*/
@RestController
@RequestMapping("owners/{ownerId}")
public class NewPetController {
private final NewPetRepository petRepository;
NewPetController(NewPetRepository petRepository) {
this.petRepository = petRepository;
}
/**
* Retrieves a pet by its ID.
* <p>
* This endpoint returns a pet based on the provided pet ID. If the pet with the given
* ID exists, it returns the pet details in the response body with a 200 OK status. If
* the pet is not found, a 404 Not Found status is returned.
* </p>
* @param petId The ID of the pet to retrieve. It is expected to be a positive
* integer.
* @return A {@link ResponseEntity} containing the {@link Pet} object if found, or a
* 404 response if not found.
*
* this endpoint is hateoas compliant
*/
@GetMapping("/pet/{petId}")
public ResponseEntity<EntityModel<NewPet>> getPetById(@PathVariable int ownerId, @PathVariable int petId) {
NewPet pet = petRepository.findById(petId);
if (pet == null) {
return ResponseEntity.notFound().build();
}
EntityModel<NewPet> petResource = EntityModel.of(pet);
// Add self link
petResource.add(linkTo(methodOn(NewPetController.class).getPetById(ownerId, petId)).withSelfRel());
// Add link to create new pet
petResource.add(linkTo(methodOn(NewPetController.class).createNewPet(ownerId, null)).withRel("create-new-pet"));
return ResponseEntity.ok(petResource);
}
/**
* Creates a new pet.
* <p>
* This endpoint accepts a {@link Pet} object in the request body and saves it to the
* database. It returns the created {@link Pet} object along with a 201 Created HTTP
* status code. If the pet data is invalid, a 400 Bad Request status is returned.
* </p>
* @param newPet The pet object to create. This is expected to contain the pet details
* in the request body.
* @return A {@link ResponseEntity} containing the created {@link Pet} object and a
* 201 Created status.
*
* this endpoint is hateoas compliant
*/
@PostMapping("/pet")
public ResponseEntity<EntityModel<NewPet>> createNewPet(@PathVariable int ownerId, @RequestBody NewPet newPet) {
NewPet savedPet = petRepository.save(newPet);
EntityModel<NewPet> petResource = EntityModel.of(savedPet);
// Add self link
petResource.add(linkTo(methodOn(NewPetController.class).getPetById(ownerId, savedPet.getId())).withSelfRel());
return ResponseEntity.status(HttpStatus.CREATED).body(petResource);
}
}

View file

@ -0,0 +1,33 @@
package org.springframework.samples.petclinic.owner;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Repository interface for managing {@link NewPet} entities.
* <p>
* Extends {@link JpaRepository} to provide CRUD operations, pagination, and JPA-specific
* functionality.
* </p>
*
* @author You
* @since 1.0
*/
public interface NewPetRepository extends JpaRepository<NewPet, Integer> {
/**
* Finds the pet with the given id.
* @param id The id of the pet to search for.
* @return a pet with the specified id.
*
*/
NewPet findById(int id);
/**
* Saves the given pet
* @param newPet The pet object to be saved.
* @return pet object being saved.
*
*/
NewPet save(NewPet newPet);
}

View file

@ -0,0 +1,46 @@
package org.springframework.samples.petclinic.owner;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
/**
* Simple business object representing pet temperament.
*
* @author Shreyas Prayag
*/
public class PetTemperament {
/**
* The unique identifier for the temperament. This field is mapped to the "id" column
* in the "pet_temperament" table. It is automatically generated by the database when
* a new temperament is created.
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* The Temperament of pet. This field is mapped to the "temperament" column in the
* "pet_temperament" table. It cannot be null and should not be empty.
*/
@NotNull
private String temperament;
public PetTemperament(String temperament) {
this.temperament = temperament;
}
}

View file

@ -1,13 +1,23 @@
# database init, supports mysql too
database=h2
database=mysql
spring.sql.init.schema-locations=classpath*:db/${database}/schema.sql
spring.sql.init.data-locations=classpath*:db/${database}/data.sql
# Data Source properties
spring.datasource.url=jdbc:mysql://localhost:3306/petclinic
spring.datasource.username=petclinic
spring.datasource.password=petclinic
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Logging level for Hibernate SQL
logging.level.org.hibernate.SQL=DEBUG
# Web
spring.thymeleaf.mode=HTML
# JPA
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.open-in-view=false
# Internationalization