簡體   English   中英

Hibernate 關聯映射

[英]Hibernate association mapping

我正在從事自行車租賃系統項目。 我可以通過 Bike 和 Customer 上的 Rest API 執行 CRUD 操作,並創建一個 Contract 對象。 為此,我公開了 CRUD 端點

  • /自行車
  • /顧客
  • /合同

POST /contract/final 端點應返回完整的合同概覽,其中包含合同 ID、自行車詳細信息和客戶

我正在使用的協會如下

class Contract {

@Id
@GeneratedValue(strategy= GenerationType.SEQUENCE)
private id;
@ManyToOne(fetch=FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name="customerId")
private Customer customer;
@ManyToOne(fetch=FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name="bikeId")
private Bike bike; 
}

class Customer{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "customer_id")
private Long customerId;
private String firstName;
}

class Bike{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "bike_id")
private long bikeId;
private String model;
}

所以我只想能夠創建/修改自行車|客戶記錄並與已經創建的客戶和自行車創建合同。

截至目前,合同請求將創建客戶和自行車記錄,而不是使用 /customer、/bike 端點單獨創建的記錄——這是我不想要的。

我使用的關聯映射是否符合此要求? 考慮到以下限制,理想情況下這些實體之間的關系應該是什么?

  • 一個客戶可以有多個合同,但一個合同將只有一個客戶

  • 一輛自行車可以有很多合同,但一份合同只能有一輛自行車

    在創建合同時如何使用現有的客戶/自行車記錄?

  1. 您是否希望在創建新Contract時能夠更改Bike型號? 顯然不是! cascade = CascadeType.ALL就是關於這樣的變化。 所以扔掉它。

  2. 你想在加載Contract時加載所有Contract數據,比如Bike嗎? 這不是很明顯,但我的建議是不要這樣做! 讓我們將fetch=FetchType.EAGER更改為fetch=FetchType.LAZY

  3. 您使用兩種策略來生成idstrategy= GenerationType.SEQUENCEstrategy = GenerationType.IDENTITY 只使用一個。

  4. 不要對id使用原始類型。 long bikeId更改為Long bikeId

  5. @JoinColumn指定數據庫列名,而不是類屬性。 @JoinColumn(name="customerId")更改為@JoinColumn(name="CUSTOMER_ID") 對列名使用大寫字母。

class Contract {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CUSTOMER_ID")
    private Customer customer;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "BIKE_ID")
    private Bike bike;
    
}

使用getReferenceById()方法將現有的BikeCustomer分配給Contract 它根本不會訪問數據庫。

Customer customer = customerRepository.getReferenceById(customerId);
contract.setCustomer(customer);

另一種方法是使用臨時客戶。

Customer customer = new Customer();
customer.setId(customerId);
contract.setCustomer(customer);

但是標准存儲庫save()方法使用merge() 因此加載客戶將是一個額外的 SQL 請求。 您可以使用帶有純save()方法的自定義存儲庫來避免這種情況https://vladmihalcea.com/best-spring-data-jparepository/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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