简体   繁体   中英

How to prevent update operation only in child table in hibernate (one-to-many mapping unidirectional)?

I have two tables Restaurant and FoodItems.

My requirement:

  1. If I added Restaurant data, then FoodItems data need to be added.
  2. If I deleted Restaurant data, then FoodItems data need to be deleted.
  3. If I updated Restaurant data, then FoodItems data need not to be updated.

Problems faced:
When I updated the restaurant details, then fooditems data is also updated.

Steps to reproduce :
I use postman tool to send JSON data to java side.
JSON :

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

I don't pass the foodItems in the JSON. When I directly call session.update(restaurant) in java side, then fooditems data is deleted.
I know it is because of cascade = CascadeType.ALL option in restaurant table.

My Query :
But I don't know how to prevent the update operation. I am new to hibernate. please help us to get rid of this problem. Thanks in advance

Restaurant.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;

}

I know it is because of cascade = CascadeType.ALL option in restaurant table.

Well, not exactly. It's because Restaurant is the owner of the association between itself and the FoodItem s. This means the association state is controlled by the Restaurant.foodItems property.

Assuming that you are simply calling restaurantRepository.save(restaurant) in your service method, then if Restaurant.foodItems is empty, all previous foodItem s are assumed to be removed from the association. The problem will persist even without CascadeType.ALL .

The simplest solution would be to load the original Restaurant from the data store, and only copy over the fields you want updated - sth like:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM