JpaRepository 中的 delete 方法从 DB 表中删除所有行
Posted
技术标签:
【中文标题】JpaRepository 中的 delete 方法从 DB 表中删除所有行【英文标题】:The delete method from JpaRepository deletes all rows from the DB table 【发布时间】:2020-09-04 14:21:19 【问题描述】:我有一个Admin
类,可以通过id
从数据库中删除cooks
。当我使用 void deleteByUserRoleAndId(String role, Long id)
方法时;它从数据库中删除所有列,但只需要一个,并且还清除与该表关联的所有交叉表!我的问题可能是什么?
厨师:
public class Cook
public Cook() // Пустой конструктор для Hibernate
// Поля
// name, lastName, login, password берем от класса User через связи;
private @Id
@GeneratedValue
Long id;
@Enumerated(EnumType.STRING)
@Column(name = "type")
private CookType cookType;
@Column(name = "rating")
private float rating;
@Column(name = "cook_status")
private boolean cookStatus;
@Column(name = "about_cook")
private String aboutCook;
//Relationships
//
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_id", referencedColumnName = "id") // Join without Cook in User class
private User user;
// Лист отзывов
@OneToMany(mappedBy = "cook", cascade = CascadeType.ALL)
@JsonIgnore // Таким образом я предотвратил рекурсию
private List<Review> reviewList;
// Лист поваров
@OneToMany(mappedBy = "cook", cascade = CascadeType.ALL)
@JsonIgnore // Таким образом я предотвратил рекурсию
private List<Order> orderList;
// Лист блюд
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(
name = "cook_dish",
joinColumns = @JoinColumn(name = "dish_id"),
inverseJoinColumns = @JoinColumn(name = "cook_id"))
@JsonIgnore // Таким образом я предотвратил рекурсию
private List<Dish> dish;
JpaRepo:
public interface CookRepository extends JpaRepository<Cook, Long> // Интерфейс для репозитория Cook
// Удалить Повара Role + ID
void deleteByUserRoleAndId(String role, Long id);
管理服务:
@Transactional
public void deleteCook(Long id)
cookRepository.deleteByUserRoleAndId("COOK", id);
管理员控制器:
@DeleteMapping("/delete/cook/id")
void removeCook(@PathVariable Long id)
adminService.deleteCook(id);
当我使用脚本运行应用程序时将数据添加到所有表中,然后在执行此方法时将其清除!
我正在写应用程序的REST
,使用下载Spring boot
+ Spring MVC
+ Spring Security
+ hibernate
+ Jpa
+ PostgreSQL
【问题讨论】:
它从数据库中删除所有列??你是说行吗? 数据都填好了,是的 您能否启用 show_sql 并查看 hibernate 在删除时生成了什么查询。还有一件事是因为 ID 是主键,所以 deleteByID(Long id) 应该没问题。 也许这是因为我在级联方面做错了什么? 你能在数据库被删除之前显示数据吗? 【参考方案1】:你有一个类和一个名为“Cook”的数据库表,它有一个唯一的 ID。您想删除一个您通过该 ID 标识的特定厨师 - 例如,您想删除 ID 为 123 的厨师。
其中没有“用户角色”。你不需要这个角色 - 你已经知道你正在处理 Cook 表。事实上,“Cook”类甚至没有“UserRole”属性。
所以 spring 尽可能地解释deleteByUserRoleAndId
。在没有“userRole”属性的情况下,它可能会尝试将函数名称中的“用户”与确实存在的“用户”属性进行匹配(为了比较,https://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html 表示findByAddressZipCode(ZipCode zipCode);
将遍历@987654324 @ 财产)。之后会发生什么我只能猜测。
无论如何,解决方案很简单。由于Cook
没有UserRole
,所以方法名中没有UserRole。
所以方法签名很简单:
void deleteById(Long id);
服务是:
@Transactional
public void deleteCook(Long id)
cookRepository.deleteById(id);
【讨论】:
【参考方案2】:在模型类中,我删除了cascade = CascadeType.All
并添加了cascade = CascadeType.PERSIST
。然后在Dish
课堂上我也做了同样的事情。
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinTable(
name = "cook_dish",
joinColumns = @JoinColumn(name = "dish_id"),
inverseJoinColumns = @JoinColumn(name = "cook_id"))
@JsonIgnore
private List<Dish> dish;
【讨论】:
【参考方案3】:我遇到了同样的问题。我的错误在 application.properties 文件中。
spring.jpa.hibernate.ddl-auto = create-drop
我应该使用 update 或 validate 而不是 create-drop
请参考How does spring.jpa.hibernate.ddl-auto property exactly work in Spring?
【讨论】:
以上是关于JpaRepository 中的 delete 方法从 DB 表中删除所有行的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA - JpaRepository 中的自定义排序
Spring JpaRepository 中的 %Like% 查询
如何将 FindAllBy 与 JpaRepository 中的多个字段一起使用?
Spring 数据 JpaRepository 方法问题中的 Pageable 和 @Param [2]