I have two tables Restaurant and FoodItems.
My requirement:
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.