JPA Inheritance Mapping হলো একটি টেকনিক, যার মাধ্যমে জাভার ইনহেরিটেন্স (Inheritance) স্ট্রাকচারকে ডেটাবেস টেবিলের সঙ্গে ম্যাপ করা যায়। এটি ডেটা মডেলকে আরও কার্যকরভাবে ডিজাইন করার সুযোগ দেয়। JPA বিভিন্ন ইনহেরিটেন্স স্ট্রাটেজি সমর্থন করে, যা ডেটাবেসের কাঠামো অনুযায়ী নির্বাচন করা যায়।
সব ক্লাসের ডেটা একটি টেবিলে রাখা হয়। প্রতিটি ইনহেরিটেড ক্লাসের জন্য একটি আলাদা কলাম থাকে।
প্রত্যেক সাবক্লাসের জন্য আলাদা টেবিল তৈরি হয়। অভিভাবক (Parent) ক্লাসের টেবিল থাকে না।
অভিভাবক এবং প্রত্যেক সাবক্লাসের জন্য আলাদা টেবিল তৈরি হয়। Parent এবং Child টেবিলগুলো একটি সম্পর্কের (Join) মাধ্যমে যুক্ত থাকে।
@Inheritance
: ইনহেরিটেন্স স্ট্রাটেজি নির্ধারণের জন্য ব্যবহৃত হয়।@DiscriminatorColumn
: Single Table স্ট্রাটেজির ক্ষেত্রে টেবিলে সাবক্লাস চিহ্নিত করার জন্য একটি কলাম নির্ধারণ করে।@MappedSuperclass
: কোনো ক্লাসকে Entity হিসেবে চিহ্নিত না করে শুধুমাত্র ইনহেরিটেন্সের জন্য Parent হিসেবে ব্যবহার করা হয়।নিচে একটি উদাহরণ দেওয়া হলো যেখানে একটি Person
ক্লাস Parent এবং Employee
এবং Customer
ক্লাস Child।
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED) // স্ট্রাটেজি: Joined
public abstract class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import jakarta.persistence.Entity;
@Entity
public class Employee extends Person {
private String department;
// Getters and Setters
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
}
import jakarta.persistence.Entity;
@Entity
public class Customer extends Person {
private String membershipLevel;
// Getters and Setters
public String getMembershipLevel() {
return membershipLevel;
}
public void setMembershipLevel(String membershipLevel) {
this.membershipLevel = membershipLevel;
}
}
Joined স্ট্রাটেজির ক্ষেত্রে ডেটাবেসে তিনটি টেবিল তৈরি হবে:
Person
টেবিল:
CREATE TABLE Person (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255)
);
Employee
টেবিল:
CREATE TABLE Employee (
id BIGINT PRIMARY KEY,
department VARCHAR(255),
FOREIGN KEY (id) REFERENCES Person(id)
);
Customer
টেবিল:
CREATE TABLE Customer (
id BIGINT PRIMARY KEY,
membershipLevel VARCHAR(255),
FOREIGN KEY (id) REFERENCES Person(id)
);
JPA Repository ব্যবহার করে ডেটাবেস অপারেশন সম্পন্ন করা যায়:
import org.springframework.data.jpa.repository.JpaRepository;
public interface PersonRepository extends JpaRepository<Person, Long> {
// Custom query methods
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/persons")
public class PersonController {
@Autowired
private PersonRepository personRepository;
@GetMapping
public List<Person> getAllPersons() {
return personRepository.findAll();
}
@PostMapping("/employee")
public Person addEmployee(@RequestBody Employee employee) {
return personRepository.save(employee);
}
@PostMapping("/customer")
public Person addCustomer(@RequestBody Customer customer) {
return personRepository.save(customer);
}
}
JPA Inheritance Mapping স্প্রিং বুটে ডেটা মডেলিংকে আরও কার্যকর করে। এর মাধ্যমে ডেটাবেসের কাঠামো এবং জাভার ইনহেরিটেড ক্লাসগুলোর মধ্যে মেলবন্ধন তৈরি করা যায়। বিভিন্ন স্ট্রাটেজি ব্যবহার করে আপনার প্রজেক্টের চাহিদা অনুযায়ী উপযুক্ত মডেল তৈরি করা সম্ভব।
Java Persistence API (JPA) অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং মডেলের একটি গুরুত্বপূর্ণ বৈশিষ্ট্য হল Inheritance। এটি ডাটাবেসের টেবিল এবং জাভা ক্লাসের মধ্যে অবজেক্ট-ওরিয়েন্টেড উত্তরাধিকার (Inheritance) মডেল পরিচালনার জন্য ব্যবহৃত হয়। জাভার ইনহেরিটেন্স কনসেপ্টকে ডাটাবেসে রিফ্লেক্ট করতে JPA বিভিন্ন স্ট্র্যাটেজি প্রদান করে।
Inheritance হল অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ের একটি মৌলিক বৈশিষ্ট্য, যা এক ক্লাসের বৈশিষ্ট্য (Attributes) এবং মেথড (Methods) আরেকটি ক্লাসে শেয়ার করার সুযোগ দেয়। JPA ইনহেরিটেন্সের মাধ্যমে, আমরা প্যারেন্ট ক্লাসের তথ্য একাধিক চাইল্ড ক্লাসের মধ্যে শেয়ার করতে পারি এবং সেগুলো ডাটাবেস টেবিলের মধ্যে সঠিকভাবে ম্যাপ করতে পারি।
JPA-তে ইনহেরিটেন্স ব্যবস্থাপনার জন্য তিনটি স্ট্র্যাটেজি ব্যবহৃত হয়:
একটি মাত্র টেবিলে সব প্যারেন্ট এবং চাইল্ড ক্লাসের তথ্য রাখা হয়। এটি দ্রুত এবং কার্যকর কিন্তু ডাটা রিডান্ডেন্সি বাড়তে পারে।
উদাহরণ:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public class Employee {
@Id
private Long id;
private String name;
}
@Entity
public class FullTimeEmployee extends Employee {
private double salary;
}
@Entity
public class PartTimeEmployee extends Employee {
private double hourlyRate;
}
টেবিল গঠন:
ID | NAME | TYPE | SALARY | HOURLY_RATE |
---|---|---|---|---|
1 | Alice | FullTimeEmployee | 50000 | NULL |
2 | Bob | PartTimeEmployee | NULL | 20 |
প্রতিটি ক্লাসের জন্য আলাদা টেবিল তৈরি হয়। এটি রিলেশনাল ডাটাবেসের জন্য আরও স্বচ্ছ, কিন্তু কার্যকারিতা কিছুটা কম হতে পারে।
উদাহরণ:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Employee {
@Id
private Long id;
private String name;
}
@Entity
public class FullTimeEmployee extends Employee {
private double salary;
}
@Entity
public class PartTimeEmployee extends Employee {
private double hourlyRate;
}
টেবিল গঠন:
Employee (প্যারেন্ট টেবিল):
ID | NAME |
---|---|
1 | Alice |
2 | Bob |
FullTimeEmployee (চাইল্ড টেবিল):
ID | SALARY |
---|---|
1 | 50000 |
PartTimeEmployee (চাইল্ড টেবিল):
ID | HOURLY_RATE |
---|---|
2 | 20 |
প্যারেন্ট ক্লাস এবং চাইল্ড ক্লাসের জন্য আলাদা টেবিল তৈরি হয় এবং তাদের মধ্যে যোগসূত্র থাকে। এটি নরমালাইজড ডাটাবেস মডেল তৈরি করে এবং ডাটা রিডান্ডেন্সি কমায়।
উদাহরণ:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Employee {
@Id
private Long id;
private String name;
}
@Entity
public class FullTimeEmployee extends Employee {
private double salary;
}
@Entity
public class PartTimeEmployee extends Employee {
private double hourlyRate;
}
টেবিল গঠন:
Employee (প্যারেন্ট টেবিল):
ID | NAME |
---|---|
1 | Alice |
2 | Bob |
FullTimeEmployee (চাইল্ড টেবিল):
ID | SALARY |
---|---|
1 | 50000 |
PartTimeEmployee (চাইল্ড টেবিল):
ID | HOURLY_RATE |
---|---|
2 | 20 |
JPA Inheritance ডাটাবেস এবং জাভা অবজেক্টের মধ্যে ইনহেরিটেন্স মডেল তৈরি করতে গুরুত্বপূর্ণ ভূমিকা পালন করে। এটি ডাটাবেস মডেলিংকে আরও কার্যকর এবং অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ের সাথে সামঞ্জস্যপূর্ণ করে। Inheritance এর বিভিন্ন স্ট্র্যাটেজি ব্যবহার করে আপনি আপনার অ্যাপ্লিকেশনের প্রয়োজন অনুযায়ী ডাটাবেস ডিজাইন করতে পারেন।
স্প্রিং বুট এবং JPA (Java Persistence API) বিভিন্ন ধরণের ইনহেরিটেন্স স্ট্র্যাটেজি প্রদান করে। ইনহেরিটেন্স স্ট্র্যাটেজি ডেটাবেসে অবজেক্ট-ওরিয়েন্টেড সম্পর্ককে টেবিল ফর্ম্যাটে মানচিত্র করতে সাহায্য করে। JPA তিনটি প্রধান ইনহেরিটেন্স স্ট্র্যাটেজি প্রদান করে:
এই স্ট্র্যাটেজিতে প্রতিটি ক্লাসের জন্য একটি স্বতন্ত্র টেবিল তৈরি করা হয়। বেস ক্লাস এবং ডেরাইভড ক্লাসের ডেটা আলাদাভাবে সংরক্ষণ করা হয়।
Inheritance Type: InheritanceType.TABLE_PER_CLASS
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
// Getters and Setters
}
@Entity
public class Car extends Vehicle {
private int seatingCapacity;
// Getters and Setters
}
@Entity
public class Bike extends Vehicle {
private boolean hasCarrier;
// Getters and Setters
}
id
, name
, seatingCapacity
id
, name
, hasCarrier
এই স্ট্র্যাটেজিতে সমস্ত ক্লাসের ডেটা একটি টেবিলে রাখা হয়। টেবিলটি একটি discriminator column
ব্যবহার করে ডেটা আলাদা করে।
Inheritance Type: InheritanceType.SINGLE_TABLE
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "vehicle_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
// Getters and Setters
}
@Entity
@DiscriminatorValue("CAR")
public class Car extends Vehicle {
private int seatingCapacity;
// Getters and Setters
}
@Entity
@DiscriminatorValue("BIKE")
public class Bike extends Vehicle {
private boolean hasCarrier;
// Getters and Setters
}
id
, name
, vehicle_type
, seatingCapacity
, hasCarrier
এই স্ট্র্যাটেজিতে প্রতিটি ক্লাসের জন্য আলাদা টেবিল থাকে, তবে তাদের মধ্যে সম্পর্ক গঠন করার জন্য JOIN
অপারেশন ব্যবহৃত হয়।
Inheritance Type: InheritanceType.JOINED
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
// Getters and Setters
}
@Entity
public class Car extends Vehicle {
private int seatingCapacity;
// Getters and Setters
}
@Entity
public class Bike extends Vehicle {
private boolean hasCarrier;
// Getters and Setters
}
id
, name
id
, seatingCapacity
id
, hasCarrier
বৈশিষ্ট্য | Table-per-Class | Single Table | Joined Table |
---|---|---|---|
সংরক্ষণ কৌশল | প্রতিটি ক্লাসের জন্য আলাদা টেবিল | একক টেবিলে সমস্ত ডেটা | সম্পর্কিত টেবিল ব্যবহার |
ডেটার অখণ্ডতা | কম | কম | বেশি |
স্টোরেজ দক্ষতা | কম | বেশি | মাঝারি |
কোয়েরি জটিলতা | কম | সহজ | বেশি |
নাল ভ্যালু সমস্যা | না | হ্যাঁ | না |
Spring Boot এবং JPA-তে Table-per-Class, Single Table, এবং Joined Table ইনহেরিটেন্স স্ট্র্যাটেজি ব্যবহার করে ডেটাবেস সম্পর্ক গঠন এবং ডেটা সংরক্ষণ করা যায়। প্রতিটি স্ট্র্যাটেজির নিজস্ব সুবিধা এবং সীমাবদ্ধতা রয়েছে। আপনার প্রয়োজন অনুসারে স্ট্র্যাটেজি বেছে নেওয়া উচিত।
JPA Inheritance Mapping ব্যবহার করে আমরা ডাটাবেস টেবিলের মধ্যে Object-Oriented Programming এর Inheritance ধারণা প্রয়োগ করতে পারি। এটি বিশেষভাবে উপকারী যখন আমাদের কাছে Parent এবং Child ক্লাস থাকে এবং আমরা ডেটা টেবিলগুলোর মধ্যে সম্পর্ক তৈরি করতে চাই।
JPA বিভিন্ন স্ট্র্যাটেজি ব্যবহার করে Inheritance Mapping সম্পন্ন করে। এগুলো হলো:
SINGLE_TABLE স্ট্র্যাটেজিতে Parent এবং Child ক্লাসের সব ডেটা একটি একক টেবিলে সংরক্ষিত হয়।
Entity ক্লাস (Parent এবং Child):
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getters and Setters
}
@Entity
@DiscriminatorValue("Car")
public class Car extends Vehicle {
private int seatCount;
// Getters and Setters
}
@Entity
@DiscriminatorValue("Bike")
public class Bike extends Vehicle {
private boolean hasCarrier;
// Getters and Setters
}
জেনারেট হওয়া টেবিল:
id | name | type | seatCount | hasCarrier |
---|---|---|---|---|
1 | Toyota | Car | 5 | NULL |
2 | Yamaha | Bike | NULL | true |
TABLE_PER_CLASS স্ট্র্যাটেজিতে Parent ক্লাস এবং প্রতিটি Child ক্লাসের জন্য আলাদা আলাদা টেবিল তৈরি হয়।
Entity ক্লাস (Parent এবং Child):
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getters and Setters
}
@Entity
public class Car extends Vehicle {
private int seatCount;
// Getters and Setters
}
@Entity
public class Bike extends Vehicle {
private boolean hasCarrier;
// Getters and Setters
}
জেনারেট হওয়া টেবিল:
Car টেবিল:
id | name | seatCount |
---|---|---|
1 | Toyota | 5 |
Bike টেবিল:
id | name | hasCarrier |
---|---|---|
1 | Yamaha | true |
JOINED স্ট্র্যাটেজিতে Parent ক্লাস এবং Child ক্লাসের জন্য আলাদা টেবিল তৈরি হয়, এবং তাদের মধ্যে একটি JOIN
সম্পর্ক থাকে।
Entity ক্লাস (Parent এবং Child):
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getters and Setters
}
@Entity
public class Car extends Vehicle {
private int seatCount;
// Getters and Setters
}
@Entity
public class Bike extends Vehicle {
private boolean hasCarrier;
// Getters and Setters
}
জেনারেট হওয়া টেবিল:
Vehicle টেবিল:
id | name |
---|---|
1 | Toyota |
2 | Yamaha |
Car টেবিল:
id | seatCount |
---|---|
1 | 5 |
Bike টেবিল:
id | hasCarrier |
---|---|
2 | true |
Repository:
import org.springframework.data.jpa.repository.JpaRepository;
public interface VehicleRepository extends JpaRepository<Vehicle, Long> {
}
Service:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class VehicleService {
@Autowired
private VehicleRepository vehicleRepository;
public void saveVehicles() {
Car car = new Car();
car.setName("Toyota");
car.setSeatCount(5);
vehicleRepository.save(car);
Bike bike = new Bike();
bike.setName("Yamaha");
bike.setHasCarrier(true);
vehicleRepository.save(bike);
}
}
JOIN
অপারেশনের কারণে স্লো হতে পারে।JPA Inheritance Mapping ব্যবহার করে Parent-Child সম্পর্কের ডেটা টেবিলের সঙ্গে মানিয়ে নেওয়া যায়। SINGLE_TABLE, TABLE_PER_CLASS, এবং JOINED স্ট্র্যাটেজির মধ্যে সঠিক একটি নির্বাচন অ্যাপ্লিকেশনের প্রয়োজন অনুযায়ী নির্ভর করে। প্রতিটি স্ট্র্যাটেজির নিজস্ব সুবিধা এবং সীমাবদ্ধতা রয়েছে।
Read more