برنامه نویسی
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
توابع موجودیت درست در بوت بهار + خواب زمستانی محیط 🚀