diff --git a/single-table-inheritance/README.md b/single-table-inheritance/README.md index 019f037e6..c37682256 100644 --- a/single-table-inheritance/README.md +++ b/single-table-inheritance/README.md @@ -129,12 +129,92 @@ public class VehicleService { } ``` +Finally, here is the Spring Boot application that runs our example. + +```java +@SpringBootApplication +@AllArgsConstructor +public class SingleTableInheritance implements CommandLineRunner { + + //Autowiring the VehicleService class to execute the business logic methods + private final VehicleService vehicleService; + + public static void main(String[] args) { + SpringApplication.run(SingleTableInheritance.class, args); + } + + @Override + public void run(String... args) { + + 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())); + } +} +``` + +Console output: + +``` +2024-05-27T12:29:49.949+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Starting SingleTableInheritance using Java 17.0.4.1 with PID 56372 (/Users/ilkka.seppala/git/java-design-patterns/single-table-inheritance/target/classes started by ilkka.seppala in /Users/ilkka.seppala/git/java-design-patterns) +2024-05-27T12:29:49.951+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : No active profile set, falling back to 1 default profile: "default" +2024-05-27T12:29:50.154+03:00 INFO 56372 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2024-05-27T12:29:50.176+03:00 INFO 56372 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 1 JPA repository interface. +2024-05-27T12:29:50.315+03:00 INFO 56372 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2024-05-27T12:29:50.345+03:00 INFO 56372 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.4.4.Final +2024-05-27T12:29:50.360+03:00 INFO 56372 --- [ main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2024-05-27T12:29:50.457+03:00 INFO 56372 --- [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2024-05-27T12:29:50.468+03:00 INFO 56372 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2024-05-27T12:29:50.541+03:00 INFO 56372 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:sti user=SA +2024-05-27T12:29:50.542+03:00 INFO 56372 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2024-05-27T12:29:50.930+03:00 INFO 56372 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2024-05-27T12:29:50.953+03:00 INFO 56372 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2024-05-27T12:29:51.094+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Started SingleTableInheritance in 1.435 seconds (process running for 1.678) +2024-05-27T12:29:51.095+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Saving Vehicles :- +2024-05-27T12:29:51.114+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Vehicle 1 saved : Car{PassengerVehicle(noOfPassengers=4)} +2024-05-27T12:29:51.115+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Vehicle 2 saved : Truck{ TransportVehicle(loadCapacity=3325), towingCapacity=14000} + +2024-05-27T12:29:51.115+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Fetching Vehicles :- +2024-05-27T12:29:51.129+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Fetching Car1 from DB : Car{PassengerVehicle(noOfPassengers=0)} +2024-05-27T12:29:51.130+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Fetching Truck1 from DB : Truck{ TransportVehicle(loadCapacity=0), towingCapacity=14000} + +2024-05-27T12:29:51.130+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Fetching All Vehicles :- +2024-05-27T12:29:51.169+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Car{PassengerVehicle(noOfPassengers=0)} +2024-05-27T12:29:51.169+03:00 INFO 56372 --- [ main] com.iluwatar.SingleTableInheritance : Truck{ TransportVehicle(loadCapacity=0), towingCapacity=14000} +2024-05-27T12:29:51.172+03:00 INFO 56372 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' +2024-05-27T12:29:51.173+03:00 INFO 56372 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... +2024-05-27T12:29:51.174+03:00 INFO 56372 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. +``` + The Single Table Inheritance pattern is a simple and efficient way to map an inheritance hierarchy to a relational database. However, it can lead to sparse tables if subclasses have many unique fields. In such cases, other patterns like Class Table Inheritance or Concrete Table Inheritance might be more appropriate. -## Class diagram - -![Single Table Inheritance](./etc/single-table-inheritance.urm.png "Single Table Inheritance") - ## Applicability * Use when you have a class hierarchy with subclasses that share a common base class and you want to store all instances of the hierarchy in a single table. @@ -142,7 +222,7 @@ The Single Table Inheritance pattern is a simple and efficient way to map an inh ### Tutorials -* [Hibernate Tutorial 18 - Implementing Inheritance - Single Table Strategy - Java Brains](https://www.youtube.com/watch?v=M5YrLtAHtOo) +* [Hibernate Tutorial 18 - Implementing Inheritance - Single Table Strategy (Java Brains)](https://www.youtube.com/watch?v=M5YrLtAHtOo) ## Known uses @@ -172,4 +252,4 @@ Trade-offs: * [Domain-Driven Design: Tackling Complexity in the Heart of Software](https://amzn.to/3wlDrze) * [Java Persistence with Hibernate](https://amzn.to/44tP1ox) * [Patterns of Enterprise Application Architecture](https://amzn.to/3WfKBPR) -* [Single Table Inheritance - Martin Fowler](https://www.martinfowler.com/eaaCatalog/singleTableInheritance.html) +* [Single Table Inheritance (Martin Fowler)](https://www.martinfowler.com/eaaCatalog/singleTableInheritance.html)