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