Как я могу удалить элемент, который находится на нескольких сторонах в spring-data-jpa? - PullRequest
1 голос
/ 31 октября 2019

Между Департаментом и Сотрудником существует двунаправленная связь один-ко-многим.

@Setter
@Getter
@Entity
@Table(name = "t_department")
public class Department {
    @Id
    private String id;

    private String name;

    @OneToMany(mappedBy = "department",fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    private List<Employee> employees;
}


@Setter
@Getter
@Entity
@Table(name = "t_employee")
public class Employee {
    @Id
    private String id;

    private String name;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "dept_id")
    private Department department;
}

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, String> {

}

В базе данных есть эти записи.

t_department:
+----+------------+
| id | name       |
+----+------------+
| 2  | accounting |
| 3  | logistics  |
+----+------------+

t_employee:
+----+------+---------+
| id | name | dept_id |
+----+------+---------+
| 3  | Tom  | 2       |
| 4  | Tina | 3       |
+----+------+---------+

Когда я пытался удалитьСотрудник (id = "3"),

    @Test
    @Transactional
    public void should_delete_employee_success_when_delete_employee_given_a_exist_employee_id_in_DB() {
        employeeRepository.delete("3");
    }

Но в консоли он напечатал только 2 выбранных оператора без удаления:

Hibernate: select employee0_.id as id1_2_0_, employee0_.dept_id as dept_id3_2_0_, employee0_.name as name2_2_0_, department1_.id as id1_1_1_, department1_.name as name2_1_1_ from t_employee employee0_ left outer join t_department department1_ on employee0_.dept_id=department1_.id where employee0_.id=?
Hibernate: select employees0_.dept_id as dept_id3_2_0_, employees0_.id as id1_2_0_, employees0_.id as id1_2_1_, employees0_.dept_id as dept_id3_2_1_, employees0_.name as name2_2_1_ from t_employee employees0_ where employees0_.dept_id=?

И я пошелчтобы увидеть базу данных, ничего не было сделано.

Как работает spring-data-jpa? Я запутался в течение нескольких дней.

Спасибо за ваши ответы заранее.

Ответы [ 3 ]

0 голосов
/ 31 октября 2019

Поскольку @Transactional Spring-тесты по умолчанию помечены только для отката, а изменения SQL обычно передаются в базу данных только при фиксации транзакции.

Затем вам нужно будет либо (1) вручную сбросить изменения впринудительная запись в базу данных:

public class SomeTest{

    @PersistenceContext 
    private EntityManager em;

    @Test
    @Transactional
    public void should_delete_employee_success_when_delete_employee_given_a_exist_employee_id_in_DB() {
        employeeRepository.delete("3");
        em.flush(); //force db update however transaction will still be rolled back
    }

или (2)

Установите транзакцию как не предназначенную только для отката, которую можно выполнять различными способами, включая использование @Commit и @Rollback аннотации:

https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#integration-testing-annotations-spring

0 голосов
/ 05 ноября 2019

Я обнаружил, что как только отдел узнает, кто с ним связан, вы не можете удалять сотрудников, которые связаны с отделом. Я использую fetch=FetchType.EAGER с обеих сторон, поэтому, когда я удаляю сотрудника, он загружает отдел и сотрудников отдела. Правильно то, что вам нужно удалить сотрудника из сотрудников отдела, а затем удалить его. Вы можете попробовать это:

    Optional<Employee> employeeOpt = employeeRepository.findById("3");
    if (employeeOpt.isPresent()) {
        Employee employee = employeeOpt.get();
        employee.getDepartment().getEmployees().removeIf(emp -> emp.getId().equals("3"));
        employeeRepository.deleteById("3");
    }
0 голосов
/ 31 октября 2019

CrudRepository имеет методы delete(<entity>) и deleteById(). Вы должны использовать deleteById, а не сущность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...