برنامه نویسی
Hibernate-004: PaideId.Class

PaymentId کلاس (بهترین شیوه ها)
import java.io.Serializable;
import java.util.Objects;
public class PaymentId implements Serializable {
private Integer customer; // Must match the type of Payment.customer (Customer's ID)
private String checkNumber;
// Default constructor (required by JPA)
public PaymentId() {}
// Parameterized constructor for convenience
public PaymentId(Integer customer, String checkNumber) {
this.customer = customer;
this.checkNumber = checkNumber;
}
// Getters and Setters (JPA needs these)
public Integer getCustomer() { return customer; }
public void setCustomer(Integer customer) { this.customer = customer; }
public String getCheckNumber() { return checkNumber; }
public void setCheckNumber(String checkNumber) { this.checkNumber = checkNumber; }
// Override equals() to compare objects logically
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PaymentId that = (PaymentId) o;
return Objects.equals(customer, that.customer) &&
Objects.equals(checkNumber, that.checkNumber);
}
// Override hashCode() to ensure correct behavior in HashMap, HashSet, etc.
@Override
public int hashCode() {
return Objects.hash(customer, checkNumber);
}
}
توضیح دقیق
1. چرا Serializable؟
- در
PaymentIdطبقه باید اجراSerializable، همانطور که JPA هنگام استفاده از کلیدهای اولیه از سریال سازی داخلی استفاده می کند@IdClassبشر - بدون
Serializable، JPA ممکن است در زمان اجرا شکست بخورد.
2. چرا یک سازنده بدون ARG؟
- JPA مستلزم یک سازنده بدون آریش برای فوری موجودیت.
- اگر به صراحت تعریف نشده باشد ، JPA ممکن است هنگام بازیابی موجودات خطا کند.
3. چرا گیرنده ها و تنظیم کننده ها؟
- هر چند
@IdClassاز کار نه به صراحت به گیرنده ها و تنظیم کننده ها نیاز دارید ، این بهترین عمل است زیرا:- برخی از چارچوب ها (به عنوان مثال ، خواب زمستانی) ممکن است آنها را برای پروکسی ها نیاز داشته باشند.
- این سازگاری با کنوانسیون های Javabeans را تضمین می کند.
4. چرا نادیده گرفتن equals() وت hashCode()؟
- این روشها از مقایسه مناسب برابری شیء اطمینان حاصل می کنند ، که در مواردی بسیار مهم است:
- ذخیره اشیا در a
Set(از کلیدهای تکراری خودداری کنید). - موجودات با کلیدهای کامپوزیت.
- جلوگیری از ناسازگاری هنگام مدیریت روابط موجودیت.
- ذخیره اشیا در a
چگونه JPA استفاده می کند PaymentId
-
هنگام ایجاد
Paymentموجودیت، JPA بررسی می کند که آیا یک موجود با همانPaymentIdقبلاً قبل از وارد کردن یک مورد جدید وجود دارد. -
هنگام واکشی a
Paymentموجودیت، JPA کلید را با استفاده از بازسازی می کندPaymentIdو ورودی صحیح را بازیابی می کند. -
هنگام حذف a
Paymentموجودیت، JPA استفاده می کندPaymentIdبرای یافتن رکورد
مثال: استفاده از PaymentId برای یافتن یک موجود
@EntityManager entityManager = ...;
PaymentId paymentId = new PaymentId(103, "CHK123456"); // Composite Key
Payment payment = entityManager.find(Payment.class, paymentId);
- اینجا ، JPA بطور خودکار نقشه ها
customerوتcheckNumberزمینه ها ازPaymentIdبه مربوطه@Idمزارع درPaymentبشر
رویکرد جایگزین: @EmbeddedId
راه دیگر برای تعریف کلید کامپوزیت استفاده است @EmbeddedId، که کلید اصلی را در داخل موجودیت جاسازی می کند.
با @EmbeddedId:
@Embeddable
public class PaymentId implements Serializable {
@ManyToOne
@JoinColumn(name = "customerNumber")
private Customer customer;
@Column(name = "checkNumber", length = 50)
private String checkNumber;
// Constructors, equals(), hashCode(), Getters, and Setters
}
سپس ، اصلاح کنید Payment موجودیت:
@Entity
@Table(name = "payments")
public class Payment {
@EmbeddedId
private PaymentId id;
}
-
تفاوت کلیدی:
@EmbeddedIdبا کلید به عنوان یک رفتار می کند اعتراض به جای زمینه های جداگانه در موجودیت.
افکار نهایی
- همیشه نادیده گرفتن
equals()وتhashCode()برای اطمینان از اینکه مقایسه های موجودیت به درستی کار می کنند. - در نظر گرفتن
@EmbeddedIdاگر ترجیح می دهید به جای زمینه های جداگانه در موجودیت ، کلید کامپوزیت را به عنوان یک شیء درمان کنید.
این شما را تضمین می کند Payment توابع موجودیت درست در بوت بهار + خواب زمستانی محیط 🚀



