![](/img/trans.png)
[英]How to filter association entities across a mapping table using Spring Data JPA(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 端點單獨創建的記錄——這是我不想要的。
我使用的關聯映射是否符合此要求? 考慮到以下限制,理想情況下這些實體之間的關系應該是什么?
一個客戶可以有多個合同,但一個合同將只有一個客戶
一輛自行車可以有很多合同,但一份合同只能有一輛自行車
在創建合同時如何使用現有的客戶/自行車記錄?
您是否希望在創建新Contract
時能夠更改Bike
型號? 顯然不是! cascade = CascadeType.ALL
就是關於這樣的變化。 所以扔掉它。
你想在加載Contract
時加載所有Contract
數據,比如Bike
嗎? 這不是很明顯,但我的建議是不要這樣做! 讓我們將fetch=FetchType.EAGER
更改為fetch=FetchType.LAZY
。
您使用兩種策略來生成id
— strategy= GenerationType.SEQUENCE
, strategy = GenerationType.IDENTITY
。 只使用一個。
不要對id
使用原始類型。 將long bikeId
更改為Long bikeId
。
@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()
方法將現有的Bike
和Customer
分配給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.