简体   繁体   English

无法删除CrudRepository中的所有条目

[英]Cannot delete all the entries from a CrudRepository

Based on the tutorial in https://spring.io/guides/gs/accessing-data-rest/ , I use "CrudRepository" and "RepositoryRestResource" to make an address book. 基于https://spring.io/guides/gs/accessing-data-rest/中的教程,我使用“ CrudRepository”和“ RepositoryRestResource”来制作地址簿。 It works well for all the services such as adding a new contact, removing a contact, and etc. But, my problem is with deleting all the contacts (entries of the repository) from my address book. 它适用于所有服务,例如添加新联系人,删除联系人等。但是,我的问题是从地址簿中删除所有联系人(存储库条目)。 More specifically, when I want to delete them all by: 更具体地说,当我想通过以下方式将其全部删除时:

$curl -X DELETE http://localhost:8080/api/contact/

I get the following error: 我收到以下错误:

{"timestamp":1518158144204,"status":404,"error":"Not Found","message":"No message available","path":"/api/contact/"}. {“时间戳”:1518158144204,“状态”:404,“错误”:“未找到”,“消息”:“无消息”,“路径”:“ / api / contact /”}。

Note that spring.data.rest.basePath=/api is added to application.properties. 请注意,spring.data.rest.basePath = / api已添加到application.properties。

PersonRepository.java: PersonRepository.java:

package hello;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource(collectionResourceRel = "contact", path = "contact")
public interface PersonRepository extends CrudRepository<Person,String>{
}

Person.java: Person.java:

package hello;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Person {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String id;

private String firstname;
private String familyname;
private String phonenumber;
private String email;

public String getfirstname() {
    return firstname;
}

public void setfirstname(String firstName) {
    this.firstname = firstName;
}

public String getfamilyname() {
    return familyname;
}

public void setfamilyname(String familyName) {
    this.familyname = familyName;
}

public String getphonenumber() {
    return phonenumber;
}

public void setphonenumber(String phoneNumber) {
    this.phonenumber = phoneNumber;
}

public String getemail() {
    return email;
}

public void setemail(String Email) {
    this.email = Email;
}


}

Spring REST repositories have different methods that are exposed for collection resources and for individual item resources . Spring REST存储库具有针对集合资源单个项目资源公开的不同方法。 More specifically GET, HEAD and POST are available out of the box for collection resources but DELETE is not. 更具体地说,GET,HEAD和POST可以直接用于收集资源,而DELETE则不可用。

Reference the docs here . 此处参考文档。

You can delete an individual item by passing a DELETE request with an item ID, just like the guide you are following says, for example curl -X DELETE http://localhost:8080/api/contact/23 . 您可以通过传递带有项目ID的DELETE请求来删除单个项目,就像您遵循的指南所说,例如curl -X DELETE http://localhost:8080/api/contact/23

IMHO, I think this was done right because of security reasons. 恕我直言,我认为这样做是出于安全原因。 Imagine if someone could delete your entire collection by accident if they happen not to pass an item id when deleting a single resource. 想象一下,如果某人在删除单个资源时碰巧没有传递项目ID,则可以意外删除您的整个收藏集。

What you can do is write your own custom deleteAll method if you want/need it however be careful. 您可以做的是编写自己的自定义deleteAll方法(如果需要),但是要小心。

You can write a custom delete method, for example: 您可以编写一个自定义删除方法,例如:

public void deleteAllContacts();

And you can access that method via simple GET request: http://localhost:8080/api/contact/search/deleteAllContacts 您可以通过简单的GET请求访问该方法: http://localhost:8080/api/contact/search/deleteAllContacts

Now I have to mention that this is not really by REST principles, making a GET request and deleting a resource and this /search/delete... part really sticks out as it kinda confuses the APi user. 现在,我不得不提到,这并不是真正的REST原理,发出GET请求并删除资源, /search/delete...部分确实很突出,因为这有点使APi用户感到困惑。 Does it searches, deletes or what?? 它会搜索,删除还是什么?

This is one way to do what you want but I really do NOT recommend this as it is not an elegant way of doing things AND doesn't really follow good programming principles. 这是做您想要的事情的一种方法,但是我真的不建议您这样做,因为它不是一种优雅的做事方法,并且也没有真正遵循良好的编程原则。

Maybe you should consider having a ContactController that allows this functionality if a user passes a token or some other required parameter because you don't want to expose your API to the mercy of every google chrome out there and putting it at risk to erase all your data just with a single http request. 如果用户传递令牌或其他必需参数,也许您应该考虑拥有一个允许该功能的ContactController ,因为您不想让您的API受到那里每一个Google Chrome的摆布,并冒着擦除所有您的风险的风险只需一个http请求即可获得数据。

In my experience it is better to write a delete function that works off the ids and not the entities because sometimes even if you delete the entity they are not deleted until the background process does it. 以我的经验,最好编写一个可以处理id而不是实体的delete函数,因为有时即使删除实体,它们也不会被后台进程删除。

In your repository you can write something like 在您的存储库中,您可以编写类似

@Modifying
@Transactional
@Query("DELETE FROM Person p WHERE p.id = ?1)
void delete(Integer id);

@Modifying
@Transactional
@Query("DELETE FROM Person p WHERE p.id in ?1)
void delete(Set<Integer> ids);

The first one will allow you delete a single entity by id while the second one allows you to delete a set by ids. 第一个允许您通过ID删除单个实体,而第二个允许您通过ID删除一组实体。

What Urosh T states is true, you shouldn't be using your rest calls to call the repository directly. Urosh T所说的是正确的,您不应该使用rest调用直接调用存储库。 The rest calls should be going to a controller which then can act on the repository to do the delete. 其余的调用应该转到控制器,然后控制器可以对存储库执行操作以执行删除操作。

//You can use JPA Repository if you have no problem with it
//For Deleting all entities managed by the userRepository
@DeleteMapping("/users")
public void deleteAllUsers() {

     userRepository.deleteAll();
}


import com.my.package.model.UserModel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<UserModel, Long> 
{

}

 //You are welcome to ask where you don't understand.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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