JPA 映射(OneToMany、ManyToOne)

问题描述 投票:0回答:1

销售类

@Entity
@Table(name = "sale")
@AllArgsConstructor
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@Data
public class Sale {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;
    @Column(name = "sale_price")
    BigDecimal salePrice;
    @Column(name = "sale_time")
    LocalDateTime saleTime;
    @OneToMany(mappedBy = "sale", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    List<SaleItem> saleItems;
}

销售商品类


@Entity
@Table(name = "sale_item")
@AllArgsConstructor
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@Data
public class SaleItem {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;
    @ManyToOne
    @JoinColumn(name = "product_id", referencedColumnName = "id")
    Product product;
    int quantity;
    BigDecimal price;
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "sale_id", referencedColumnName = "id")
    Sale sale;
}

从 sale_item 表中删除 saleItem

Sale sale=repo.findById(saleId).
orElseThrow(()->new NoSuchElementException("There is no sale with the id"));
SaleItem theSaleItem=sale.getSaleItems().stream().filter
(saleItem->saleItem.getProduct().getBarcode().equals(barcode)).findFirst().get();
saleItemRepo.delete(theSaleItem);

SQL 代码

Hibernate: select si1_0.id,si1_0.price,p1_0.id,p1_0.barcode,p1_0.category,p1_0.price,p1_0.name,p1_0.quantity,si1_0.quantity,s1_0.id,s1_0.sale_price,s1_0.sale_time from sale_item si1_0 left join product p1_0 on p1_0.id=si1_0.product_id left join sale s1_0 on s1_0.id=si1_0.sale_id where si1_0.id=?
Hibernate: select si1_0.sale_id,si1_0.id,si1_0.price,p1_0.id,p1_0.barcode,p1_0.category,p1_0.price,p1_0.name,p1_0.quantity,si1_0.quantity from sale_item si1_0 left join product p1_0 on p1_0.id=si1_0.product_id where si1_0.sale_id=?
Hibernate: select si1_0.id,si1_0.price,p1_0.id,p1_0.barcode,p1_0.category,p1_0.price,p1_0.name,p1_0.quantity,si1_0.quantity,s1_0.id,s1_0.sale_price,s1_0.sale_time from sale_item si1_0 left join product p1_0 on p1_0.id=si1_0.product_id left join sale s1_0 on s1_0.id=si1_0.sale_id where si1_0.id=?
Hibernate: select si1_0.sale_id,si1_0.id,si1_0.price,p1_0.id,p1_0.barcode,p1_0.category,p1_0.price,p1_0.name,p1_0.quantity,si1_0.quantity from sale_item si1_0 left join product p1_0 on p1_0.id=si1_0.product_id where si1_0.sale_id=?
Hibernate: delete from sale_item where id=?
Hibernate: delete from sale_item where id=?
Hibernate: delete from sale_item where id=?
Hibernate: delete from sale_item where id=?
Hibernate: delete from sale where id=?

如您所见,我有“sale”和“sale_item”表 映射中的级联类型“ALL” 当我保存销售时,它会根据我的需要保存 sale_items 但是当我想删除特定的 sale_item 时,它会删除具有相同 sale_id 和相关 sale 的所有 saleItems 例如,在 sale 表中,我有一个 id = 2 的销售,在 sale_item 表中,我有 3 个 saleItems,id 分别为 1,2,3。当我删除 id = 1 的 saleItem 时,它会自动删除 id 为 2 的“sale”表中的所有 saleItems (1,2,3) 和 sale。

spring-boot jpa spring-data-jpa mapping cascade
1个回答
0
投票

SaleItem

 实体中使用的 
CascadeType.ALL 意味着与 SaleItem 关联的所有操作都会受到影响。当您使用删除操作时,会导致删除具有相同 sale_id 的每个 SaleItem

去掉

SaleItem实体中sale的级联,表示在不指定任何级联类型的情况下,在执行操作时不会对关联实体应用级联操作。

你应该改变:

@ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "sale_id", referencedColumnName = "id") Sale sale;
至:

@ManyToOne @JoinColumn(name = "sale_id", referencedColumnName = "id") Sale sale;
    
© www.soinside.com 2019 - 2024. All rights reserved.