-2

I have an Admin class that can delete cooks from the database by id. When I use the void deleteByUserRoleAndId(String role, Long id) method; it removes all columns from the database, but only one is needed, and also clears all cross-tables that are associated with this table! What could be my problem?

Cook:

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);

AdminService:

@Transactional
    public void deleteCook(Long id) {

        cookRepository.deleteByUserRoleAndId("COOK", id);

    }

AdminController:

@DeleteMapping("/delete/cook/{id}")
    void removeCook(@PathVariable Long id) {
        adminService.deleteCook(id);
    }

Data is added to all tables when I run the application using the script, and then when this method is executed, it is cleared!

enter image description here

enter image description here

I'm writing the REST of the app, using the download Spring boot + Spring MVC + Spring Security + hibernate + Jpa + PostgreSQL

Artur Vartanyan
  • 589
  • 3
  • 10
  • 35

3 Answers3

1

In the model class I remove cascade = CascadeType.All and add cascade = CascadeType.PERSIST. And then in the class Dish I did the same.

@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;
Artur Vartanyan
  • 589
  • 3
  • 10
  • 35
0

You have a class and a database table called “Cook”, that has a unique Id. You want to delete one particular cook that you identify by that Id - eg, you want to delete the cook with Id 123.

Nowhere in that is there a “UserRole”. You don’t need the role - you already know you’re dealing with the Cook table. In fact, the class “Cook” does not even have a “UserRole” property.

So spring tries to interpret deleteByUserRoleAndId as best it can. In the absence of a “userRole” property, it probably tries to match the “User” from your function name against the “User” property that DOES exist (for comparison, https://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html says that findByAddressZipCode(ZipCode zipCode); will traverse across the address property). What happens after that I can only guess.

Regardless, the solution is simple. Since Cook does not have a UserRole, then do not have UserRole in the method name.

So the method signatory is simply :

void deleteById(Long id);

And the service is :

@Transactional
public void deleteCook(Long id) {

    cookRepository.deleteById(id);

}
racraman
  • 4,988
  • 1
  • 16
  • 16
-1

I faced the same issue. My mistake was in application.properties file.

spring.jpa.hibernate.ddl-auto = create-drop

I should have used update or validate instead of create-drop

Please refer to How does spring.jpa.hibernate.ddl-auto property exactly work in Spring?