首页 > 解决方案 > 如何防止仅在休眠中的子表中进行更新操作(一对多映射单向)?

问题描述

我有两张桌子 Restaurant 和 FoodItems。

我的要求:

  1. 如果我添加了餐厅数据,则需要添加 FoodItems 数据。
  2. 如果我删除了餐厅数据,则需要删除 FoodItems 数据。
  3. 如果我更新了餐厅数据,则不需要更新 FoodItems 数据。

面临
的问题:当我更新餐厅详细信息时,fooditems 数据也会更新。

重现步骤:
我使用邮递员工具将 JSON 数据发送到 java 端。
JSON:

{“restaurantId”:1,“restaurantName”:“Salem RRR”,“restaurantAddress”:“omr,chennai”}

我没有在 JSON 中传递 foodItems。当我在 java 端直接调用 session.update(restaurant) 时,会删除 fooditems 数据。
我知道这是因为餐厅餐桌上的 cascade = CascadeType.ALL 选项。

我的查询:
但我不知道如何阻止更新操作。我是新来的冬眠。请帮助我们摆脱这个问题。提前致谢

餐厅.java

@Getter
@Setter
@Entity
@Table(name = "restaurant")
public class Restaurant {

    @Column(name = "restaurant_id")
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int restaurantId;

    @Column(name = "restaurant_name",nullable = false)
    private String restaurantName;

    @Column(name = "restaurant_address",nullable = false)
    private String restaurantAddress;

    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinTable(name = "restaurant_fooditems",
    joinColumns = {@JoinColumn(name="restaurant_id",referencedColumnName = "restaurant_id")},
    inverseJoinColumns = {@JoinColumn(name="food_id",referencedColumnName = "food_id")})
    private Set<FoodItems> foodItems;

}

FoodItems.java

@Getter
@Setter
@Entity
@Table(name = "fooditems")
public class FoodItems {

    @Column(name = "food_id")
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int foodId;

    @Column(name = "food_name",nullable = false)
    private String productName;

    @Column(name = "price",nullable = false)
    private double price;

}

标签: javahibernatespring-data-jpahibernate-mappingnhibernate-mapping

解决方案


我知道这是因为餐厅餐桌上的 cascade = CascadeType.ALL 选项。

嗯,不完全是。这是因为Restaurant是自身与FoodItems 之间关联的所有者。这意味着关联状态由Restaurant.foodItems属性控制。

假设您只是restaurantRepository.save(restaurant)在您的服务方法中调用,那么如果Restaurant.foodItems为空,foodItem则假定所有以前的 s 都从关联中删除。即使没有CascadeType.ALL.

最简单的解决方案是从数据存储中加载原始Restaurant文件,并且只复制您想要更新的字段——比如:

@Transactional
public void update(Restaurant updated) {
    restaurantRepository.findById(updated.getId())
        .ifPresent(original -> {
            original.setRestaurantName(updated.getRestaurantName());
            original.setRestaurantAddress(updated.getRestaurantAddress());
        });
}

推荐阅读