diff --git a/pom.xml b/pom.xml index 48e725a4f9bc..e45a5ee16447 100644 --- a/pom.xml +++ b/pom.xml @@ -210,6 +210,7 @@ crtp log-aggregation health-check + single-table-inheritance diff --git a/single-table-inheritance/README.md b/single-table-inheritance/README.md new file mode 100644 index 000000000000..541ad1423e24 --- /dev/null +++ b/single-table-inheritance/README.md @@ -0,0 +1,157 @@ +--- +title: Single Table Inheritance Pattern +category: Structural +language: en +tag: + - Data access +--- + +## Single Table Inheritance(STI) + +## Intent + +Represents an inheritance hierarchy of classes as a single table that has columns for all the fields of the various classes. + +## Explanation + +Real-world example + +> There can be many different types of vehicles in this world but all of them +> come under the single umbrella of Vehicle + +In plain words + +> It maps each instance of class in an inheritance tree into a single table. + +Wikipedia says + +> Single table inheritance is a way to emulate object-oriented inheritance in a relational database. +> When mapping from a database table to an object in an object-oriented language, +> a field in the database identifies what class in the hierarchy the object belongs to. +> All fields of all the classes are stored in the same table, hence the name "Single Table Inheritance". + +**Programmatic Example** + +Baeldung - Hibernate Inheritance + +> We can define the strategy we want to use by adding the @Inheritance annotation to the superclass: + +```java +@Entity +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +public class MyProduct { + @Id + private long productId; + private String name; + + // constructor, getters, setters +} +``` + +The identifier of the entities is also defined in the superclass. + +Then we can add the subclass entities: + +```java +@Entity +public class Book extends MyProduct { + private String author; +} +``` + +```java +@Entity +public class Pen extends MyProduct { + private String color; +} +``` +Discriminator Values + +- Since the records for all entities will be in the same table, Hibernate needs a way to differentiate between them. + +- By default, this is done through a discriminator column called DTYPE that has the name of the entity as a value. + +- To customize the discriminator column, we can use the @DiscriminatorColumn annotation: + +```java +@Entity(name="products") +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn(name="product_type", + discriminatorType = DiscriminatorType.INTEGER) +public class MyProduct { + // ... +} +``` +- Here we’ve chosen to differentiate MyProduct subclass entities by an integer column called product_type. + +- Next, we need to tell Hibernate what value each subclass record will have for the product_type column: + +```java +@Entity +@DiscriminatorValue("1") +public class Book extends MyProduct { + // ... +} +``` +```java +@Entity +@DiscriminatorValue("2") +public class Pen extends MyProduct { + // ... +} +``` + +- Hibernate adds two other predefined values that the annotation can take — null and not null: + + - @DiscriminatorValue(“null”) means that any row without a discriminator value will be mapped to the entity class with this annotation; this can be applied to the root class of the hierarchy. + - @DiscriminatorValue(“not null”) – Any row with a discriminator value not matching any of the ones associated with entity definitions will be mapped to the class with this annotation. + + +## Class diagram + +![alt text](./etc/single-table-inheritance.urm.png "Singleton pattern class diagram") + +## Applicability + +Use the Singleton pattern when + +* Use STI When The Subclasses Have The Same Fields/Columns But Different Behavior + - A good indication that STI is right is when the different subclasses have the same fields/columns but different methods. In the accounts example above, we expect all the columns in the database to be used by each subclass. Otherwise, there will be a lot of null columns in the database. +

+* Use STI When We Expect To Perform Queries Across All Subclasses + - Another good indication STI is right is if we expect to perform queries across all classes. For example, if we want to find the top 10 accounts with the highest balances across all types, STI allows lets us use just one query, whereas MTI will require in memory manipulation. + + +### Tutorials + +- Java Brains - Single Table Inheritance + +## Consequences + +* Fields are sometimes relevant and sometimes not, which can be confusing + to people using the tables directly. +* Columns used only by some subclasses lead to wasted space in the database. + How much this is actually a problem depends on the specific data + characteristics and how well the database compresses empty columns. + Oracle, for example, is very efficient in trimming wasted space, particularly + if you keep your optional columns to the right side of the database + table. Each database has its own tricks for this. +* The single table may end up being too large, with many indexes and frequent + locking, which may hurt performance. You can avoid this by having + separate index tables that either list keys of rows that have a certain property + or that copy a subset of fields relevant to an index. +* You only have a single namespace for fields, so you have to be sure that + you don’t use the same name for different fields. Compound names with + the name of the class as a prefix or suffix help here. + +## Related patterns + +* MappedSuperclass +* Single Table +* Joined Table +* Table per Class + +## Credits + +* [Single Table Inheritance - martinFowler.com](https://www.martinfowler.com/eaaCatalog/singleTableInheritance.html) +* [Patterns of Enterprise Application Architecture](https://books.google.co.in/books?id=vqTfNFDzzdIC&pg=PA278&redir_esc=y#v=onepage&q&f=false) diff --git a/single-table-inheritance/etc/single-table-inheritance.urm.png b/single-table-inheritance/etc/single-table-inheritance.urm.png new file mode 100644 index 000000000000..f3abe8df6fec Binary files /dev/null and b/single-table-inheritance/etc/single-table-inheritance.urm.png differ diff --git a/single-table-inheritance/etc/single-table-inheritance.urm.puml b/single-table-inheritance/etc/single-table-inheritance.urm.puml new file mode 100644 index 000000000000..644d27e070ea --- /dev/null +++ b/single-table-inheritance/etc/single-table-inheritance.urm.puml @@ -0,0 +1,163 @@ +@startuml +package com.iluwatar.repository { + interface VehicleRepository { + } +} +package com.iluwatar.service { + class VehicleService { + - vehicleRepository : VehicleRepository + + VehicleService(vehicleRepository : VehicleRepository) + + deleteVehicle(vehicle : Vehicle) + + getAllVehicles() : List + + getVehicle(vehicleId : int) : Vehicle + + saveVehicle(vehicle : Vehicle) : Vehicle + + updateVehicle(vehicle : Vehicle) : Vehicle + } +} +package com.iluwatar.entity { + class Car { + - engineCapacity : int + + Car() + + Car(manufacturer : String, model : String, noOfPassengers : int, engineCapacity : int) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getEngineCapacity() : int + + hashCode() : int + + setEngineCapacity(engineCapacity : int) + + toString() : String + } + class Freighter { + - flightLength : double + + Freighter() + + Freighter(manufacturer : String, model : String, countOfSeats : int, loadCapacity : int, flightLength : double) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getFlightLength() : double + + hashCode() : int + + setFlightLength(flightLength : double) + + toString() : String + } + abstract class PassengerVehicle { + - noOfPassengers : int + + PassengerVehicle() + + PassengerVehicle(manufacturer : String, model : String, noOfPassengers : int) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getNoOfPassengers() : int + + hashCode() : int + + setNoOfPassengers(noOfPassengers : int) + + toString() : String + } + class Train { + - noOfCarriages : int + + Train() + + Train(manufacturer : String, model : String, noOfPassengers : int, noOfCarriages : int) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getNoOfCarriages() : int + + hashCode() : int + + setNoOfCarriages(noOfCarriages : int) + + toString() : String + } + abstract class TransportVehicle { + - loadCapacity : int + + TransportVehicle() + + TransportVehicle(manufacturer : String, model : String, loadCapacity : int) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getLoadCapacity() : int + + hashCode() : int + + setLoadCapacity(loadCapacity : int) + + toString() : String + } + class Truck { + + towingCapacity : int + + Truck() + + Truck(manufacturer : String, model : String, loadCapacity : int, towingCapacity : int) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getTowingCapacity() : int + + hashCode() : int + + setTowingCapacity(towingCapacity : int) + + toString() : String + } + abstract class Vehicle { + - manufacturer : String + - model : String + - vehicleId : int + + Vehicle() + + Vehicle(manufacturer : String, model : String) + + Vehicle(vehicleId : int, manufacturer : String, model : String) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getManufacturer() : String + + getModel() : String + + getVehicleId() : int + + hashCode() : int + + setManufacturer(manufacturer : String) + + setModel(model : String) + + setVehicleId(vehicleId : int) + + toString() : String + } +} +package com.iluwatar.abstractEntity { + abstract class PassengerVehicle { + - noOfPassengers : int + + PassengerVehicle() + + PassengerVehicle(manufacturer : String, model : String, noOfPassengers : int) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getNoOfPassengers() : int + + hashCode() : int + + setNoOfPassengers(noOfPassengers : int) + + toString() : String + } + abstract class TransportVehicle { + - loadCapacity : int + + TransportVehicle() + + TransportVehicle(manufacturer : String, model : String, loadCapacity : int) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getLoadCapacity() : int + + hashCode() : int + + setLoadCapacity(loadCapacity : int) + + toString() : String + } + abstract class Vehicle { + - manufacturer : String + - model : String + - vehicleId : int + + Vehicle() + + Vehicle(manufacturer : String, model : String) + + Vehicle(vehicleId : int, manufacturer : String, model : String) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getManufacturer() : String + + getModel() : String + + getVehicleId() : int + + hashCode() : int + + setManufacturer(manufacturer : String) + + setModel(model : String) + + setVehicleId(vehicleId : int) + + toString() : String + } +} +package com.iluwatar { + class SingleTableInheritance { + - vehicleService : VehicleService + + SingleTableInheritance(vehicleService : VehicleService) + + main(args : String[]) {static} + + run(args : String[]) + } +} +SingleTableInheritance --> "-vehicleService" VehicleService +VehicleService --> "-vehicleRepository" VehicleRepository +PassengerVehicle --|> Vehicle +TransportVehicle --|> Vehicle +Car --|> PassengerVehicle +Freighter --|> TransportVehicle +PassengerVehicle --|> Vehicle +Train --|> PassengerVehicle +TransportVehicle --|> Vehicle +Truck --|> TransportVehicle +@enduml \ No newline at end of file diff --git a/single-table-inheritance/pom.xml b/single-table-inheritance/pom.xml new file mode 100644 index 000000000000..159a683bea21 --- /dev/null +++ b/single-table-inheritance/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.26.0-SNAPSHOT + + + single-table-inheritance + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + runtime + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + \ No newline at end of file diff --git a/single-table-inheritance/src/main/java/com/iluwatar/SingleTableInheritance.java b/single-table-inheritance/src/main/java/com/iluwatar/SingleTableInheritance.java new file mode 100644 index 000000000000..01fbb37b828f --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/SingleTableInheritance.java @@ -0,0 +1,93 @@ +package com.iluwatar; + +import com.iluwatar.entity.Car; +import com.iluwatar.entity.Truck; +import com.iluwatar.entity.Vehicle; +import com.iluwatar.service.VehicleService; +import java.util.List; +import lombok.AllArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Single Table Inheritance pattern : + *
+ * It maps each instance of class in an inheritance tree into a single table. + *
+ *

+ * In case of current project, in order to specify the Single Table Inheritance to Hibernate + * we annotate the main Vehicle root class with @Inheritance(strategy = InheritanceType.SINGLE_TABLE) + * due to which a single root Vehicle class table will be created + * in the database and it will have columns for all the fields of + * it's subclasses(Car, Freighter, Train, Truck).
+ * Additional to that, a new separate "vehicle_id" column would be added + * to the Vehicle table to save the type of the subclass object that + * is being stored in the database. This value is specified by the @DiscriminatorValue annotation + * value for each subclass in case of Hibernate.
+ *


+ * Below is the main Spring Boot Application class from where the Program Runs. + *

+ * It implements the CommandLineRunner to run the statements at the + * start of the application program. + *

+ */ +@SpringBootApplication +@AllArgsConstructor +public class SingleTableInheritance implements CommandLineRunner { + + //Autowiring the VehicleService class to execute the business logic methods + private final VehicleService vehicleService; + + /** + * The entry point of the Spring Boot Application. + * + * @param args program runtime arguments + */ + public static void main(String[] args) { + SpringApplication.run(SingleTableInheritance.class, args); + } + + /** + * The starting point of the CommandLineRunner + * where the main program is run. + * + * @param args program runtime arguments + */ + @Override + public void run(String... args) throws Exception { + + Logger log = LoggerFactory.getLogger(SingleTableInheritance.class); + + log.info("Saving Vehicles :- "); + + // Saving Car to DB as a Vehicle + Vehicle vehicle1 = new Car("Tesla", "Model S", 4, 825); + Vehicle car1 = vehicleService.saveVehicle(vehicle1); + log.info("Vehicle 1 saved : {}", car1); + + // Saving Truck to DB as a Vehicle + Vehicle vehicle2 = new Truck("Ford", "F-150", 3325, 14000); + Vehicle truck1 = vehicleService.saveVehicle(vehicle2); + log.info("Vehicle 2 saved : {}\n", truck1); + + + log.info("Fetching Vehicles :- "); + + // Fetching the Car from DB + Car savedCar1 = (Car) vehicleService.getVehicle(vehicle1.getVehicleId()); + log.info("Fetching Car1 from DB : {}", savedCar1); + + // Fetching the Truck from DB + Truck savedTruck1 = (Truck) vehicleService.getVehicle(vehicle2.getVehicleId()); + log.info("Fetching Truck1 from DB : {}\n", savedTruck1); + + log.info("Fetching All Vehicles :- "); + + // Fetching the Vehicles present in the DB + List allVehiclesFromDb = vehicleService.getAllVehicles(); + allVehiclesFromDb.forEach(s -> log.info(s.toString())); + } +} \ No newline at end of file diff --git a/single-table-inheritance/src/main/java/com/iluwatar/entity/Car.java b/single-table-inheritance/src/main/java/com/iluwatar/entity/Car.java new file mode 100644 index 000000000000..c8d3185fdce9 --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/entity/Car.java @@ -0,0 +1,39 @@ +package com.iluwatar.entity; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * A class that extends the PassengerVehicle class + * and provides the concrete inheritance implementation of the Car. + * + * @see PassengerVehicle PassengerVehicle + * @see Vehicle Vehicle + */ + +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Entity +@DiscriminatorValue(value = "CAR") +public class Car extends PassengerVehicle { + + private int engineCapacity; + + public Car(String manufacturer, String model, int noOfPassengers, int engineCapacity) { + super(manufacturer, model, noOfPassengers); + this.engineCapacity = engineCapacity; + } + + // Overridden the toString method to specify the Vehicle object + @Override + public String toString() { + return "Car{" + + super.toString() + + '}'; + } + +} diff --git a/single-table-inheritance/src/main/java/com/iluwatar/entity/Freighter.java b/single-table-inheritance/src/main/java/com/iluwatar/entity/Freighter.java new file mode 100644 index 000000000000..ce35f3df37df --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/entity/Freighter.java @@ -0,0 +1,41 @@ +package com.iluwatar.entity; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * A class that extends the TransportVehicle class + * and provides the concrete inheritance implementation of the Car. + * + * @see TransportVehicle TransportVehicle + * @see Vehicle Vehicle + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Entity +@DiscriminatorValue(value = "FREIGHTER") +public class Freighter extends TransportVehicle { + + private double flightLength; + + public Freighter(String manufacturer, String model, int loadCapacity, double flightLength) { + super(manufacturer, model, loadCapacity); + this.flightLength = flightLength; + } + + // Overridden the toString method to specify the Vehicle object + @Override + public String toString() { + return "Freighter{ " + + super.toString() + + " ," + + "flightLength=" + + flightLength + + '}'; + } + +} diff --git a/single-table-inheritance/src/main/java/com/iluwatar/entity/PassengerVehicle.java b/single-table-inheritance/src/main/java/com/iluwatar/entity/PassengerVehicle.java new file mode 100644 index 000000000000..c27818a9a1d9 --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/entity/PassengerVehicle.java @@ -0,0 +1,30 @@ +package com.iluwatar.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * An abstract class that extends the Vehicle class + * and provides properties for the Passenger type of Vehicles. + * + * @see Vehicle + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public abstract class PassengerVehicle extends Vehicle { + + private int noOfPassengers; + + protected PassengerVehicle(String manufacturer, String model, int noOfPassengers) { + super(manufacturer, model); + this.noOfPassengers = noOfPassengers; + } + + @Override + public String toString() { + return super.toString(); + } + +} diff --git a/single-table-inheritance/src/main/java/com/iluwatar/entity/Train.java b/single-table-inheritance/src/main/java/com/iluwatar/entity/Train.java new file mode 100644 index 000000000000..10a74f36ac5a --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/entity/Train.java @@ -0,0 +1,38 @@ +package com.iluwatar.entity; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * A class that extends the PassengerVehicle class + * and provides the concrete inheritance implementation of the Car. + * + * @see PassengerVehicle PassengerVehicle + * @see Vehicle Vehicle + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Entity +@DiscriminatorValue(value = "TRAIN") +public class Train extends PassengerVehicle { + + private int noOfCarriages; + + public Train(String manufacturer, String model, int noOfPassengers, int noOfCarriages) { + super(manufacturer, model, noOfPassengers); + this.noOfCarriages = noOfCarriages; + } + + // Overridden the toString method to specify the Vehicle object + @Override + public String toString() { + return "Train{" + + super.toString() + + '}'; + } + +} diff --git a/single-table-inheritance/src/main/java/com/iluwatar/entity/TransportVehicle.java b/single-table-inheritance/src/main/java/com/iluwatar/entity/TransportVehicle.java new file mode 100644 index 000000000000..9f9c60516e88 --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/entity/TransportVehicle.java @@ -0,0 +1,25 @@ +package com.iluwatar.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * An abstract class that extends the Vehicle class + * and provides properties for the Transport type of Vehicles. + * + * @see Vehicle + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public abstract class TransportVehicle extends Vehicle { + + private int loadCapacity; + + protected TransportVehicle(String manufacturer, String model, int loadCapacity) { + super(manufacturer, model); + this.loadCapacity = loadCapacity; + } + +} diff --git a/single-table-inheritance/src/main/java/com/iluwatar/entity/Truck.java b/single-table-inheritance/src/main/java/com/iluwatar/entity/Truck.java new file mode 100644 index 000000000000..e389666e4dcc --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/entity/Truck.java @@ -0,0 +1,38 @@ +package com.iluwatar.entity; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * A class that extends the PassengerVehicle class + * and provides the concrete inheritance implementation of the Car. + * + * @see TransportVehicle TransportVehicle + * @see Vehicle Vehicle + */ +@Data +@NoArgsConstructor +@Entity +@DiscriminatorValue(value = "TRUCK") +public class Truck extends TransportVehicle { + + private int towingCapacity; + + public Truck(String manufacturer, String model, int loadCapacity, int towingCapacity) { + super(manufacturer, model, loadCapacity); + this.towingCapacity = towingCapacity; + } + + // Overridden the toString method to specify the Vehicle object + @Override + public String toString() { + return "Truck{ " + + super.toString() + + ", " + + "towingCapacity=" + + towingCapacity + + '}'; + } +} diff --git a/single-table-inheritance/src/main/java/com/iluwatar/entity/Vehicle.java b/single-table-inheritance/src/main/java/com/iluwatar/entity/Vehicle.java new file mode 100644 index 000000000000..901a37705455 --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/entity/Vehicle.java @@ -0,0 +1,54 @@ +package com.iluwatar.entity; + +import javax.persistence.DiscriminatorColumn; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + * An abstract class that is the root of the Vehicle Inheritance hierarchy + * and basic provides properties for all the vehicles. + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode +@Entity +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn(name = "VEHICLE_TYPE") +public abstract class Vehicle { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int vehicleId; + + private String manufacturer; + + private String model; + + protected Vehicle(String manufacturer, String model) { + this.manufacturer = manufacturer; + this.model = model; + } + + @Override + public String toString() { + return "Vehicle{" + + "vehicleId=" + + vehicleId + + ", manufacturer='" + + manufacturer + + '\'' + + ", model='" + + model + + '}'; + } + +} diff --git a/single-table-inheritance/src/main/java/com/iluwatar/repository/VehicleRepository.java b/single-table-inheritance/src/main/java/com/iluwatar/repository/VehicleRepository.java new file mode 100644 index 000000000000..5aec26c3aa95 --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/repository/VehicleRepository.java @@ -0,0 +1,14 @@ +package com.iluwatar.repository; + +import com.iluwatar.entity.Vehicle; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +/** + * A repository that is extending the JPA Repository + * to provide the default Spring DATA JPA methods for the Vehicle class. + */ +@Repository +public interface VehicleRepository extends JpaRepository { + +} diff --git a/single-table-inheritance/src/main/java/com/iluwatar/service/VehicleService.java b/single-table-inheritance/src/main/java/com/iluwatar/service/VehicleService.java new file mode 100644 index 000000000000..4aeacd04824d --- /dev/null +++ b/single-table-inheritance/src/main/java/com/iluwatar/service/VehicleService.java @@ -0,0 +1,71 @@ +package com.iluwatar.service; + +import com.iluwatar.entity.Vehicle; +import com.iluwatar.repository.VehicleRepository; +import java.util.List; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +/** + * A service class that is used to provide the business logic + * for the Vehicle class and connect to the database to + * perform the CRUD operations on the root Vehicle class. + * + * @see Vehicle + */ +@Service +@AllArgsConstructor +public class VehicleService { + + private final VehicleRepository vehicleRepository; + + /** + * A method to save all the vehicles to the database. + * + * @param vehicle Vehicle bbject + * @see Vehicle + */ + public Vehicle saveVehicle(Vehicle vehicle) { + return vehicleRepository.save(vehicle); + } + + /** + * A method to get a specific vehicle from vehicle id. + * + * @param vehicleId Vehicle Id + * @see Vehicle + */ + public Vehicle getVehicle(int vehicleId) { + return vehicleRepository.findById(vehicleId).orElse(null); + } + + /** + * A method to get all the vehicles saved in the database. + * + * @see Vehicle + */ + public List getAllVehicles() { + return vehicleRepository.findAll(); + } + + /** + * A method to update a vehicle in the database. + * + * @param vehicle Vehicle object + * @see Vehicle + */ + public Vehicle updateVehicle(Vehicle vehicle) { + return vehicleRepository.save(vehicle); + } + + /** + * A method to save all the vehicles to the database. + * + * @param vehicle Vehicle object + * @see Vehicle + */ + public void deleteVehicle(Vehicle vehicle) { + vehicleRepository.delete(vehicle); + } + +} diff --git a/single-table-inheritance/src/main/resources/application.properties b/single-table-inheritance/src/main/resources/application.properties new file mode 100644 index 000000000000..e2d8176fde86 --- /dev/null +++ b/single-table-inheritance/src/main/resources/application.properties @@ -0,0 +1,11 @@ + +# H2 Database Configuration +spring.datasource.url=jdbc:h2:mem:sti +spring.datasource.username=sa +spring.datasource.password=password +spring.datasource.driverClassName=org.h2.Driver +spring.jpa.hibernate.ddl-auto=update + +#Uncomment the below properties to see the SQL being generated in backend +#spring.jpa.show-sql=true +#spring.jpa.properties.hibernate.format_sql=true \ No newline at end of file