繁体   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