[英]Hibernate association mapping
I am working on a bike rental system project.我正在从事自行车租赁系统项目。 I am able to do CRUD operations via Rest API on Bike, and Customer and create a Contract object.
我可以通过 Bike 和 Customer 上的 Rest API 执行 CRUD 操作,并创建一个 Contract 对象。 For this, I have exposed CRUD endpoints(s) for
为此,我公开了 CRUD 端点
The POST /contract/final endpoint should return a complete contract overview with contractid, bike details, and customer POST /contract/final 端点应返回完整的合同概览,其中包含合同 ID、自行车详细信息和客户
The association I am using is as below我正在使用的协会如下
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;
}
So I just want to be able to create/modify the bike|customer records and create a contract with the already created customer(s) and bike(s).所以我只想能够创建/修改自行车|客户记录并与已经创建的客户和自行车创建合同。
As of now, the contract request will create the customer and bike records apart from records created separately using /customer, /bike endpoints - which I do not want.截至目前,合同请求将创建客户和自行车记录,而不是使用 /customer、/bike 端点单独创建的记录——这是我不想要的。
Is the association mapping I have used correct for this requirement?我使用的关联映射是否符合此要求? What should ideally be the relationship between these entities given the below contraints?
考虑到以下限制,理想情况下这些实体之间的关系应该是什么?
One customer can have many contracts but one contract will have only one customer一个客户可以有多个合同,但一个合同将只有一个客户
One bike can have many contracts but one contract will have only one bike一辆自行车可以有很多合同,但一份合同只能有一辆自行车
How can I make use of the existing customer/bike records while creating a contract?在创建合同时如何使用现有的客户/自行车记录?
Do you want to have the ability to change a Bike
model when you create a new Contract
?您是否希望在创建新
Contract
时能够更改Bike
型号? Obviously no!显然不是!
cascade = CascadeType.ALL
is about such changes. cascade = CascadeType.ALL
就是关于这样的变化。 So throw it away.所以扔掉它。
Do you want to load all the Contract
data, like a Bike
, when you load a Contract
?你想在加载
Contract
时加载所有Contract
数据,比如Bike
吗? It is not so obvious, but my advice don't do this!这不是很明显,但我的建议是不要这样做! Let's change
fetch=FetchType.EAGER
to fetch=FetchType.LAZY
.让我们将
fetch=FetchType.EAGER
更改为fetch=FetchType.LAZY
。
You use two strategies to generate an id
— strategy= GenerationType.SEQUENCE
, strategy = GenerationType.IDENTITY
.您使用两种策略来生成
id
— strategy= GenerationType.SEQUENCE
, strategy = GenerationType.IDENTITY
。 Use only one.只使用一个。
Don't use a primitive type for an id
.不要对
id
使用原始类型。 Change long bikeId
to Long bikeId
.将
long bikeId
更改为Long bikeId
。
@JoinColumn
specifies a database column name, not a class property. @JoinColumn
指定数据库列名,而不是类属性。 Change @JoinColumn(name="customerId")
to @JoinColumn(name="CUSTOMER_ID")
. @JoinColumn(name="customerId")
更改为@JoinColumn(name="CUSTOMER_ID")
。 Use uppercase for column names.对列名使用大写字母。
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;
}
Assign existing Bike
and Customer
to the Contract
, using getReferenceById()
method.使用
getReferenceById()
方法将现有的Bike
和Customer
分配给Contract
。 It doesn't hit a database at all.它根本不会访问数据库。
Customer customer = customerRepository.getReferenceById(customerId);
contract.setCustomer(customer);
Another way is to use a transient customer.另一种方法是使用临时客户。
Customer customer = new Customer();
customer.setId(customerId);
contract.setCustomer(customer);
But standard repository save()
method uses merge()
.但是标准存储库
save()
方法使用merge()
。 So it will be an additional SQL request to load a customer.因此加载客户将是一个额外的 SQL 请求。 You can use custom repository with pure
save()
method to avoid this https://vladmihalcea.com/best-spring-data-jparepository/您可以使用带有纯
save()
方法的自定义存储库来避免这种情况https://vladmihalcea.com/best-spring-data-jparepository/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.