JPA (Java Persistence API) তে Inheritance Mapping ব্যবহার করে, আপনি একটি Entity শ্রেণীকে (class) অন্য একটি Entity শ্রেণীর থেকে বংশানুক্রমিকভাবে উত্তরাধিকারী (inherit) করতে পারেন। এটি ডেটাবেসে একাধিক Entity শ্রেণীর মধ্যে সম্পর্ক তৈরি করতে ব্যবহৃত হয়, যেমন একটি সাধারণ শ্রেণী থেকে অন্যান্য শ্রেণীতে শেয়ার করা বৈশিষ্ট্য বা আচরণ। JPA তে Inheritance Mapping তিনটি প্রধান পদ্ধতিতে করা যায়:
- Single Table Inheritance (একটি টেবিল ব্যবহার)
- Joined Table Inheritance (বিভিন্ন টেবিল ব্যবহার)
- Table Per Class Inheritance (প্রত্যেক ক্লাসের জন্য পৃথক টেবিল)
1. Single Table Inheritance
Single Table Inheritance পদ্ধতিতে, সমস্ত সাবক্লাসের ডেটা একটিই টেবিলের মধ্যে সঞ্চিত হয়। এই পদ্ধতিতে, সব ক্লাসের জন্য একটি মাত্র টেবিল তৈরি করা হয় এবং টেবিলের মধ্যে প্রতিটি রেকর্ডের জন্য একটি ডিফারেন্ট discriminator কলাম ব্যবহৃত হয়, যা নির্ধারণ করে কোন সাবক্লাসের অবজেক্ট এটি।
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
- SINGLE_TABLE স্ট্রাটেজি ব্যবহার করে এই পদ্ধতি কনফিগার করা হয়।
- টেবিলের একটি discriminator column থাকে যা জানায় কোন সাবক্লাসের অবজেক্ট এটি।
উদাহরণ:
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "vehicle_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String model;
// Getter and Setter Methods
}
@Entity
@DiscriminatorValue("Car")
public class Car extends Vehicle {
private int numberOfDoors;
// Getter and Setter Methods
}
@Entity
@DiscriminatorValue("Truck")
public class Truck extends Vehicle {
private int payloadCapacity;
// Getter and Setter Methods
}
এখানে, Vehicle একটি সুপার ক্লাস এবং Car ও Truck দুটি সাবক্লাস। SINGLE_TABLE স্ট্রাটেজি ব্যবহার করা হয়েছে, এবং vehicle_type নামক discriminator কলামটি সাবক্লাসের ধরন চিহ্নিত করবে।
টেবিল উদাহরণ:
| id | model | vehicle_type | numberOfDoors | payloadCapacity |
|---|---|---|---|---|
| 1 | Model1 | Car | 4 | NULL |
| 2 | Model2 | Truck | NULL | 5000 |
2. Joined Table Inheritance
Joined Table Inheritance পদ্ধতিতে, প্রতিটি সাবক্লাসের জন্য আলাদা টেবিল তৈরি করা হয়। তবে, সমস্ত সাবক্লাসের ডেটা সংরক্ষিত হয় এবং তাদের মধ্যে সম্পর্ক JOIN এর মাধ্যমে প্রতিষ্ঠিত হয়। এই পদ্ধতিতে মূল ক্লাসের জন্য একটি টেবিল এবং তার সাথেই সাবক্লাসের জন্য আলাদা টেবিল থাকে।
@Inheritance(strategy = InheritanceType.JOINED)
- JOINED স্ট্রাটেজি ব্যবহার করে এই পদ্ধতি কনফিগার করা হয়।
- এতে Vehicle টেবিলের সাথে Car এবং Truck টেবিল JOIN হয়।
উদাহরণ:
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String model;
// Getter and Setter Methods
}
@Entity
public class Car extends Vehicle {
private int numberOfDoors;
// Getter and Setter Methods
}
@Entity
public class Truck extends Vehicle {
private int payloadCapacity;
// Getter and Setter Methods
}
এখানে, Vehicle ক্লাসের জন্য একটি টেবিল এবং Car এবং Truck ক্লাসের জন্য আলাদা টেবিল তৈরি হবে।
টেবিল উদাহরণ:
Vehicle টেবিল:
| id | model |
|---|---|
| 1 | Model1 |
| 2 | Model2 |
Car টেবিল:
| id | numberOfDoors |
|---|---|
| 1 | 4 |
Truck টেবিল:
| id | payloadCapacity |
|---|---|
| 2 | 5000 |
3. Table Per Class Inheritance
Table Per Class Inheritance পদ্ধতিতে, প্রতিটি ক্লাসের জন্য আলাদা টেবিল তৈরি করা হয় এবং প্রতিটি টেবিল সম্পূর্ণ ডেটা ধারণ করে, যার মধ্যে সুপার ক্লাসের এবং সাবক্লাসের ফিল্ড থাকে।
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
- TABLE_PER_CLASS স্ট্রাটেজি ব্যবহার করে এই পদ্ধতি কনফিগার করা হয়।
- প্রতিটি ক্লাসের জন্য আলাদা টেবিল তৈরি হয়, তবে সুপার ক্লাসের কোনো টেবিল থাকে না। সমস্ত তথ্য সরাসরি সাবক্লাসের টেবিলেই থাকে।
উদাহরণ:
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String model;
// Getter and Setter Methods
}
@Entity
public class Car extends Vehicle {
private int numberOfDoors;
// Getter and Setter Methods
}
@Entity
public class Truck extends Vehicle {
private int payloadCapacity;
// Getter and Setter Methods
}
এখানে, Vehicle ক্লাসের জন্য কোনো টেবিল তৈরি হবে না, তবে Car এবং Truck ক্লাসের জন্য পৃথক টেবিল তৈরি হবে।
টেবিল উদাহরণ:
Car টেবিল:
| id | model | numberOfDoors |
|---|---|---|
| 1 | Model1 | 4 |
Truck টেবিল:
| id | model | payloadCapacity |
|---|---|---|
| 2 | Model2 | 5000 |
Inheritance Mapping এর সুবিধা এবং অসুবিধা
| পদ্ধতি | সুবিধা | অসুবিধা |
|---|---|---|
| Single Table | - সহজ এবং দ্রুত ডেটা রিট্রিভাল- কম টেবিল তৈরি | - টেবিল খুব বড় হয়ে যেতে পারে- বিভিন্ন ক্লাসের ডেটার মিশ্রণ হতে পারে |
| Joined Table | - ডেটা আরও সুনির্দিষ্ট এবং পরিষ্কার- নর্মালাইজড ডেটাবেস | - JOIN অপারেশন প্রয়োজন- পারফরম্যান্স কিছুটা কম হতে পারে |
| Table Per Class | - প্রতিটি ক্লাসের জন্য আলাদা টেবিল- কমপ্লেক্স রিলেশন সহজ | - ডেটা ডুপ্লিকেট হতে পারে- পারফরম্যান্স সমস্যা হতে পারে |
সার্বিক পর্যালোচনা
JPA তে Inheritance Mapping Java অবজেক্ট-রিলেশনাল মডেলিং এর জন্য একটি গুরুত্বপূর্ণ বৈশিষ্ট্য। এটি ডেটাবেস টেবিলগুলির মধ্যে সম্পর্ক স্থাপন এবং ডেটা পুনরুদ্ধার প্রক্রিয়াকে সহজ করে তোলে। Single Table, Joined Table, এবং Table Per Class স্ট্রাটেজি প্রতিটির আলাদা সুবিধা এবং সীমাবদ্ধতা রয়েছে। ডেভেলপারদের তাদের প্রয়োজনের ওপর ভিত্তি করে সঠিক স্ট্রাটেজি বেছে নেওয়া উচিত, যাতে তারা ডেটাবেস মডেলিং এবং পারফরম্যান্সে ভালো ফলাফল পায়।
JPA (Java Persistence API) তে Inheritance Mapping হল একটি কৌশল যার মাধ্যমে Object-Oriented Inheritance এর ধারণা রিলেশনাল ডেটাবেসে বাস্তবায়িত করা হয়। অর্থাৎ, যখন Java ক্লাসে Inheritance ব্যবহৃত হয়, তখন এটি ডেটাবেস টেবিলের মধ্যে কিভাবে ম্যাপ করা হবে তা JPA নির্ধারণ করে।
Inheritance হল OOP (Object-Oriented Programming) এর একটি মৌলিক ধারণা, যেখানে একটি ক্লাস অন্য একটি ক্লাস থেকে বৈশিষ্ট্য (properties) এবং আচরণ (behaviors) উত্তরাধিকার সূত্রে পায়। JPA তে, ইনহেরিট্যান্স মডেল কনফিগার করার জন্য তিনটি প্রধান পদ্ধতি রয়েছে:
- Single Table Inheritance (একটি টেবিল ব্যবহার করা)
- Joined Table Inheritance (একাধিক টেবিল ব্যবহার করা)
- Table Per Class Inheritance (প্রতিটি ক্লাসের জন্য আলাদা টেবিল)
এই তিনটি পদ্ধতির মাধ্যমে JPA ইনহেরিট্যান্স সম্পর্কিত ক্লাসের মধ্যে ডেটাবেস টেবিলের ম্যাপিং কিভাবে হবে তা নির্ধারণ করা হয়।
Single Table Inheritance (একটি টেবিল ব্যবহার করা)
Single Table Inheritance পদ্ধতিতে সমস্ত ইনহেরিটেড ক্লাসগুলোকে একটি একক টেবিলে ম্যাপ করা হয়। এই পদ্ধতিতে একটি টেবিল থাকে যা সমস্ত সাবক্লাসের ডেটা ধারণ করে, এবং একটি অতিরিক্ত কলাম (যেমন discriminator column) ব্যবহার করা হয় যাতে বোঝা যায় কোন রেকর্ড কোন সাবক্লাসের।
Single Table Inheritance এর উদাহরণ:
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "vehicle_type", discriminatorType = DiscriminatorType.STRING)
public class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String model;
// Getter এবং Setter
}
@Entity
@DiscriminatorValue("Car")
public class Car extends Vehicle {
private int doors;
// Getter এবং Setter
}
@Entity
@DiscriminatorValue("Bike")
public class Bike extends Vehicle {
private boolean hasPedals;
// Getter এবং Setter
}
এখানে:
- @Inheritance(strategy = InheritanceType.SINGLE_TABLE) অ্যানোটেশনটি Vehicle ক্লাসকে একটি সিঙ্গেল টেবিলের জন্য ব্যবহার করছে।
- @DiscriminatorColumn এবং @DiscriminatorValue ব্যবহার করে টেবিলের মধ্যে ভিন্ন ভিন্ন সাবক্লাসগুলোকে চিহ্নিত করা হয়।
Database Table Structure:
| id | model | vehicle_type | doors | hasPedals |
|---|---|---|---|---|
| 1 | CarModel1 | Car | 4 | NULL |
| 2 | BikeModel1 | Bike | NULL | true |
- vehicle_type কলামটি ডিসক্রিমিনেটর কলাম হিসেবে কাজ করে, যা
CarএবংBikeএর মধ্যে পার্থক্য নির্ধারণ করে।
Joined Table Inheritance (একাধিক টেবিল ব্যবহার করা)
Joined Table Inheritance পদ্ধতিতে, প্রতিটি ক্লাসের জন্য একটি আলাদা টেবিল তৈরি করা হয়। একটি টেবিল সপোর্ট করে মূল (পারেন্ট) ক্লাসের প্রপার্টি, এবং অন্য টেবিলগুলো সাবক্লাসের জন্য নির্দিষ্ট ডেটা ধারণ করে। টেবিলগুলোর মধ্যে একটি JOIN সম্পর্ক স্থাপন করা হয়।
Joined Table Inheritance এর উদাহরণ:
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String model;
// Getter এবং Setter
}
@Entity
public class Car extends Vehicle {
private int doors;
// Getter এবং Setter
}
@Entity
public class Bike extends Vehicle {
private boolean hasPedals;
// Getter এবং Setter
}
Database Tables:
- Vehicle Table:
| id | model |
|---|---|
| 1 | CarModel1 |
| 2 | BikeModel1 |
- Car Table:
| id | doors |
|---|---|
| 1 | 4 |
- Bike Table:
| id | hasPedals |
|---|---|
| 2 | true |
এখানে:
- Vehicle টেবিলটি Car এবং Bike টেবিলের সাথে JOIN সম্পর্ক স্থাপন করে, যাতে উপরের সব ডেটা একসাথে পাওয়া যায়।
Table Per Class Inheritance (প্রতিটি ক্লাসের জন্য আলাদা টেবিল)
Table Per Class Inheritance পদ্ধতিতে, প্রতিটি ক্লাসের জন্য আলাদা আলাদা টেবিল তৈরি করা হয়, এবং সেই টেবিলে পুরো ক্লাসের ডেটা থাকে, তবে তারপরে JOIN করা হয় না। এটি সহজ তবে কিছু ক্ষেত্রে ডেটার পুনরাবৃত্তি হতে পারে।
Table Per Class Inheritance এর উদাহরণ:
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String model;
// Getter এবং Setter
}
@Entity
public class Car extends Vehicle {
private int doors;
// Getter এবং Setter
}
@Entity
public class Bike extends Vehicle {
private boolean hasPedals;
// Getter এবং Setter
}
Database Tables:
- Vehicle Table:
| id | model |
|---|---|
| 1 | CarModel1 |
| 2 | BikeModel1 |
- Car Table:
| id | model | doors |
|---|---|---|
| 1 | CarModel1 | 4 |
- Bike Table:
| id | model | hasPedals |
|---|---|---|
| 2 | BikeModel1 | true |
এখানে:
- Vehicle, Car, এবং Bike টেবিলগুলো আলাদা আলাদা ডেটা ধারণ করে, এবং প্রত্যেকটি টেবিল সম্পূর্ণ ক্লাসের ডেটা সংরক্ষণ করে।
JPA Inheritance Strategy Summary
| Strategy | Description | Example |
|---|---|---|
| Single Table | সমস্ত ইনহেরিটেড ক্লাস একটি টেবিলের মধ্যে স্টোর করা হয়। | সহজ, তবে বড় ক্লাসের জন্য ডেটা পুনরাবৃত্তি হতে পারে। |
| Joined Table | প্রতিটি ক্লাসের জন্য আলাদা টেবিল, ডেটা JOIN করা হয়। | ডেটার পুনরাবৃত্তি কম, তবে জটিলতা বেশি। |
| Table Per Class | প্রতিটি ক্লাসের জন্য আলাদা টেবিল, কিন্তু JOIN করা হয় না। | সহজ, তবে বড় ক্লাসের জন্য ডেটা পুনরাবৃত্তি হতে পারে। |
সার্বিক পর্যালোচনা
JPA Inheritance Mapping একটি গুরুত্বপূর্ণ ধারণা যা Java অবজেক্ট এবং ডেটাবেস টেবিলের মধ্যে সম্পর্ক স্থাপন করতে সাহায্য করে। JPA তে ইনহেরিট্যান্স মডেল কনফিগার করার জন্য Single Table, Joined Table, এবং Table Per Class এর তিনটি পদ্ধতি রয়েছে। প্রতিটি পদ্ধতির সুবিধা এবং অসুবিধা রয়েছে, এবং ডেভেলপারদের এটি তাদের প্রোজেক্টের চাহিদা অনুযায়ী নির্বাচন করতে হবে।
Single Table Inheritance সিম্পল কিন্তু কিছু ক্ষেত্রে ডেটা পুনরাবৃত্তি হতে পারে, Joined Table Inheritance রিলেশনাল ডেটাবেসের জন্য আরও উপযোগী, এবং Table Per Class Inheritance সহজ হলেও কিছু ক্ষেত্রে ডেটা পুনরাবৃত্তি হতে পারে।
JPA (Java Persistence API) ডেটাবেসের সাথে সম্পর্কিত অবজেক্ট-রিলেশনাল ম্যাপিং (ORM) এর একটি অংশ যা অবজেক্টের ক্লাস হায়ারার্কি (অর্থাৎ, ইনহেরিটেন্স) টেবিলের মধ্যে ম্যাপ করে। JPA-তে ক্লাস হায়ারার্কি পরিচালনার জন্য @Inheritance অ্যানোটেশন ব্যবহার করা হয় এবং এর মাধ্যমে একটি নির্দিষ্ট স্ট্র্যাটেজি নির্বাচন করা হয়। একাধিক ইনহেরিটেন্স স্ট্র্যাটেজি রয়েছে, তার মধ্যে একটি হলো Single Table Strategy।
Single Table Strategy কী?
Single Table Strategy (বা SINGLE_TABLE ইনহেরিটেন্স স্ট্র্যাটেজি) হলো একটি পদ্ধতি যেখানে বিভিন্ন শ্রেণীর (subclasses) ডেটা একটি একক টেবিল এ সঞ্চিত হয়। অর্থাৎ, পারেন্ট এবং সাবক্লাসের সকল ফিল্ড একটি একক টেবিলের মধ্যে থাকবে, এবং type discriminator column ব্যবহৃত হয় যাতে প্রতিটি রেকর্ড বুঝতে পারে যে এটি কোন ক্লাসের অবজেক্ট।
এটি সবচেয়ে সাধারণ এবং সহজ ইনহেরিটেন্স স্ট্র্যাটেজি, যেখানে সবকিছু একটি টেবিলে রাখা হয়। তবে, টেবিলটি বড় হয়ে যেতে পারে যদি অনেক সাবক্লাস এবং ক্ষেত্র থাকে, কারণ সমস্ত ক্ষেত্র একে অপরের সাথে শেয়ার করা হয়।
Single Table Strategy ব্যবহারের জন্য @Inheritance অ্যানোটেশন
JPA-তে @Inheritance(strategy = InheritanceType.SINGLE_TABLE) ব্যবহার করে ইনহেরিটেন্স হায়ারার্কি তৈরি করা হয় যেখানে সব ক্লাসের ডেটা একক টেবিলে রাখা হয়।
উদাহরণ: Single Table Strategy
ধরা যাক, আমাদের একটি প্যারেন্ট ক্লাস Vehicle এবং এর দুইটি সাবক্লাস Car এবং Truck রয়েছে। এই সমস্ত ডেটা একটি টেবিলে সঞ্চিত থাকবে।
Step 1: Entity Class তৈরি করা
Parent Class (Vehicle):
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // Single Table Strategy
@DiscriminatorColumn(name = "vehicle_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String make;
private String model;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
এখানে, @Inheritance(strategy = InheritanceType.SINGLE_TABLE) ব্যবহার করা হয়েছে, যার মাধ্যমে Vehicle ক্লাসের সব ডেটা একটিমাত্র টেবিলেই সঞ্চিত হবে। এছাড়াও, @DiscriminatorColumn ব্যবহার করে একটি discriminator column (vehicle_type) নির্ধারণ করা হয়েছে যা এই টেবিলের মধ্যে নির্ধারণ করবে কোন রেকর্ডটি Car বা Truck ক্লাসের অন্তর্ভুক্ত।
Child Class (Car):
import javax.persistence.*;
@Entity
@DiscriminatorValue("Car") // Discriminator value for the Car class
public class Car extends Vehicle {
private int doors;
// Getters and Setters
public int getDoors() {
return doors;
}
public void setDoors(int doors) {
this.doors = doors;
}
}
এখানে, @DiscriminatorValue("Car") ব্যবহার করে Car ক্লাসের জন্য একটি নির্দিষ্ট ডিসক্রিমিনেটর ভ্যালু (এক্ষেত্রে "Car") দেওয়া হয়েছে, যা Vehicle টেবিলের ডিসক্রিমিনেটর কলামে সঞ্চিত থাকবে।
Child Class (Truck):
import javax.persistence.*;
@Entity
@DiscriminatorValue("Truck") // Discriminator value for the Truck class
public class Truck extends Vehicle {
private double loadCapacity;
// Getters and Setters
public double getLoadCapacity() {
return loadCapacity;
}
public void setLoadCapacity(double loadCapacity) {
this.loadCapacity = loadCapacity;
}
}
এখানে, @DiscriminatorValue("Truck") ব্যবহার করে Truck ক্লাসের জন্য ডিসক্রিমিনেটর ভ্যালু "Truck" দেওয়া হয়েছে।
Step 2: Database Table Structure
এই কনফিগারেশনের মাধ্যমে JPA একটি একক টেবিল তৈরি করবে যা Vehicle ক্লাসের এবং তার সাবক্লাস Car এবং Truck ক্লাসের ডেটা সঞ্চিত রাখবে। টেবিলের কাঠামো হবে এমন:
| id | make | model | vehicle_type | doors | loadCapacity |
|---|---|---|---|---|---|
| 1 | Toyota | Corolla | Car | 4 | null |
| 2 | Ford | F-150 | Truck | null | 2000 |
এখানে:
- vehicle_type কলামটি ডিসক্রিমিনেটর হিসেবে কাজ করে যা নির্দেশ করে যে এটি
CarবাTruckক্লাসের ডেটা। doorsএবংloadCapacityফিল্ডগুলি শুধুমাত্র তাদের সংশ্লিষ্ট সাবক্লাসের জন্য প্রযোজ্য।
Step 3: EntityManager দিয়ে ডেটা সঞ্চয়
JPA ব্যবহার করে এই Entity গুলি সেভ করার সময়, আপনি একটি সাধারণ EntityManager ব্যবহার করতে পারেন। নিম্নলিখিত কোডে একটি উদাহরণ দেওয়া হল:
import javax.persistence.*;
public class VehicleTest {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJpaUnit");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// Creating and persisting a Car
Car car = new Car();
car.setMake("Toyota");
car.setModel("Corolla");
car.setDoors(4);
em.persist(car);
// Creating and persisting a Truck
Truck truck = new Truck();
truck.setMake("Ford");
truck.setModel("F-150");
truck.setLoadCapacity(2000);
em.persist(truck);
em.getTransaction().commit();
em.close();
emf.close();
}
}
এখানে, Car এবং Truck অবজেক্টগুলো Vehicle টেবিলের একক টেবিলে সেভ করা হবে, যেখানে vehicle_type ডিসক্রিমিনেটর কলামটি Car এবং Truck হিসাবে শনাক্ত করবে।
সারাংশ
Single Table Strategy (SINGLE_TABLE) JPA ইনহেরিটেন্স স্ট্র্যাটেজির একটি অংশ, যেখানে প্যারেন্ট এবং সাবক্লাসের ডেটা একটি একক টেবিলের মধ্যে রাখা হয়। এতে @Entity এবং @Inheritance(strategy = InheritanceType.SINGLE_TABLE) অ্যানোটেশন ব্যবহার করে ক্লাস হায়ারার্কি তৈরি করা হয় এবং @DiscriminatorColumn এবং @DiscriminatorValue ব্যবহার করে প্রতিটি সাবক্লাসের জন্য ডিসক্রিমিনেটর কলাম সংজ্ঞায়িত করা হয়। এটি ডেটাবেসের মধ্যে এক টেবিলে সব তথ্য সংরক্ষণ করে, যার ফলে পারফরম্যান্সে কিছুটা পার্থক্য হতে পারে তবে এটি সিম্পল এবং সহজ প্রয়োগযোগ্য।
JPA (Java Persistence API) এ Inheritance Mapping এর মাধ্যমে একটি Superclass এবং তার Subclass গুলির মধ্যে সম্পর্ক প্রতিষ্ঠিত হয়। JPA বিভিন্ন ধরনের ইনহেরিটেন্স স্ট্রাটেজি সমর্থন করে, যার মধ্যে অন্যতম Joined Strategy এবং Table-per-Class Strategy। এগুলি ডেটাবেসে ইনহেরিটেন্স সম্পর্কিত ডেটা কীভাবে সংরক্ষিত হবে তা নির্ধারণ করে।
1. Joined Strategy
Joined Strategy (বা Joined Table Inheritance) হল একটি ইনহেরিটেন্স স্ট্রাটেজি যেখানে সুপারক্লাসের জন্য একটি টেবিল এবং প্রতিটি সাবক্লাসের জন্য পৃথক টেবিল তৈরি হয়। তবে, এই টেবিলগুলির মধ্যে একটি সম্পর্ক থাকে, অর্থাৎ সাবক্লাসের টেবিল সুপারক্লাসের টেবিলের সাথে join করা হয়। প্রতিটি টেবিল শুধুমাত্র তার নিজস্ব ক্ষেত্রগুলো ধারণ করে, এবং সব টেবিলের মধ্যে একটি সাধারণ সম্পর্ক থাকে।
Joined Strategy এর বৈশিষ্ট্য:
- ডেটাবেসে সম্পর্ক: একটি সুপারক্লাস এবং তার সাবক্লাসের মধ্যে সম্পর্ক join করা হয়।
- ফিল্ডগুলির বিভাজন: প্রতিটি টেবিল শুধুমাত্র নিজস্ব ক্ষেত্রগুলি ধারণ করে এবং সুপারক্লাসের ফিল্ডগুলো আলাদা টেবিলের মধ্যে সংরক্ষিত থাকে।
- ডুপ্লিকেশন কমানো: সাধারণ ফিল্ডগুলো (যেমন সুপারক্লাসের) একাধিক সাবক্লাসের জন্য পুনরাবৃত্তি করা হয় না, বরং একটিতে সংরক্ষিত থাকে।
উদাহরণ:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getter and Setter
}
@Entity
public class Car extends Vehicle {
private String carModel;
// Getter and Setter
}
@Entity
public class Bike extends Vehicle {
private String bikeType;
// Getter and Setter
}
এখানে, Vehicle সুপারক্লাস এবং Car, Bike দুটি সাবক্লাস। @Inheritance(strategy = InheritanceType.JOINED) এর মাধ্যমে JPA-তে Joined Strategy ব্যবহার করা হয়েছে।
ডেটাবেস টেবিলের গঠন:
Vehicle Table:
id name 1 Car 2 Bike Car Table:
id carModel 1 Sedan Bike Table:
id bikeType 2 Mountain
এখানে, Vehicle টেবিলের id ফিল্ডটি Car এবং Bike টেবিলের সাথে যুক্ত, এবং তারা নির্দিষ্ট ডেটা সংরক্ষণ করে।
2. Table-per-Class Strategy
Table-per-Class Strategy হল এমন একটি ইনহেরিটেন্স স্ট্রাটেজি যেখানে প্রতি ক্লাস (সুপারক্লাস এবং সাবক্লাস) এর জন্য আলাদা আলাদা টেবিল তৈরি করা হয়, এবং প্রতিটি টেবিল তার নিজস্ব ক্ষেত্রগুলো ধারণ করে। এতে কোনো join অপারেশন প্রয়োজন হয় না, কারণ প্রতিটি ক্লাসের ডেটা তার নিজস্ব টেবিলে সংরক্ষিত থাকে।
Table-per-Class Strategy এর বৈশিষ্ট্য:
- পৃথক টেবিল: সুপারক্লাস এবং সাবক্লাসের জন্য আলাদা টেবিল তৈরি করা হয়।
- ডেটাবেসে ডুপ্লিকেশন: সাবক্লাসের ক্ষেত্রগুলি সুপারক্লাসের ক্ষেত্রের সাথে মিশে থাকতে পারে, যার ফলে কিছু ডুপ্লিকেশন হতে পারে।
- কোনো Join নেই: কোনো
joinটেবিলের মধ্যে করা হয় না, যা ডেটা অ্যাক্সেসে আরও দ্রুততা আনে।
উদাহরণ:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getter and Setter
}
@Entity
public class Car extends Vehicle {
private String carModel;
// Getter and Setter
}
@Entity
public class Bike extends Vehicle {
private String bikeType;
// Getter and Setter
}
এখানে, @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) দ্বারা Table-per-Class Strategy ব্যবহার করা হয়েছে।
ডেটাবেস টেবিলের গঠন:
Vehicle Table:
id name 1 Car 2 Bike Car Table:
id name carModel 1 Car Sedan Bike Table:
id name bikeType 2 Bike Mountain
এখানে, প্রতিটি টেবিল তার নিজস্ব ক্ষেত্র ধারণ করে এবং Vehicle টেবিলের ক্ষেত্র গুলি Car এবং Bike টেবিলের মধ্যে পুনরাবৃত্তি করা হচ্ছে।
Joined Strategy এবং Table-per-Class Strategy এর মধ্যে পার্থক্য
| বৈশিষ্ট্য | Joined Strategy | Table-per-Class Strategy |
|---|---|---|
| টেবিলের সংখ্যা | একাধিক টেবিল (সুপারক্লাস এবং সাবক্লাসের জন্য আলাদা টেবিল) | প্রতিটি ক্লাসের জন্য আলাদা টেবিল |
| ডেটাবেসে সম্পর্ক | টেবিলগুলোর মধ্যে join সম্পর্ক থাকে | কোনো join সম্পর্ক নেই, প্রতিটি টেবিল সম্পূর্ণ স্বাধীন |
| ফিল্ড ডুপ্লিকেশন | ডুপ্লিকেশন কম থাকে কারণ সুপারক্লাসের ক্ষেত্রগুলো একটি টেবিলে থাকে | সাবক্লাসের ক্ষেত্রগুলি সুপারক্লাসের ক্ষেত্রের সাথে মিশে যায় |
| পারফরম্যান্স | join অপারেশন কারণে কিছু পারফরম্যান্স হিট হতে পারে | কোনো join নেই, তাই পারফরম্যান্স ভাল |
| ডেটা পুনঃব্যবহার | ডেটা পুনঃব্যবহার সহজ, কারণ সাধারণ ফিল্ডগুলো একটি টেবিলে থাকে | প্রতিটি ক্লাসের জন্য আলাদা টেবিল হওয়ায় কিছু ডেটা পুনঃব্যবহার সম্ভব না |
| ডেটা রক্ষণাবেক্ষণ | ডেটা রক্ষণাবেক্ষণ সহজ, কারণ একাধিক টেবিলের মধ্যে সম্পর্ক থাকে | ডেটা রক্ষণাবেক্ষণ কঠিন হতে পারে, কারণ আলাদা টেবিল ব্যবহার হয় |
সারাংশ
- Joined Strategy হল এমন একটি পদ্ধতি যেখানে সুপারক্লাস এবং সাবক্লাসের জন্য আলাদা টেবিল তৈরি করা হয় এবং এগুলোর মধ্যে সম্পর্ক join করা হয়। এতে ডেটা পুনঃব্যবহার সহজ হয়, তবে কিছু পারফরম্যান্স সমস্যা থাকতে পারে।
- Table-per-Class Strategy হল একটি পদ্ধতি যেখানে প্রতিটি ক্লাসের জন্য আলাদা টেবিল তৈরি করা হয়। এতে পারফরম্যান্স ভালো হয়, তবে কিছু ডেটা পুনঃব্যবহার করা কঠিন হতে পারে এবং ডেটাবেসে কিছু ডুপ্লিকেশন হতে পারে।
JPA তে ইনহেরিটেন্স মডেল নির্বাচন করার সময় এই দুটি স্ট্রাটেজি নির্বাচন করতে পারেন, যেটি আপনার অ্যাপ্লিকেশনের পারফরম্যান্স এবং ডেটা রক্ষণাবেক্ষণের প্রয়োজনীয়তার উপর নির্ভর করে।
JPA (Java Persistence API) তে Inheritance একটি মৌলিক ধারণা, যেখানে একটি শ্রেণী (class) অন্য শ্রেণী (class) থেকে বৈশিষ্ট্য এবং আচরণ (properties and behaviors) উত্তরাধিকারী হয়। জেভিএইচ (JPA) এ ইনহেরিটেন্স সম্পর্কিত তিনটি মূল কৌশল বা স্ট্রাটেজি রয়েছে:
- Joined Strategy
- Table-per-Class Strategy
- Single Table Strategy
এই তিনটি স্ট্র্যাটেজি জাভা অবজেক্টের ইনহেরিটেন্স মডেল ডেটাবেসে ম্যাপ করার জন্য ব্যবহৃত হয়।
এই উদাহরণে, আমরা Inheritance in JPA এর জন্য Joined Strategy এবং Table-per-Class Strategy এর মাধ্যমে একটি বাস্তব প্রয়োগ (Practical Example) দেখবো।
1. Joined Strategy
Joined Strategy তে প্রতি সাবক্লাসের জন্য আলাদা টেবিল তৈরি করা হয় এবং সব টেবিলের মধ্যে একটি সম্পর্ক (JOIN) প্রতিষ্ঠিত থাকে। এই স্ট্র্যাটেজি ডেটাবেসে normalized কাঠামো তৈরি করে, যেখানে মূল ক্লাসের টেবিল এবং সাবক্লাসের টেবিল পৃথকভাবে থাকে, কিন্তু তাদের মধ্যে সম্পর্ক থাকে।
Joined Strategy উদাহরণ:
ধরা যাক, আমাদের একটি Person ক্লাস আছে এবং এর দুটি সাবক্লাস Employee এবং Customer আছে।
Step 1: Entity Classes
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Getter and Setter methods
}
@Entity
public class Employee extends Person {
private String department;
// Getter and Setter methods
}
@Entity
public class Customer extends Person {
private String membershipLevel;
// Getter and Setter methods
}
এখানে, @Inheritance(strategy = InheritanceType.JOINED) অ্যানোটেশন ব্যবহার করা হয়েছে, যা Joined Strategy এর মাধ্যমে ইনহেরিটেন্স মডেল নির্ধারণ করে।
Step 2: Database Schema
Person টেবিল:
id name email 1 John john@example.com Employee টেবিল:
id department 1 HR Customer টেবিল:
id membershipLevel 2 Silver
এখানে, Employee এবং Customer টেবিল শুধুমাত্র তাদের নিজস্ব specific তথ্য ধারণ করে এবং Person টেবিলের id, name, এবং email ফিল্ডগুলির সাথে যুক্ত থাকে।
2. Table-per-Class Strategy
Table-per-Class Strategy তে প্রতিটি সাবক্লাসের জন্য একটি আলাদা টেবিল তৈরি হয় এবং এতে ক্লাসের সকল ফিল্ড (superclass এবং subclass) থাকে। এখানে JOIN এর কোনো প্রয়োজন হয় না, কারণ প্রতিটি ক্লাসের জন্য সম্পূর্ণ তথ্য তার নিজস্ব টেবিলেই থাকে।
Table-per-Class Strategy উদাহরণ:
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Getter and Setter methods
}
@Entity
public class Employee extends Person {
private String department;
// Getter and Setter methods
}
@Entity
public class Customer extends Person {
private String membershipLevel;
// Getter and Setter methods
}
এখানে, @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) অ্যানোটেশন ব্যবহার করা হয়েছে, যা Table-per-Class Strategy কে নির্দেশ করে।
Step 2: Database Schema
Person টেবিল:
id name email 1 John john@example.com Employee টেবিল:
id name email department 1 John john@example.com HR Customer টেবিল:
id name email membershipLevel 2 Alice alice@example.com Silver
এখানে, Person টেবিলের ডেটা Employee এবং Customer টেবিলেও ডুপ্লিকেট থাকে, কারণ প্রতিটি টেবিলের সব ফিল্ড (superclass + subclass) আলাদা টেবিলে রয়েছে।
পার্থক্য - Joined Strategy এবং Table-per-Class Strategy
| বৈশিষ্ট্য | Joined Strategy | Table-per-Class Strategy |
|---|---|---|
| টেবিল সংখ্যা | তিনটি টেবিল, একটি superclass এবং দুটি subclass টেবিল | প্রতিটি ক্লাসের জন্য আলাদা একটি টেবিল |
| ডেটা ডুপ্লিকেশন | কম, কারণ শুধুমাত্র subclass specific ডেটা টেবিলে থাকে | বেশি, কারণ superclass এবং subclass ডেটা আলাদা টেবিলে থাকে |
| পারফরম্যান্স | কিছুটা ধীর, কারণ JOIN অপারেশন প্রয়োজন | দ্রুত, কারণ ডেটা আলাদা টেবিলে থাকে এবং JOIN এর প্রয়োজন হয় না |
| নরমালাইজেশন | অধিক নরমালাইজড | কম নরমালাইজড |
| ডেটাবেসের স্টোরেজ | কম স্টোরেজ প্রয়োজন (শেয়ারড তথ্য) | বেশি স্টোরেজ প্রয়োজন (ডুপ্লিকেট ডেটা) |
| কোডিং সহজতা | সাবলীল, তবে JOIN প্রয়োজন | সহজ, কারণ ডেটা আলাদা টেবিলে থাকে |
সারাংশ
JPA Inheritance ব্যবহারে দুটি প্রধান স্ট্র্যাটেজি হল Joined Strategy এবং Table-per-Class Strategy। Joined Strategy ডেটাবেসে অবজেক্টর মধ্যে সম্পর্ক স্থাপন করে (JOIN), যেখানে ডেটা নরমালাইজড থাকে, কিন্তু পারফরম্যান্স কিছুটা কম হতে পারে। Table-per-Class Strategy সব ডেটা আলাদা টেবিলে রাখে, যার ফলে পারফরম্যান্স উন্নত হয়, তবে ডেটার ডুপ্লিকেশন এবং স্টোরেজের সমস্যা হতে পারে। আপনার প্রজেক্টের প্রয়োজন অনুযায়ী আপনি যে কোনো স্ট্র্যাটেজি নির্বাচন করতে পারেন।
Read more