簡體   English   中英

在使用 Spring JPA 時在 @AllArgsConstructor 中使用 id 字段是否正確?

[英]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

我不知道究竟是如何設置id但由於有一個關鍵字 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM