[英]Is using id field in @AllArgsConstructor while using Spring JPA correct?
使用spring-boot
和 JPA 我有一個Entity
,我想使用 lombok 來減少樣板代碼。 但是在我的實體中有id
字段。 我應該把它放在帶有@AllArgsConstructor
的構造函數 arguments 中,還是應該將它從參數列表中刪除(不知何故,如何?),因為它是使用@id
和@GeneratedValue
注釋自動生成的?
代碼:
@Entity
@NoArgsConstructor // JPA requires empty constructor
@AllArgsConstructor // ? is id in constuctor needed?
@Getter
@Setter
@ToString(exclude = {"room", "customer"})
public class Reservation {
@Id
@GeneratedValue
private long id;
private Room room;
private Customer customer;
private Date dateFrom;
private Date dateTo;
}
對於您在代碼中的問題:
@AllArgsConstructor // ? 需要構造函數中的 id 嗎?
不,不需要。 此外,對於您在標題中的問題:
使用 Spring JPA 時在@AllArgsConstructor 中使用 id 字段是否正確?
除非有很好的理由,否則不建議將字段id
暴露給任何構造函數或 setter。 字段id
應僅由 JPA 實現操作。
請注意,當您在Reservation
類級別聲明@Setter
時,也會發生此公開。
這可以避免從類級別刪除注釋並注釋每個字段以公開但更簡單的方法是使用繼承。
您可以創建一個基類,如:
@Entity
@Getter
// Choose your inheritance strategy:
//@Inheritance(strategy=InheritanceType.JOINED)
//@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity {
@Id
@GeneratedValue
private Long id;
}
請注意,它沒有字段id
設置器。 擴展上面的類,如:
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString(exclude = {"room", "customer"})
public class Reservation extends BaseEntity {
private Room room;
private Customer customer;
private Date dateFrom;
private Date dateTo;
}
構造函數和設置器將如下所示:
Reservation r1 = new Reservation();
Reservation r2 = new Reservation(room, customer, dateFrom, dateTo);
r1.setRoom(room);
r1.setCustomer(customer);
r1.setDateFrom(dateFrom);
r1.setDateTo(dateTo);
並且沒有辦法 - 除了 JPA 使用的反射 - 來設置字段id
。
我不知道spring-data-jpa究竟是如何設置id
但由於有一個關鍵字 JPA 和標簽jpa,我認為這是一個 JPA 東西,實際上根本不需要字段id
設置器。
在這種情況下, spring-data
使用 setter 來設置值,因此@AllArgsConstructor
。
Lombok 部分的注釋:無法從@AllArgsConstructor
排除字段(不使用繼承)。 對於有限的構造函數,您只能使用@RequiredArgsConstructor
,但這通常對 JPA 實體沒有幫助。
我的解決方案是當 id 由 jpa 自動生成並且您使用 lombok 來避免樣板代碼時。
@Entity
@Getter
@Setter
@ToString
@RequiredArgsConstructor
@AllArgsConstructor
public class Patient {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long reg;
@NotNull
private String name;
@NotNull
private String gender;
@NotNull
private String specimen;
@NotNull
private String contact;
@NotNull
private String cnic;
@NotNull
private String referred_by;
public Patient(String name, String gender, String specimen, String contact, String cnic, String referred_by) {
this.name = name;
this.gender = gender;
this.specimen = specimen;
this.contact = contact;
this.cnic = cnic;
this.referred_by = referred_by;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
Patient patient = (Patient) o;
return reg != null && Objects.equals(reg, patient.reg);
}
@Override
public int hashCode() {
return getClass().hashCode();
}
}
只需使用不包括 id 字段的自定義構造函數即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.